Completed
Branch master (627c02)
by Koldo
02:22
created

GenRepositoryGenerator::setFormat()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 14
rs 8.8571
cc 5
eloc 11
nc 5
nop 1
1
<?php
2
3
namespace Kpicaza\GenBundle\Generator;
4
5
use Doctrine\Common\Inflector\Inflector;
6
use Doctrine\ORM\Mapping\ClassMetadataInfo;
7
use Sensio\Bundle\GeneratorBundle\Generator\Generator;
8
use Symfony\Component\Filesystem\Filesystem;
9
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
10
use Symfony\Component\Yaml\Dumper;
11
use Symfony\Component\Yaml\Parser;
12
13
class GenRepositoryGenerator extends Generator
14
{
15
    protected $filesystem;
16
    protected $entity;
17
    protected $entitySingularized;
18
    protected $entityPluralized;
19
    protected $bundle;
20
    protected $metadata;
21
    protected $rootDir;
22
    protected $data;
23
24
    /**
25
     * Constructor.
26
     *
27
     * @param Filesystem $filesystem A Filesystem instance
28
     * @param string $rootDir The root dir
29
     */
30
    public function __construct(Filesystem $filesystem, $rootDir)
31
    {
32
        $this->filesystem = $filesystem;
33
        $this->rootDir = $rootDir;
34
    }
35
36
    public function generate(BundleInterface $bundle, $entity, ClassMetadataInfo $metadata, $format, $forceOverwrite)
37
    {
38
        if (count($metadata->identifier) != 1) {
39
            throw new \RuntimeException('The REST generator does not support entity classes with multiple or no primary keys.');
40
        }
41
42
        $this->entity = $entity;
43
        $this->entitySingularized = lcfirst(Inflector::singularize($entity));
44
        $this->entityPluralized = lcfirst(Inflector::pluralize($entity));
45
        $this->bundle = $bundle;
46
        $this->metadata = $metadata;
47
        $this->setFormat($format);
48
49
        $this->data = $this->genParamsData();
50
51
        foreach ($this->data[0]['Repository'] as $service => $arguments) {
52
            $this->generateRepository($arguments, $forceOverwrite);
53
        }
54
55
        $this->generateTestClass();
56
    }
57
58
    public function generateRepository($arguments, $forceOverwrite)
59
    {
60
61
        $parts = explode('\\', $this->entity);
62
        $entityClass = array_pop($parts);
63
        $serviceNamespace = $arguments['dir'];
64
65
        $items = array(
66
            'Interface',
67
            ''
68
        );
69
70
        foreach ($items as $item) {
71
            if ('Gateway' == $arguments['type'] && '' == $item) {
72
                $arguments['dir'] = str_replace('Model/' . $this->entity, 'Repository', $arguments['dir']);
73
                $serviceNamespace = $arguments['dir'];
74
            }
75
            $dir = $this->bundle->getPath() . '/' . $arguments['dir'];
76
77
            $target = sprintf(
78
                '%s/%s.php',
79
                $dir,
80
                $arguments['classname'] . $item
81
            );
82
83
            if (!$forceOverwrite && file_exists($target)) {
84
                throw new \RuntimeException('Unable to generate the repository pattern as it already exists.');
85
            }
86
87
            if ('Interface' == $item && 'Repository' == $arguments['type']) {
88
                $this->generateEntityInterface($arguments, $forceOverwrite);
89
                continue;
90
            }
91
92
            $this->processRenderFile(
93
                sprintf('repository/%s.php.twig', strtolower($arguments['type']) . $item),
94
                $target,
95
                $arguments['classname'],
96
                $entityClass,
97
                $serviceNamespace,
98
                null
99
            );
100
        }
101
102
        $this->addPatternToServices($this->data[0]['Repository']);
103
    }
104
105
    /**
106
     * @param $arguments
107
     * @param $forceOverwrite
108
     */
109
    public function generateEntityInterface($arguments, $forceOverwrite)
110
    {
111
        $dir = $this->bundle->getPath() . '/' . $arguments['dir'];
112
113
        $parts = explode('\\', $this->entity);
114
        $entityClass = array_pop($parts);
115
        $serviceNamespace = $arguments['dir'];
116
        $arguments['classname'] = $entityClass . 'Interface';
117
        $target = sprintf(
118
            '%s/%s.php',
119
            $dir,
120
            $arguments['classname']
121
        );
122
123
        if (!$forceOverwrite && file_exists($target)) {
124
            throw new \RuntimeException('Unable to generate the Interface as it already exists.');
125
        }
126
127
        $this->processRenderFile(
128
            'repository/entityInterface.php.twig',
129
            $target,
130
            $arguments['classname'],
131
            $entityClass,
132
            $serviceNamespace,
133
            null
134
        );
135
    }
136
137 View Code Duplication
    protected function generateTestClass()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
138
    {
139
        $parts = explode('\\', $this->entity);
140
        $entityClass = array_pop($parts);
141
142
        $dir = sprintf('%s/../tests/%s/Model/', $this->rootDir, $this->bundle->getName());
143
144
        $target = $dir . $entityClass . 'RepositoryTest.php';
145
146
147
        $this->processRenderFile(
148
            'crud/tests/repositoryTest.php.twig',
149
            $target,
150
            sprintf('%sRepositoryTest', $entityClass),
151
            $entityClass,
152
            'Model',
153
            null
154
        );
155
    }
156
157
    /**
158
     * @param $file
159
     * @param $target
160
     * @param $classname
161
     * @param $entityClass
162
     * @param $serviceNamespace
163
     * @param null $service
164
     */
165
    protected function processRenderFile($file, $target, $classname, $entityClass, $serviceNamespace, $service = null, $options = null)
166
    {
167
        $this->renderFile($file, $target, array(
168
            'bundle' => $this->bundle->getName(),
169
            'entity' => $this->entity,
170
            'entity_singularized' => $this->entitySingularized,
171
            'entity_pluralized' => $this->entityPluralized,
172
            'entity_class' => $entityClass,
173
            'namespace' => $this->bundle->getNamespace(),
174
            'service_namespace' => $serviceNamespace,
175
            'entity_namespace' => $serviceNamespace,
176
            'class_name' => $classname,
177
            'service' => $service,
178
            'fields' => $this->metadata->fieldMappings,
179
            'options' => $options
180
        ));
181
    }
182
183
    /**
184
     * Sets the configuration format.
185
     *
186
     * @param string $format The configuration format
187
     */
188
    protected function setFormat($format)
189
    {
190
        switch ($format) {
191
            case 'yml':
192
            case 'xml':
193
            case 'php':
194
            case 'annotation':
195
                $this->format = $format;
0 ignored issues
show
Bug introduced by
The property format does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
196
                break;
197
            default:
198
                $this->format = 'yml';
199
                break;
200
        }
201
    }
202
203
    /**
204
     * @return array
205
     */
206 View Code Duplication
    protected function genParamsData()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
207
    {
208
        $data = array();
209
        $dir = sprintf('%s/config/gen/%s', $this->rootDir, $this->entity);
210
        $yaml = new Parser();
211
212
        $files = scandir(str_replace('\\', '/', $dir));
213
214
        foreach ($files as $file) {
215
            if (0 == strpos($file, '.')) {
216
                continue;
217
            }
218
219
            $data[] = $yaml->parse(file_get_contents($dir . '/' . $file));
220
        }
221
222
        return $data;
223
    }
224
225
    /**
226
     * @param $definitions
227
     */
228
    protected function addPatternToServices($definitions)
229
    {
230
        $file = sprintf('%s/config/%s', $this->rootDir, 'services.yml');
231
232
        $yaml = new Parser();
233
        $services = $yaml->parse(file_get_contents($file));
234
235
        foreach ($definitions as $key => $definition) {
236
            $array = array(
237
                $key => array(
238
                    'class' => $definition['class'],
239
                    'arguments' => empty($definition['arguments']) ? null : array(
240
                        $definition['arguments'][0][0],
241
                        empty($definition['arguments'][1][0]) ?: $definition['arguments'][1][0]
242
                    )
243
                )
244
            );
245
246
            $arguments = array();
247
248
            if (!empty($definition['factory'])) {
249
                $arguments['factory'] = $definition['factory'];
250
            }
251
252
            if (!empty($definition['arguments'])) {
253
                $arguments['arguments'][] = $definition['arguments'][0];
254
                if (!empty($definition['arguments'][1])) {
255
                    $arguments['arguments'][] = $definition['arguments'][1];
256
                }
257
            }
258
259
            $services['services'][$key] = array_merge($array[$key], $arguments);
260
        }
261
262
        $dumper = new Dumper();
263
264
        $yaml = $dumper->dump($services, 4);
265
266
        $file = sprintf('%s/config/%s', $this->rootDir, 'gen/services.yml');
267
268
        file_put_contents($file, $yaml);
269
    }
270
}