AbstractCommand::getMetaData()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
/**
3
 * Sake
4
 *
5
 * @link      http://github.com/sandrokeil/CodeGenerator for the canonical source repository
6
 * @copyright Copyright (c) 2014 Sandro Keil
7
 * @license   http://github.com/sandrokeil/CodeGenerator/blob/master/LICENSE.txt New BSD License
8
 */
9
10
namespace Sake\CodeGenerator\Doctrine\ORM\Tools\Console\Command;
11
12
use Doctrine\ORM\EntityManager;
13
use Sake\CodeGenerator\Code\Metadata\MetadataInfo;
14
use Sake\CodeGenerator\Hydrator\DoctrineMetadata;
15
use Symfony\Component\Console\Input\InputArgument;
16
use Symfony\Component\Console\Input\InputOption;
17
use Doctrine\ORM\Tools\Console\MetadataFilter;
18
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
19
use Doctrine\ORM\Mapping\Driver\DatabaseDriver;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Symfony\Component\Console\Input\InputInterface;
22
use Symfony\Component\Console\Command\Command;
23
24
/**
25
 * Abstract command class
26
 *
27
 * Base class for generate commands
28
 */
29
abstract class AbstractCommand extends Command
30
{
31
    /**
32
     * Configure command with default arguments
33
     */
34
    protected function configure()
35
    {
36
        $this->setDefinition(
37
            array(
38
                new InputOption(
39
                    'filter',
40
                    null,
41
                    InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
42
                    'A string pattern used to match classes that should be processed.'
43
                ),
44
                new InputArgument(
45
                    'dest-path',
46
                    InputArgument::REQUIRED,
47
                    'The path to generate your classes.'
48
                ),
49
                new InputOption(
50
                    'force',
51
                    null,
52
                    InputOption::VALUE_NONE,
53
                    'Force to overwrite existing files.'
54
                ),
55
                new InputOption(
56
                    'from-database',
57
                    null,
58
                    null,
59
                    'Whether or not to convert mapping information from existing database.'
60
                ),
61
                new InputOption(
62
                    'extend',
63
                    null,
64
                    InputOption::VALUE_OPTIONAL,
65
                    'Defines a base class to be extended by generated classes.'
66
                ),
67
                new InputOption(
68
                    'namespace',
69
                    null,
70
                    InputOption::VALUE_OPTIONAL,
71
                    'Defines a namespace for this class.'
72
                ),
73
                new InputOption(
74
                    'num-spaces',
75
                    null,
76
                    InputOption::VALUE_OPTIONAL,
77
                    'Defines the number of indentation spaces',
78
                    4
79
                )
80
            )
81
        );
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87
    protected function execute(InputInterface $input, OutputInterface $output)
88
    {
89
        $em = $this->getHelper('em')->getEntityManager();
90
91
        if ($input->getOption('from-database') === true) {
92
            $databaseDriver = new DatabaseDriver(
93
                $em->getConnection()->getSchemaManager()
94
            );
95
96
            $em->getConfiguration()->setMetadataDriverImpl(
97
                $databaseDriver
98
            );
99
100
            if (($namespace = $input->getOption('namespace')) !== null) {
101
                $databaseDriver->setNamespace($namespace);
102
            }
103
        }
104
        $doctrineMetaData = $this->getMetaData($em, $input);
105
106
        // Process destination directory
107
        if (!is_dir($destPath = $input->getArgument('dest-path'))) {
108
            mkdir($destPath, 0777, true);
109
        }
110
        $destPath = realpath($destPath);
111
112
        if (!file_exists($destPath)) {
113
            throw new \InvalidArgumentException(
114
                sprintf(
115
                    "Destination directory '<info>%s</info>' does not exist.",
116
                    $input->getArgument('dest-path')
117
                )
118
            );
119
        }
120
121
        if (!is_writable($destPath)) {
122
            throw new \InvalidArgumentException(
123
                sprintf(
124
                    "Destination directory '<info>%s</info>' does not have write permissions.",
125
                    $destPath
126
                )
127
            );
128
        }
129
130
        if (0 === count($doctrineMetaData)) {
131
            $output->writeln('No Metadata Classes to process.');
132
            return;
133
        }
134
        $generator = $this->getGenerator();
135
136
        if (($extend = $input->getOption('extend')) !== null) {
137
            $generator->setClassToExtend($extend);
138
        }
139
140
        if (($namespace = $input->getOption('namespace')) !== null) {
141
            $generator->setNamespace($namespace);
142
        }
143
        if (($numSpaces = $input->getOption('num-spaces')) !== null) {
144
            $generator->setNumSpaces($numSpaces);
145
        }
146
147
        $metaData = array();
148
        $hydtrator = $this->getHydrator();
149
150
        foreach ($doctrineMetaData as $data) {
151
            $metaData[$data->name] = new MetadataInfo($hydtrator->extract($data));
152
            $output->writeln(
153
                sprintf('Processing class "<info>%s</info>"', $data->name)
154
            );
155
        }
156
157
        $generator->generate($metaData, $destPath);
158
159
        // Outputting information message
160
        $output->writeln(PHP_EOL . sprintf('Classes generated to "<info>%s</INFO>"', $destPath));
161
    }
162
163
    /**
164
     * Returns metadata
165
     *
166
     * @param EntityManager $em
167
     * @param InputInterface $input
168
     * @return array
169
     */
170
    protected function getMetaData(EntityManager $em, InputInterface $input)
171
    {
172
        $cmf = new DisconnectedClassMetadataFactory();
173
        $cmf->setEntityManager($em);
174
        $metadata = $cmf->getAllMetadata();
175
176
        return MetadataFilter::filter($metadata, $input->getOption('filter'));
177
    }
178
179
    /**
180
     * @return \Sake\CodeGenerator\Code\Generator\AbstractGenerator
181
     */
182
    abstract protected function getGenerator();
183
184
    /**
185
     * Returns hydrator
186
     *
187
     * @return DoctrineMetadata
188
     */
189
    protected function getHydrator()
190
    {
191
        return new DoctrineMetadata();
192
    }
193
}
194