Completed
Push — master ( 28a6ee...eae980 )
by Eric
9s
created

ResourceExtension   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 316
Duplicated Lines 29.75 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 83.93%

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 47
c 5
b 0
f 1
lcom 1
cbo 7
dl 94
loc 316
ccs 141
cts 168
cp 0.8393
rs 8.439

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getConfiguration() 0 8 2
A getAlias() 0 4 1
A loadInternal() 0 16 3
A loadBundle() 0 3 1
B configureResource() 0 16 8
A createRepositoryDefinition() 8 8 1
F loadResource() 54 70 20
B createResourceDefinition() 0 32 2
A createManagerAlias() 0 8 2
A createFactoryDefinition() 0 16 2
A createFormDefinition() 11 11 1
A createChoiceFormDefinition() 10 10 1
A createDomainManagerDefinition() 0 13 1
A createControllerDefinition() 11 11 1

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ResourceExtension often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ResourceExtension, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of the Lug package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Lug\Bundle\ResourceBundle\DependencyInjection\Extension;
13
14
use Lug\Bundle\ResourceBundle\ResourceBundleInterface;
15
use Lug\Bundle\ResourceBundle\Util\ClassUtils;
16
use Lug\Component\Resource\Model\Resource;
17
use Lug\Component\Resource\Model\ResourceInterface;
18
use Lug\Component\Translation\Factory\TranslatableFactory;
19
use Symfony\Component\DependencyInjection\ContainerBuilder;
20
use Symfony\Component\DependencyInjection\Definition;
21
use Symfony\Component\DependencyInjection\Reference;
22
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
23
24
/**
25
 * @author GeLo <[email protected]>
26
 */
