GenRepositoryGenerator   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 257
Duplicated Lines 14.4 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 32
c 2
b 1
f 0
lcom 1
cbo 6
dl 37
loc 257
rs 9.6

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A generate() 0 21 3
C generateRepository() 0 45 8
B generateEntityInterface() 0 27 3
A generateTestClass() 18 18 1
A processRenderFile() 0 17 1
B setFormat() 0 14 5
A genParamsData() 18 18 3
C addPatternToServices() 0 42 7

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
    protected $format;
24
25
    /**
26
     * Constructor.
27
     *
28
     * @param Filesystem $filesystem A Filesystem instance
29
     * @param string     $rootDir    The root dir
30
     */
31
    public function __construct(Filesystem $filesystem, $rootDir)
32
    {
33
        $this->filesystem = $filesystem;
34
        $this->rootDir = $rootDir;
35
    }
36
37
    public function generate(BundleInterface $bundle, $entity, ClassMetadataInfo $metadata, $format, $forceOverwrite)
38
    {
39
        if (count($metadata->identifier) != 1) {
40
            throw new \RuntimeException('The REST generator does not support entity classes with multiple or no primary keys.');
41
        }
42
43
        $this->entity = $entity;
44
        $this->entitySingularized = lcfirst(Inflector::singularize($entity));
45
        $this->entityPluralized = lcfirst(Inflector::pluralize($entity));
46
        $this->bundle = $bundle;
47
        $this->metadata = $metadata;
48
        $this->setFormat($format);
49
50
        $this->data = $this->genParamsData();
51
52
        foreach ($this->data[0]['Repository'] as $service => $arguments) {
53
            $this->generateRepository($arguments, $forceOverwrite);
54
        }
55
56
        $this->generateTestClass();
57
    }
58
59
    public function generateRepository($arguments, $forceOverwrite)
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
        $this->processRenderFile(
147
            'crud/tests/repositoryTest.php.twig',
148
            $target,
149
            sprintf('%sRepositoryTest', $entityClass),
150
            $entityClass,
151
            'Model',
152
            null
153
        );
154
    }
155
156
    /**
157
     * @param $file
158
     * @param $target
159
     * @param $classname
160
     * @param $entityClass
161
     * @param $serviceNamespace
162
     * @param null $service
163
     */
164
    protected function processRenderFile($file, $target, $classname, $entityClass, $serviceNamespace, $service = null, $options = null)
165
    {
166
        $this->renderFile($file, $target, array(
167
            'bundle' => $this->bundle->getName(),
168
            'entity' => $this->entity,
169
            'entity_singularized' => $this->entitySingularized,
170
            'entity_pluralized' => $this->entityPluralized,
171
            'entity_class' => $entityClass,
172
            'namespace' => $this->bundle->getNamespace(),
173
            'service_namespace' => $serviceNamespace,
174
            'entity_namespace' => $serviceNamespace,
175
            'class_name' => $classname,
176
            'service' => $service,
177
            'fields' => $this->metadata->fieldMappings,
178
            'options' => $options,
179
        ));
180
    }
181
182
    /**
183
     * Sets the configuration format.
184
     *
185
     * @param string $format The configuration format
186
     */
187
    protected function setFormat($format)
188
    {
189
        switch ($format) {
190
            case 'yml':
191
            case 'xml':
192
            case 'php':
193
            case 'annotation':
194
                $this->format = $format;
195
                break;
196
            default:
197
                $this->format = 'yml';
198
                break;
199
        }
200
    }
201
202
    /**
203
     * @return array
204
     */
205 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...
206
    {
207
        $data = array();
208
        $dir = sprintf('%s/config/gen/%s', $this->rootDir, $this->entity);
209
        $yaml = new Parser();
210
211
        $files = scandir(str_replace('\\', '/', $dir));
212
213
        foreach ($files as $file) {
214
            if (0 == strpos($file, '.')) {
215
                continue;
216
            }
217
218
            $data[] = $yaml->parse(file_get_contents($dir.'/'.$file));
219
        }
220
221
        return $data;
222
    }
223
224
    /**
225
     * @param $definitions
226
     */
227
    protected function addPatternToServices($definitions)
228
    {
229
        $file = sprintf('%s/config/%s', $this->rootDir, 'services.yml');
230
231
        $yaml = new Parser();
232
        $services = $yaml->parse(file_get_contents($file));
233
234
        foreach ($definitions as $key => $definition) {
235
            $array = array(
236
                $key => array(
237
                    'class' => $definition['class'],
238
                    'arguments' => empty($definition['arguments']) ? null : array(
239
                        $definition['arguments'][0][0],
240
                        empty($definition['arguments'][1][0]) ?: $definition['arguments'][1][0],
241
                    ),
242
                ),
243
            );
244
245
            $arguments = array();
246
247
            if (!empty($definition['factory'])) {
248
                $arguments['factory'] = $definition['factory'];
249
            }
250
251
            if (!empty($definition['arguments'])) {
252
                $arguments['arguments'][] = $definition['arguments'][0];
253
                if (!empty($definition['arguments'][1])) {
254
                    $arguments['arguments'][] = $definition['arguments'][1];
255
                }
256
            }
257
258
            $services['services'][$key] = array_merge($array[$key], $arguments);
259
        }
260
261
        $dumper = new Dumper();
262
263
        $yaml = $dumper->dump($services, 4);
264
265
        $file = sprintf('%s/config/%s', $this->rootDir, 'gen/services.yml');
266
267
        file_put_contents($file, $yaml);
268
    }
269
}
270