Completed
Branch master (f09254)
by Koldo
03:40 queued 01:22
created

GenCrudGenerator   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 257
Duplicated Lines 14.4 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 7
Bugs 2 Features 5
Metric Value
wmc 21
c 7
b 2
f 5
lcom 1
cbo 7
dl 37
loc 257
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
B generate() 0 37 5
B generateControllerClass() 0 32 3
B generateHandlers() 0 29 3
A generateHandlerException() 0 6 1
A generateTestClass() 19 19 1
A processRenderFile() 0 21 1
B addToServices() 0 32 2
A genParamsData() 18 18 3
A generateConfiguration() 0 21 2

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\DoctrineCrudGenerator;
8
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
9
use Symfony\Component\Yaml\Dumper;
10
use Symfony\Component\Yaml\Parser;
11
12
class GenCrudGenerator extends DoctrineCrudGenerator
13
{
14
    protected $services;
15
16
    protected $data;
17
18
    /**
19
     * {@inheritdoc}
20
     */
21
    public function generate(BundleInterface $bundle, $entity, ClassMetadataInfo $metadata, $format, $routePrefix, $needWriteActions, $forceOverwrite)
22
    {
23
        $this->routePrefix = $routePrefix;
24
        $this->routeNamePrefix = self::getRouteNamePrefix($routePrefix);
25
        $this->actions = $needWriteActions ? array('index', 'show', 'new', 'edit', 'delete', 'options') : array('index', 'show', 'options');
26
27
        if (count($metadata->identifier) != 1) {
28
            throw new \RuntimeException('The REST generator does not support entity classes with multiple or no primary keys.');
29
        }
30
31
        $this->entity = $entity;
32
        $this->entitySingularized = lcfirst(Inflector::singularize($entity));
33
        $this->entityPluralized = lcfirst(Inflector::pluralize($entity));
34
        $this->bundle = $bundle;
35
        $this->metadata = $metadata;
36
        $this->setFormat($format);
37
38
        $this->data = $this->genParamsData();
39
40
        foreach ($this->data[0]['Handlers'] as $service => $arguments) {
41
            $this->generateHandlers($arguments, $forceOverwrite);
42
        }
43
44
        $this->generateHandlerException();
45
46
        $this->generateControllerClass($forceOverwrite);
47
48
        $dir = sprintf('%s/Resources/views/%s', $this->rootDir, str_replace('\\', '/', strtolower($this->entity)));
49
50
        if (!file_exists($dir)) {
51
            $this->filesystem->mkdir($dir, 0777);
52
        }
53
54
        $this->generateTestClass();
55
        $this->generateConfiguration();
56
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    protected function generateControllerClass($forceOverwrite)
63
    {
64
        $dir = $this->bundle->getPath();
65
66
        $parts = explode('\\', $this->entity);
67
        $entityClass = array_pop($parts);
68
        $entityNamespace = implode('\\', $parts);
69
        $options = $this->data[0]['Controller'];
70
71
        $target = sprintf(
72
            '%s/Controller/%s/%sController.php',
73
            $dir,
74
            str_replace('\\', '/', $entityNamespace),
75
            $entityClass
76
        );
77
78
        if (!$forceOverwrite && file_exists($target)) {
79
            throw new \RuntimeException('Unable to generate the controller as it already exists.');
80
        }
81
82
        $handler = $this->data[0]['Handlers'];
83
84
        $this->processRenderFile(
85
            'crud/controller.php.twig',
86
            $target,
87
            null,
88
            $entityClass,
89
            $entityNamespace,
90
            key($handler),
91
            $options
92
        );
93
    }
94
95
    /**
96
     * @param $arguments
97
     * @param $forceOverwrite
98
     */
99
    protected function generateHandlers($arguments, $forceOverwrite)
100
    {
101
        $dir = $this->bundle->getPath() . '/' . $arguments['dir'];
102
103
        $parts = explode('\\', $this->entity);
104
        $entityClass = array_pop($parts);
105
        $serviceNamespace = $arguments['dir'];
106
107
        $target = sprintf(
108
            '%s/%s.php',
109
            $dir,
110
            $arguments['classname']
111
        );
112
113
        if (!$forceOverwrite && file_exists($target)) {
114
            throw new \RuntimeException('Unable to generate the handler as it already exists.');
115
        }
116
117
        $this->processRenderFile(
118
            'crud/handler.php.twig',
119
            $target,
120
            $arguments['classname'],
121
            $entityClass,
122
            $serviceNamespace,
123
            null
124
        );
125
126
        $this->addToServices($this->data[0]['Handlers']);
127
    }
128
129
    protected function generateHandlerException()
130
    {
131
        return $this->renderFile('crud/formException.php.twig', sprintf('%s/Exception/InvalidFormException.php', $this->bundle->getPath()), array(
132
            'namespace' => $this->bundle->getNamespace(),
133
        ));
134
    }
135
136 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...
137
    {
138
        $parts = explode('\\', $this->entity);
139
        $entityClass = array_pop($parts);
140
141
        $dir = sprintf('%s/../tests/%s/Controller/', $this->rootDir, $this->bundle->getName());
142
143
        $target = $dir . $entityClass . 'ControllerTest.php';
144
145
146
        $this->processRenderFile(
147
            'crud/tests/controllerTest.php.twig',
148
            $target,
149
            sprintf('%sControllerTest', $entityClass),
150
            $entityClass,
151
            'Controller',
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
            'actions' => $this->actions,
168
            'route_prefix' => $this->routePrefix,
169
            'route_name_prefix' => $this->routeNamePrefix,
170
            'bundle' => $this->bundle->getName(),
171
            'entity' => $this->entity,
172
            'entity_singularized' => $this->entitySingularized,
173
            'entity_pluralized' => $this->entityPluralized,
174
            'entity_class' => $entityClass,
175
            'namespace' => $this->bundle->getNamespace(),
176
            'service_namespace' => $serviceNamespace,
177
            'entity_namespace' => $serviceNamespace,
178
            'format' => $this->format,
179
            'class_name' => $classname,
180
            'service' => $service,
181
            'fields' => $this->metadata->fieldMappings,
182
            'options' => $options
183
        ));
184
    }
185
186
    /**
187
     * @param $definition
188
     */
189
    protected function addToServices($definition)
190
    {
191
        $file = sprintf('%s/config/%s', $this->rootDir, 'services.yml');
192
193
        $yaml = new Parser();
194
        $services = $yaml->parse(file_get_contents($file));
195
196
        if (empty($services['services'][sprintf('app.%s_repository', strtolower($this->entity))])) {
197
            $file = sprintf('%s/config/%s', $this->rootDir, 'gen/services.yml');
198
            $services = array_merge($services, $yaml->parse(file_get_contents($file)));
199
        }
200
201
        $array = array(
202
            key($definition) => array(
203
                'class' => $definition[key($definition)]['class'],
204
                'arguments' => array(
205
                    $definition[key($definition)]['arguments'][0][0],
206
                    $definition[key($definition)]['arguments'][1][0],
207
                )
208
            )
209
        );
210
211
        $services['services'][key($array)] = $array[key($array)];
212
213
        $dumper = new Dumper();
214
215
        $yaml = $dumper->dump($services, 4);
216
217
        $file = sprintf('%s/config/%s', $this->rootDir, 'gen/services.yml');
218
219
        file_put_contents($file, $yaml);
220
    }
221
222
    /**
223
     * @return array
224
     */
225 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...
226
    {
227
        $data = array();
228
        $dir = sprintf('%s/config/gen/%s', $this->rootDir, $this->entity);
229
        $yaml = new Parser();
230
231
        $files = scandir(str_replace('\\', '/', $dir));
232
233
        foreach ($files as $file) {
234
            if (0 == strpos($file, '.')) {
235
                continue;
236
            }
237
238
            $data[] = $yaml->parse(file_get_contents($dir . '/' . $file));
239
        }
240
241
        return $data;
242
    }
243
244
    /**
245
     * {@inheritdoc}
246
     */
247
    protected function generateConfiguration()
248
    {
249
        if (!in_array($this->format, array('yml', 'xml', 'php'))) {
250
            return;
251
        }
252
253
        $target = sprintf(
254
            '%s/Resources/config/routing/%s.%s',
255
            $this->bundle->getPath(),
256
            strtolower(str_replace('\\', '_', $this->entity)),
257
            $this->format
258
        );
259
260
        $this->renderFile('crud/config/routing.' . $this->format . '.twig', $target, array(
261
            'actions' => $this->actions,
262
            'route_prefix' => $this->routePrefix,
263
            'route_name_prefix' => $this->routeNamePrefix,
264
            'bundle' => $this->bundle->getName(),
265
            'entity' => $this->entity,
266
        ));
267
    }
268
}
269