27
class ResourceExtension extends ConfigurableExtension
28
{
29
    /**
30
     * @var ResourceBundleInterface
31
     */
32
    private $bundle;
33
34
    /**
35
     * @param ResourceBundleInterface $bundle
36
     */
37 8
    public function __construct(ResourceBundleInterface $bundle)
38
    {
39 8
        $this->bundle = $bundle;
40 8
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45 7
    public function getConfiguration(array $config, ContainerBuilder $container)
46
    {
47 7
        if (!class_exists($class = ClassUtils::getNamespace($this).'\\Configuration')) {
48
            $class = ResourceConfiguration::class;
49
        }
50
51 7
        return new $class($this->bundle);
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 8
    public function getAlias()
58
    {
59 8
        return $this->bundle->getAlias();
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65 7
    protected function loadInternal(array $config, ContainerBuilder $container)
66
    {
67 7
        foreach ($this->bundle->getResources() as $resource) {
68 7
            $resourceConfig = $config['resources'][$resource->getName()];
69
70 7
            $this->configureResource($resource, $resourceConfig);
71 7
            $this->loadResource($resource, $container);
72
73 7
            if ($resource->getTranslation() !== null) {
74
                $this->configureResource($resource->getTranslation(), $resourceConfig['translation']);
0 ignored issues
show
Documentation introduced by
$resource->getTranslation() is of type null, but the function expects a object<Lug\Component\Res...odel\ResourceInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
75
                $this->loadResource($resource->getTranslation(), $container);
0 ignored issues
show
Documentation introduced by
$resource->getTranslation() is of type null, but the function expects a object<Lug\Component\Res...odel\ResourceInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
76
            }
77 7
        }
78
79 7
        $this->loadBundle($config, $container);
80 7
    }
81
82
    /**
83
     * @param mixed[]          $config
84
     * @param ContainerBuilder $container
85
     */
86
    protected function loadBundle(array $config, ContainerBuilder $container)
87
    {
88
    }
89
90
    /**
91
     * @param ResourceInterface $resource
92
     * @param mixed[]           $config
93
     */
94 7
    private function configureResource(ResourceInterface $resource, array $config)
95
    {
96 7
        $resource->setModel($config['model']);
97 7
        $resource->setDriver($config['driver']['name']);
98 7
        $resource->setDriverManager($config['driver']['manager']);
99 7
        $resource->setDriverMappingPath($config['driver']['mapping']['path']);
100 7
        $resource->setDriverMappingFormat($config['driver']['mapping']['format']);
101 7
        $resource->setRepository($config['repository']);
102 7
        $resource->setFactory(isset($config['factory']) ? $config['factory'] : null);
103 7
        $resource->setForm(isset($config['form']) ? $config['form'] : null);
104 7
        $resource->setChoiceForm(isset($config['choice_form']) ? $config['choice_form'] : null);
105 7
        $resource->setDomainManager(isset($config['domain_manager']) ? $config['domain_manager'] : null);
106 7
        $resource->setController(isset($config['controller']) ? $config['controller'] : null);
107 7
        $resource->setIdPropertyPath(isset($config['id_property_path']) ? $config['id_property_path'] : null);
108 7
        $resource->setLabelPropertyPath(isset($config['label_property_path']) ? $config['label_property_path'] : null);
109 7
    }
110
111
    /**
112
     * @param ResourceInterface $resource
113
     * @param ContainerBuilder  $container
114
     */
115 7
    private function loadResource(ResourceInterface $resource, ContainerBuilder $container)
116
    {
117 7
        $container->setDefinition('lug.resource.'.$resource->getName(), $this->createResourceDefinition($resource));
118
119 7
        if ($resource->getDriverManager() !== null) {
120 7
            $container->setAlias('lug.manager.'.$resource->getName(), $this->createManagerAlias($resource));
121 7
        }
122
123 7 View Code Duplication
        if ($resource->getRepository() !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
124 7
            $repository = 'lug.repository.'.$resource->getName();
125
126 7
            if (class_exists($resource->getRepository())) {
127 7
                $container->setDefinition($repository, $this->createRepositoryDefinition($resource));
128 7
            } elseif ($repository !== $resource->getRepository()) {
129
                $container->setAlias($repository, $resource->getRepository());
130
            }
131 7
        }
132
133 7 View Code Duplication
        if ($resource->getFactory() !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
134 7
            $factory = 'lug.factory.'.$resource->getName();
135
136 7
            if (class_exists($resource->getFactory())) {
137 7
                $container->setDefinition($factory, $this->createFactoryDefinition($resource));
138 7
            } elseif ($factory !== $resource->getFactory()) {
139
                $container->setAlias($factory, $resource->getFactory());
140
            }
141 7
        }
142
143 7 View Code Duplication
        if ($resource->getForm() !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
144 7
            $form = 'lug.form.type.'.$resource->getName();
145
146 7
            if (class_exists($resource->getForm())) {
147 7
                $container->setDefinition($form, $this->createFormDefinition($resource));
148 7
            } elseif ($form !== $resource->getForm()) {
149
                $container->setAlias($form, $resource->getForm());
150
            }
151 7
        }
152
153 7 View Code Duplication
        if ($resource->getChoiceForm() !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
154 7
            $choiceForm = 'lug.form.type.'.$resource->getName().'.choice';
155
156 7
            if (class_exists($resource->getChoiceForm())) {
157 7
                $container->setDefinition($choiceForm, $this->createChoiceFormDefinition($resource));
158 7
            } elseif ($choiceForm !== $resource->getChoiceForm()) {
159
                $container->setAlias($choiceForm, $resource->getChoiceForm());
160
            }
161 7
        }
162
163 7 View Code Duplication
        if ($resource->getDomainManager() !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
164 7
            $domainManager = 'lug.domain_manager.'.$resource->getName();
165
166 7
            if (class_exists($resource->getDomainManager())) {
167 7
                $container->setDefinition($domainManager, $this->createDomainManagerDefinition($resource));
168 7
            } elseif ($domainManager !== $resource->getDomainManager()) {
169
                $container->setAlias($domainManager, $resource->getDomainManager());
170
            }
171 7
        }
172
173 7 View Code Duplication
        if ($resource->getController() !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
174 7
            $controller = 'lug.controller.'.$resource->getName();
175
176 7
            if (class_exists($resource->getController())) {
177 7
                $container->setDefinition($controller, $this->createControllerDefinition($resource));
178 7
            } elseif ($controller !== $resource->getController()) {
179
                $container->setAlias($container, $resource->getController());
0 ignored issues
show
Documentation introduced by
$container is of type object<Symfony\Component...ction\ContainerBuilder>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
180
            }
181 7
        }
182
183 7
        $container->addObjectResource($resource);
184 7
    }
185
186
    /**
187
     * @param ResourceInterface $resource
188
     *
189
     * @return Definition
190
     */
191 7
    private function createResourceDefinition(ResourceInterface $resource)
192
    {
193 7
        $definition = new Definition(Resource::class, [
194 7
            $resource->getName(),
195 7
            $resource->getInterfaces(),
196 7
            $resource->getModel(),
197 7
        ]);
198
199
        $definition
200 7
            ->addMethodCall('setDriver', [$resource->getDriver()])
201 7
            ->addMethodCall('setDriverManager', [$resource->getDriverManager()])
202 7
            ->addMethodCall('setDriverMappingPath', [$resource->getDriverMappingPath()])
203 7
            ->addMethodCall('setDriverMappingFormat', [$resource->getDriverMappingFormat()])
204 7
            ->addMethodCall('setRepository', [$resource->getRepository()])
205 7
            ->addMethodCall('setFactory', [$resource->getFactory()])
206 7
            ->addMethodCall('setForm', [$resource->getForm()])
207 7
            ->addMethodCall('setChoiceForm', [$resource->getChoiceForm()])
208 7
            ->addMethodCall('setDomainManager', [$resource->getDomainManager()])
209 7
            ->addMethodCall('setController', [$resource->getController()])
210 7
            ->addMethodCall('setIdPropertyPath', [$resource->getIdPropertyPath()])
211 7
            ->addMethodCall('setLabelPropertyPath', [$resource->getLabelPropertyPath()])
212 7
            ->addTag('lug.resource');
213
214 7
        if ($resource->getTranslation() !== null) {
215
            $definition->addMethodCall(
216
                'setTranslation',
217
                [new Reference('lug.resource.'.$resource->getTranslation()->getName())]
218
            );
219
        }
220
221 7
        return $definition;
222
    }
223
224
    /**
225
     * @param ResourceInterface $resource
226
     *
227
     * @return string
228
     */
229 7
    private function createManagerAlias(ResourceInterface $resource)
230
    {
231 7
        if ($resource->getDriver() === ResourceInterface::DRIVER_DOCTRINE_MONGODB) {
232
            return 'doctrine_mongodb.odm.'.$resource->getDriverManager().'_document_manager';
233
        }
234
235 7
        return 'doctrine.orm.'.$resource->getDriverManager().'_entity_manager';
236
    }
237
238
    /**
239
     * @param ResourceInterface $resource
240
     *
241
     * @return Definition
242
     */
243 7
    private function createFactoryDefinition(ResourceInterface $resource)
244
    {
245
        $arguments = [
246 7
            new Reference('lug.resource.'.$resource->getName()),
247 7
            new Reference('property_accessor'),
248 7
        ];
249
250 7
        if (is_a($resource->getFactory(), TranslatableFactory::class, true)) {
251
            $arguments[] = new Reference('lug.translation.context.locale');
252
        }
253
254 7
        $definition = new Definition($resource->getFactory(), $arguments);
255 7
        $definition->addTag('lug.factory', ['resource' => $resource->getName()]);
256
257 7
        return $definition;
258
    }
259
260
    /**
261
     * @param ResourceInterface $resource
262
     *
263
     * @return Definition
264
     */
265 7 View Code Duplication
    private function createRepositoryDefinition(ResourceInterface $resource)
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...
266
    {
267 7
        $definition = new Definition($resource->getRepository(), [$resource->getModel()]);
268 7
        $definition->setFactory([new Reference('lug.manager.'.$resource->getName()), 'getRepository']);
269 7
        $definition->addTag('lug.repository', ['resource' => $resource->getName()]);
270
271 7
        return $definition;
272
    }
273
274
    /**
275
     * @param ResourceInterface $resource
276
     *
277
     * @return Definition
278
     */
279 7 View Code Duplication
    private function createFormDefinition(ResourceInterface $resource)
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...
280
    {
281 7
        $definition = new Definition($resource->getForm(), [
282 7
            new Reference('lug.resource.'.$resource->getName()),
283 7
            new Reference('lug.factory.'.$resource->getName()),
284 7
        ]);
285
286 7
        $definition->addTag('form.type');
287
288 7
        return $definition;
289
    }
290
291
    /**
292
     * @param ResourceInterface $resource
293
     *
294
     * @return Definition
295
     */
296 7 View Code Duplication
    private function createChoiceFormDefinition(ResourceInterface $resource)
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...
297
    {
298 7
        $definition = new Definition($resource->getChoiceForm(), [
299 7
            new Reference('lug.resource.'.$resource->getName()),
300 7
        ]);
301
302 7
        $definition->addTag('form.type');
303
304 7
        return $definition;
305
    }
306
307
    /**
308
     * @param ResourceInterface $resource
309
     *
310
     * @return Definition
311
     */
312 7
    private function createDomainManagerDefinition(ResourceInterface $resource)
313
    {
314 7
        $definition = new Definition($resource->getDomainManager(), [
315 7
            new Reference('lug.resource.'.$resource->getName()),
316 7
            new Reference('lug.resource.domain.event_dispatcher'),
317 7
            new Reference('lug.manager.'.$resource->getName()),
318 7
            new Reference('lug.repository.'.$resource->getName()),
319 7
        ]);
320
321 7
        $definition->addTag('lug.domain_manager', ['resource' => $resource->getName()]);
322
323 7
        return $definition;
324
    }
325
326
    /**
327
     * @param ResourceInterface $resource
328
     *
329
     * @return Definition
330
     */
331 7 View Code Duplication
    private function createControllerDefinition(ResourceInterface $resource)
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...
332
    {
333 7
        $definition = new Definition($resource->getController(), [
334 7
            new Reference('lug.resource.'.$resource->getName()),
335 7
        ]);
336
337 7
        $definition->addMethodCall('setContainer', [new Reference('service_container')]);
338 7
        $definition->addTag('lug.controller', ['resource' => $resource->getName()]);
339
340 7
        return $definition;
341
    }
342
}
343