Completed
Push — master ( ba3223...b47a39 )
by Luís
17s
created

ConvertMappingCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 34
nc 1
nop 0
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
ccs 0
cts 13
cp 0
crap 2
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ORM\Tools\Console\Command;
21
22
use Doctrine\ORM\Mapping\Driver\DatabaseDriver;
23
use Doctrine\ORM\Tools\Console\MetadataFilter;
24
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
25
use Doctrine\ORM\Tools\EntityGenerator;
26
use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
27
use Symfony\Component\Console\Command\Command;
28
use Symfony\Component\Console\Input\InputArgument;
29
use Symfony\Component\Console\Input\InputInterface;
30
use Symfony\Component\Console\Input\InputOption;
31
use Symfony\Component\Console\Output\OutputInterface;
32
use Symfony\Component\Console\Style\SymfonyStyle;
33
34
/**
35
 * Command to convert your mapping information between the various formats.
36
 *
37
 * @link    www.doctrine-project.org
38
 * @since   2.0
39
 * @author  Benjamin Eberlei <[email protected]>
40
 * @author  Guilherme Blanco <[email protected]>
41
 * @author  Jonathan Wage <[email protected]>
42
 * @author  Roman Borschel <[email protected]>
43
 */
44
class ConvertMappingCommand extends Command
45
{
46
    /**
47
     * {@inheritdoc}
48
     */
49
    protected function configure()
50
    {
51
        $this->setName('orm:convert-mapping')
52
             ->setAliases(['orm:convert:mapping'])
53
             ->setDescription('Convert mapping information between supported formats')
54
             ->addArgument('to-type', InputArgument::REQUIRED, 'The mapping type to be converted.')
55
             ->addArgument('dest-path', InputArgument::REQUIRED, 'The path to generate your entities classes.')
56
             ->addOption('filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'A string pattern used to match entities that should be processed.')
57
             ->addOption('force', 'f', InputOption::VALUE_NONE, 'Force to overwrite existing mapping files.')
58
             ->addOption('from-database', null, null, 'Whether or not to convert mapping information from existing database.')
59
             ->addOption('extend', null, InputOption::VALUE_OPTIONAL, 'Defines a base class to be extended by generated entity classes.')
60
             ->addOption('num-spaces', null, InputOption::VALUE_OPTIONAL, 'Defines the number of indentation spaces', 4)
61
             ->addOption('namespace', null, InputOption::VALUE_OPTIONAL, 'Defines a namespace for the generated entity classes, if converted from database.')
62
             ->setHelp(<<<EOT
63
Convert mapping information between supported formats.
64
65
This is an execute <info>one-time</info> command. It should not be necessary for
66
you to call this method multiple times, especially when using the <comment>--from-database</comment>
67
flag.
68
69
Converting an existing database schema into mapping files only solves about 70-80%
70
of the necessary mapping information. Additionally the detection from an existing
71
database cannot detect inverse associations, inheritance types,
72
entities with foreign keys as primary keys and many of the
73
semantical operations on associations such as cascade.
74
75
<comment>Hint:</comment> There is no need to convert YAML or XML mapping files to annotations
76
every time you make changes. All mapping drivers are first class citizens
77
in Doctrine 2 and can be used as runtime mapping for the ORM.
78
79
<comment>Hint:</comment> If you have a database with tables that should not be managed
80
by the ORM, you can use a DBAL functionality to filter the tables and sequences down
81
on a global level:
82
83
    \$config->setFilterSchemaAssetsExpression(\$regexp);
84
EOT
85
             );
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    protected function execute(InputInterface $input, OutputInterface $output)
92
    {
93
        $ui = new SymfonyStyle($input, $output);
94
95
        $em = $this->getHelper('em')->getEntityManager();
96
97
        if ($input->getOption('from-database') === true) {
98
            $databaseDriver = new DatabaseDriver(
99
                $em->getConnection()->getSchemaManager()
100
            );
101
102
            $em->getConfiguration()->setMetadataDriverImpl(
103
                $databaseDriver
104
            );
105
106
            if (($namespace = $input->getOption('namespace')) !== null) {
107
                $databaseDriver->setNamespace($namespace);
108
            }
109
        }
110
111
        $cmf = new DisconnectedClassMetadataFactory();
112
        $cmf->setEntityManager($em);
113
        $metadata = $cmf->getAllMetadata();
114
        $metadata = MetadataFilter::filter($metadata, $input->getOption('filter'));
115
116
        // Process destination directory
117
        if ( ! is_dir($destPath = $input->getArgument('dest-path'))) {
118
            mkdir($destPath, 0775, true);
119
        }
120
        $destPath = realpath($destPath);
121
122
        if ( ! file_exists($destPath)) {
123
            throw new \InvalidArgumentException(
124
                sprintf("Mapping destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
125
            );
126
        }
127
128
        if ( ! is_writable($destPath)) {
129
            throw new \InvalidArgumentException(
130
                sprintf("Mapping destination directory '<info>%s</info>' does not have write permissions.", $destPath)
131
            );
132
        }
133
134
        $toType = strtolower($input->getArgument('to-type'));
135
136
        $exporter = $this->getExporter($toType, $destPath);
137
        $exporter->setOverwriteExistingFiles($input->getOption('force'));
138
139
        if ($toType == 'annotation') {
140
            $entityGenerator = new EntityGenerator();
141
            $exporter->setEntityGenerator($entityGenerator);
0 ignored issues
show
Bug introduced by
The method setEntityGenerator() does not exist on Doctrine\ORM\Tools\Export\Driver\AbstractExporter. It seems like you code against a sub-type of Doctrine\ORM\Tools\Export\Driver\AbstractExporter such as Doctrine\ORM\Tools\Expor...iver\AnnotationExporter. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

141
            $exporter->/** @scrutinizer ignore-call */ 
142
                       setEntityGenerator($entityGenerator);
Loading history...
142
143
            $entityGenerator->setNumSpaces($input->getOption('num-spaces'));
144
145
            if (($extend = $input->getOption('extend')) !== null) {
146
                $entityGenerator->setClassToExtend($extend);
147
            }
148
        }
149
150
        if (empty($metadata)) {
151
            $ui->success('No Metadata Classes to process.');
152
            return;
153
        }
154
155
        foreach ($metadata as $class) {
156
            $ui->text(sprintf('Processing entity "<info>%s</info>"', $class->name));
157
        }
158
159
        $exporter->setMetadata($metadata);
160
        $exporter->export();
161
162
        $ui->newLine();
163
        $ui->text(
164
            sprintf(
165
                'Exporting "<info>%s</info>" mapping information to "<info>%s</info>"',
166
                $toType,
167
                $destPath
168
            )
169
        );
170
    }
171
172
    /**
173
     * @param string $toType
174
     * @param string $destPath
175
     *
176
     * @return \Doctrine\ORM\Tools\Export\Driver\AbstractExporter
177
     */
178
    protected function getExporter($toType, $destPath)
179
    {
180
        $cme = new ClassMetadataExporter();
181
182
        return $cme->getExporter($toType, $destPath);
183
    }
184
}
185