Passed
Push — master ( b52e0b...0b7a94 )
by Dominik
02:34
created

DoctrineOrmServiceProvider   C

Complexity

Total Complexity 38

Size/Duplication

Total Lines 453
Duplicated Lines 10.38 %

Coupling/Cohesion

Components 1
Dependencies 18

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 38
lcom 1
cbo 18
dl 47
loc 453
ccs 187
cts 187
cp 1
rs 6.16
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
B register() 0 36 1
A getOrmEmDefaultOptions() 0 8 1
B getOrmEmsOptionsInitializerDefinition() 29 29 6
B getOrmEmsDefinition() 0 26 3
A getOrmEmsConfigServiceProvider() 0 13 2
B getOrmEmConfigByNameAndOptionsDefinition() 0 57 5
B getOrmMappingDriverChainDefinition() 0 31 5
A getOrmMappingDriverChainFactoryDefinition() 0 6 1
A getOrmMappingDriverFactoryAnnotation() 0 11 1
A getOrmMappingDriverFactoryYaml() 0 6 1
A getOrmMappingDriverFactorySimpleYaml() 9 9 1
A getOrmMappingDriverFactoryXml() 0 6 1
A getOrmMappingDriverFactorySimpleXml() 9 9 1
A getOrmMappingDriverFactoryPhp() 0 6 1
A getOrmNamingStrategyDefinition() 0 6 1
A getOrmQuoteStrategyDefinition() 0 6 1
A getOrmEntityListenerResolverDefinition() 0 6 1
A getOrmRepositoryFactoryDefinition() 0 6 1
A getOrmSecondLevelCacheConfigurationDefinition() 0 20 1
A getOrmEmDefinition() 0 8 1
A getOrmEmConfigDefinition() 0 8 1
A getOrmManagerRegistryDefintion() 0 6 1

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
declare(strict_types=1);
4
5
/*
6
 * (c) Beau Simensen <[email protected]> (https://github.com/dflydev/dflydev-doctrine-orm-service-provider)
7
 */
8
9
namespace Chubbyphp\ServiceProvider;
10
11
use Chubbyphp\ServiceProvider\Registry\DoctrineOrmManagerRegistry;
12
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
13
use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver;
14
use Doctrine\DBAL\Types\Type;
15
use Doctrine\ORM\Cache\CacheConfiguration;
16
use Doctrine\ORM\Cache\DefaultCacheFactory;
17
use Doctrine\ORM\Cache\RegionsConfiguration;
18
use Doctrine\ORM\Configuration;
19
use Doctrine\ORM\EntityManager;
20
use Doctrine\ORM\EntityRepository;
21
use Doctrine\ORM\Mapping\ClassMetadataFactory;
22
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
23
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
24
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
25
use Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver;
26
use Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver;
27
use Doctrine\ORM\Mapping\Driver\XmlDriver;
28
use Doctrine\ORM\Mapping\Driver\YamlDriver;
29
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
30
use Pimple\Container;
31
use Pimple\ServiceProviderInterface;
32
33
final class DoctrineOrmServiceProvider implements ServiceProviderInterface
34
{
35
    /**
36
     * Register ORM service.
37
     *
38
     * @param Container $container
39
     */
40 5
    public function register(Container $container)
41
    {
42 5
        $container['doctrine.orm.em.default_options'] = $this->getOrmEmDefaultOptions();
43 5
        $container['doctrine.orm.ems.options.initializer'] = $this->getOrmEmsOptionsInitializerDefinition($container);
44 5
        $container['doctrine.orm.ems'] = $this->getOrmEmsDefinition($container);
45 5
        $container['doctrine.orm.ems.config'] = $this->getOrmEmsConfigServiceProvider($container);
46 5
        $container['doctrine.orm.proxies_dir'] = sys_get_temp_dir();
47 5
        $container['doctrine.orm.auto_generate_proxies'] = true;
48 5
        $container['doctrine.orm.proxies_namespace'] = 'DoctrineProxy';
49 5
        $container['doctrine.orm.mapping_driver_chain'] = $this->getOrmMappingDriverChainDefinition($container);
50 5
        $container['doctrine.orm.mapping_driver_chain.factory'] = $this->getOrmMappingDriverChainFactoryDefinition($container);
51 5
        $container['doctrine.orm.mapping_driver.factory.annotation'] = $this->getOrmMappingDriverFactoryAnnotation($container);
52 5
        $container['doctrine.orm.mapping_driver.factory.yml'] = $this->getOrmMappingDriverFactoryYaml($container);
53 5
        $container['doctrine.orm.mapping_driver.factory.simple_yml'] = $this->getOrmMappingDriverFactorySimpleYaml($container);
54 5
        $container['doctrine.orm.mapping_driver.factory.xml'] = $this->getOrmMappingDriverFactoryXml($container);
55 5
        $container['doctrine.orm.mapping_driver.factory.simple_xml'] = $this->getOrmMappingDriverFactorySimpleXml($container);
56 5
        $container['doctrine.orm.mapping_driver.factory.php'] = $this->getOrmMappingDriverFactoryPhp($container);
57 5
        $container['doctrine.orm.default_cache.provider'] = ['driver' => 'array'];
58 5
        $container['doctrine.orm.custom.functions.string'] = [];
59 5
        $container['doctrine.orm.custom.functions.numeric'] = [];
60 5
        $container['doctrine.orm.custom.functions.datetime'] = [];
61 5
        $container['doctrine.orm.custom.hydration_modes'] = [];
62 5
        $container['doctrine.orm.class_metadata_factory_name'] = ClassMetadataFactory::class;
63 5
        $container['doctrine.orm.default_repository_class'] = EntityRepository::class;
64 5
        $container['doctrine.orm.strategy.naming'] = $this->getOrmNamingStrategyDefinition($container);
65 5
        $container['doctrine.orm.strategy.quote'] = $this->getOrmQuoteStrategyDefinition($container);
66 5
        $container['doctrine.orm.entity_listener_resolver'] = $this->getOrmEntityListenerResolverDefinition($container);
67 5
        $container['doctrine.orm.repository_factory'] = $this->getOrmRepositoryFactoryDefinition($container);
68 5
        $container['doctrine.orm.second_level_cache.enabled'] = false;
69 5
        $container['doctrine.orm.second_level_cache.configuration'] = $this->getOrmSecondLevelCacheConfigurationDefinition($container);
70 5
        $container['doctrine.orm.second_level_cache.provider'] = null;
71 5
        $container['doctrine.orm.default.query_hints'] = [];
72 5
        $container['doctrine.orm.em'] = $this->getOrmEmDefinition($container);
73 5
        $container['doctrine.orm.em.config'] = $this->getOrmEmConfigDefinition($container);
74 5
        $container['doctrine.orm.manager_registry'] = $this->getOrmManagerRegistryDefintion($container);
75 5
    }
76
77
    /**
78
     * @return array
79
     */
80 5
    private function getOrmEmDefaultOptions(): array
81
    {
82
        return [
83 5
            'connection' => 'default',
84
            'mappings' => [],
85
            'types' => [],
86
        ];
87
    }
88
89
    /**
90
     * @param Container $container
91
     *
92
     * @return callable
93
     */
94 View Code Duplication
    private function getOrmEmsOptionsInitializerDefinition(Container $container): callable
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...
95
    {
96 5
        return $container->protect(function () use ($container) {
97 5
            static $initialized = false;
98
99 5
            if ($initialized) {
100 5
                return;
101
            }
102
103 5
            $initialized = true;
104
105 5
            if (!isset($container['doctrine.orm.ems.options'])) {
106 4
                $container['doctrine.orm.ems.options'] = [
107 4
                    'default' => isset($container['doctrine.orm.em.options']) ? $container['doctrine.orm.em.options'] : [],
108
                ];
109
            }
110
111 5
            $tmp = $container['doctrine.orm.ems.options'];
112 5
            foreach ($tmp as $name => &$options) {
113 5
                $options = array_replace($container['doctrine.orm.em.default_options'], $options);
114
115 5
                if (!isset($container['doctrine.orm.ems.default'])) {
116 5
                    $container['doctrine.orm.ems.default'] = $name;
117
                }
118
            }
119
120 5
            $container['doctrine.orm.ems.options'] = $tmp;
121 5
        });
122
    }
123
124
    /**
125
     * @param Container $container
126
     *
127
     * @return callable
128
     */
129
    private function getOrmEmsDefinition(Container $container): callable
130
    {
131 5
        return function () use ($container) {
132 5
            $container['doctrine.orm.ems.options.initializer']();
133
134 5
            $ems = new Container();
135 5
            foreach ($container['doctrine.orm.ems.options'] as $name => $options) {
136 5
                if ($container['doctrine.orm.ems.default'] === $name) {
137
                    // we use shortcuts here in case the default has been overridden
138 5
                    $config = $container['doctrine.orm.em.config'];
139
                } else {
140 1
                    $config = $container['doctrine.orm.ems.config'][$name];
141
                }
142
143 3
                $ems[$name] = function () use ($container, $options, $config) {
144 3
                    return EntityManager::create(
145 3
                        $container['doctrine.dbal.dbs'][$options['connection']],
146 3
                        $config,
147 3
                        $container['doctrine.dbal.dbs.event_manager'][$options['connection']]
148
                    );
149 3
                };
150
            }
151
152 3
            return $ems;
153 5
        };
154
    }
155
156
    /**
157
     * @param Container $container
158
     *
159
     * @return callable
160
     */
161
    private function getOrmEmsConfigServiceProvider(Container $container): callable
162
    {
163 5
        return function () use ($container) {
164 5
            $container['doctrine.orm.ems.options.initializer']();
165
166 5
            $configs = new Container();
167 5
            foreach ($container['doctrine.orm.ems.options'] as $name => $options) {
168 5
                $configs[$name] = $this->getOrmEmConfigByNameAndOptionsDefinition($container, $name, $options);
169
            }
170
171 5
            return $configs;
172 5
        };
173
    }
174
175
    /**
176
     * @param Container $container
177
     * @param string    $name
178
     * @param array     $options
179
     *
180
     * @return callable
181
     */
182
    private function getOrmEmConfigByNameAndOptionsDefinition(
183
        Container $container,
184
        string $name,
185
        array $options
186
    ): callable {
187 5
        return function () use ($container, $name, $options) {
188 5
            $config = new Configuration();
189
190 5
            $config->setProxyDir($container['doctrine.orm.proxies_dir']);
191 5
            $config->setAutoGenerateProxyClasses($container['doctrine.orm.auto_generate_proxies']);
192 5
            $config->setProxyNamespace($container['doctrine.orm.proxies_namespace']);
193 5
            $config->setMetadataDriverImpl(
194 5
                $container['doctrine.orm.mapping_driver_chain']($name, $config, (array) $options['mappings'])
195
            );
196
197 3
            foreach (['query', 'hydration', 'metadata', 'result'] as $cacheType) {
198 3
                $setMethod = sprintf('set%sCacheImpl', ucfirst($cacheType));
199 3
                $cacheOptions = $options[sprintf('%s_cache', $cacheType)] ?? $container['doctrine.orm.default_cache.provider'];
200 3
                if (is_string($cacheOptions)) {
201 1
                    $cacheOptions = ['driver' => $cacheOptions];
202
                }
203
204 3
                $config->$setMethod(
205 3
                    $container['doctrine.cache.locator'](sprintf('%s_%s', $name, $cacheType), $cacheOptions)
206
                );
207
            }
208
209 3
            foreach ((array) $options['types'] as $typeName => $typeClass) {
210 1
                if (Type::hasType($typeName)) {
211 1
                    Type::overrideType($typeName, $typeClass);
212
                } else {
213 1
                    Type::addType($typeName, $typeClass);
214
                }
215
            }
216
217 3
            $config->setCustomStringFunctions($container['doctrine.orm.custom.functions.string']);
218 3
            $config->setCustomNumericFunctions($container['doctrine.orm.custom.functions.numeric']);
219 3
            $config->setCustomDatetimeFunctions($container['doctrine.orm.custom.functions.datetime']);
220 3
            $config->setCustomHydrationModes($container['doctrine.orm.custom.hydration_modes']);
221
222 3
            $config->setClassMetadataFactoryName($container['doctrine.orm.class_metadata_factory_name']);
223 3
            $config->setDefaultRepositoryClassName($container['doctrine.orm.default_repository_class']);
224
225 3
            $config->setNamingStrategy($container['doctrine.orm.strategy.naming']);
226 3
            $config->setQuoteStrategy($container['doctrine.orm.strategy.quote']);
227
228 3
            $config->setEntityListenerResolver($container['doctrine.orm.entity_listener_resolver']);
229 3
            $config->setRepositoryFactory($container['doctrine.orm.repository_factory']);
230
231 3
            $config->setSecondLevelCacheEnabled($container['doctrine.orm.second_level_cache.enabled']);
232 3
            $config->setSecondLevelCacheConfiguration($container['doctrine.orm.second_level_cache.configuration']);
233
234 3
            $config->setDefaultQueryHints($container['doctrine.orm.default.query_hints']);
235
236 3
            return $config;
237 5
        };
238
    }
239
240
    /**
241
     * @param Container $container
242
     *
243
     * @return callable
244
     */
245
    private function getOrmMappingDriverChainDefinition(Container $container): callable
246
    {
247 5
        return $container->protect(function (string $name, Configuration $config, array $mappings) use ($container) {
248 5
            $container['doctrine.orm.ems.options.initializer']();
249
250
            /** @var MappingDriverChain $chain */
251 5
            $chain = $container['doctrine.orm.mapping_driver_chain.factory']();
252 5
            foreach ($mappings as $mapping) {
253 4
                if (!is_array($mapping)) {
254 1
                    throw new \InvalidArgumentException(
255 1
                        'The "doctrine.orm.em.options" option "mappings" should be an array of arrays.'
256
                    );
257
                }
258
259 3
                if (isset($mapping['alias'])) {
260 2
                    $config->addEntityNamespace($mapping['alias'], $mapping['namespace']);
261
                }
262
263 3
                $factoryKey = sprintf('doctrine.orm.mapping_driver.factory.%s', $mapping['type']);
264 3
                if (!isset($container[$factoryKey])) {
265 1
                    throw new \InvalidArgumentException(
266 1
                        sprintf('There is no driver factory for type "%s"', $mapping['type'])
267
                    );
268
                }
269
270 2
                $chain->addDriver($container[$factoryKey]($mapping, $config), $mapping['namespace']);
271
            }
272
273 3
            return $container['doctrine.orm.mapping_driver_chain.instances.'.$name] = $chain;
274 5
        });
275
    }
276
277
    /**
278
     * @param Container $container
279
     *
280
     * @return callable
281
     */
282
    private function getOrmMappingDriverChainFactoryDefinition(Container $container): callable
283
    {
284 5
        return $container->protect(function () use ($container) {
285 5
            return new MappingDriverChain();
286 5
        });
287
    }
288
289
    /**
290
     * @param Container $container
291
     *
292
     * @return callable
293
     */
294
    private function getOrmMappingDriverFactoryAnnotation(Container $container): callable
295
    {
296 5
        return $container->protect(function (array $mapping, Configuration $config) {
297 2
            $useSimpleAnnotationReader = $mapping['use_simple_annotation_reader'] ?? true;
298
299 2
            return $config->newDefaultAnnotationDriver(
300 2
                (array) $mapping['path'],
301 2
                $useSimpleAnnotationReader
302
            );
303 5
        });
304
    }
305
306
    /**
307
     * @param Container $container
308
     *
309
     * @return callable
310
     */
311
    private function getOrmMappingDriverFactoryYaml(Container $container): callable
312
    {
313 5
        return $container->protect(function (array $mapping, Configuration $config) {
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
314 2
            return new YamlDriver($mapping['path'], $mapping['extension'] ?? YamlDriver::DEFAULT_FILE_EXTENSION);
315 5
        });
316
    }
317
318
    /**
319
     * @param Container $container
320
     *
321
     * @return callable
322
     */
323 View Code Duplication
    private function getOrmMappingDriverFactorySimpleYaml(Container $container): callable
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...
324
    {
325 5
        return $container->protect(function (array $mapping, Configuration $config) {
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
326 2
            return new SimplifiedYamlDriver(
327 2
                [$mapping['path'] => $mapping['namespace']],
328 2
                $mapping['extension'] ?? SimplifiedYamlDriver::DEFAULT_FILE_EXTENSION
329
            );
330 5
        });
331
    }
332
333
    /**
334
     * @param Container $container
335
     *
336
     * @return callable
337
     */
338
    private function getOrmMappingDriverFactoryXml(Container $container): callable
339
    {
340 5
        return $container->protect(function (array $mapping, Configuration $config) {
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
341 2
            return new XmlDriver($mapping['path'], $mapping['extension'] ?? XmlDriver::DEFAULT_FILE_EXTENSION);
342 5
        });
343
    }
344
345
    /**
346
     * @param Container $container
347
     *
348
     * @return callable
349
     */
350 View Code Duplication
    private function getOrmMappingDriverFactorySimpleXml(Container $container): callable
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...
351
    {
352 5
        return $container->protect(function (array $mapping, Configuration $config) {
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
353 2
            return new SimplifiedXmlDriver(
354 2
                [$mapping['path'] => $mapping['namespace']],
355 2
                $mapping['extension'] ?? SimplifiedXmlDriver::DEFAULT_FILE_EXTENSION
356
            );
357 5
        });
358
    }
359
360
    /**
361
     * @param Container $container
362
     *
363
     * @return callable
364
     */
365
    private function getOrmMappingDriverFactoryPhp(Container $container): callable
366
    {
367 5
        return $container->protect(function (array $mapping, Configuration $config) {
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
368 2
            return new StaticPHPDriver($mapping['path']);
369 5
        });
370
    }
371
372
    /**
373
     * @param Container $container
374
     *
375
     * @return callable
376
     */
377
    private function getOrmNamingStrategyDefinition(Container $container): callable
378
    {
379 5
        return function () use ($container) {
380 2
            return new DefaultNamingStrategy();
381 5
        };
382
    }
383
384
    /**
385
     * @param Container $container
386
     *
387
     * @return callable
388
     */
389
    private function getOrmQuoteStrategyDefinition(Container $container): callable
390
    {
391 5
        return function () use ($container) {
392 2
            return new DefaultQuoteStrategy();
393 5
        };
394
    }
395
396
    /**
397
     * @param Container $container
398
     *
399
     * @return callable
400
     */
401
    private function getOrmEntityListenerResolverDefinition(Container $container): callable
402
    {
403 5
        return function () use ($container) {
404 2
            return new DefaultEntityListenerResolver();
405 5
        };
406
    }
407
408
    /**
409
     * @param Container $container
410
     *
411
     * @return callable
412
     */
413
    private function getOrmRepositoryFactoryDefinition(Container $container): callable
414
    {
415 5
        return function () use ($container) {
416 2
            return new DefaultRepositoryFactory();
417 5
        };
418
    }
419
420
    /**
421
     * @param Container $container
422
     *
423
     * @return callable
424
     */
425
    private function getOrmSecondLevelCacheConfigurationDefinition(Container $container): callable
426
    {
427 5
        return function () use ($container) {
428 3
            $regionsCacheConfiguration = new RegionsConfiguration();
429 3
            $factory = new DefaultCacheFactory(
430 3
                $regionsCacheConfiguration,
431 3
                $container['doctrine.cache.locator'](
432 3
                    'second_level',
433 3
                    $container['doctrine.orm.second_level_cache.provider']
434 3
                        ?? $container['doctrine.orm.default_cache.provider']
435
                )
436
            );
437
438 3
            $cacheConfiguration = new CacheConfiguration();
439 3
            $cacheConfiguration->setCacheFactory($factory);
440 3
            $cacheConfiguration->setRegionsConfiguration($regionsCacheConfiguration);
441
442 3
            return $cacheConfiguration;
443 5
        };
444
    }
445
446
    /**
447
     * @param Container $container
448
     *
449
     * @return callable
450
     */
451
    private function getOrmEmDefinition(Container $container): callable
452
    {
453 5
        return function () use ($container) {
454 4
            $ems = $container['doctrine.orm.ems'];
455
456 2
            return $ems[$container['doctrine.orm.ems.default']];
457 5
        };
458
    }
459
460
    /**
461
     * @param Container $container
462
     *
463
     * @return callable
464
     */
465
    private function getOrmEmConfigDefinition(Container $container): callable
466
    {
467 5
        return function () use ($container) {
468 5
            $configs = $container['doctrine.orm.ems.config'];
469
470 5
            return $configs[$container['doctrine.orm.ems.default']];
471 5
        };
472
    }
473
474
    /**
475
     * @param Container $container
476
     *
477
     * @return callable
478
     */
479
    private function getOrmManagerRegistryDefintion(Container $container): callable
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
480
    {
481 5
        return function ($container) {
482 1
            return new DoctrineOrmManagerRegistry($container);
483 5
        };
484
    }
485
}
486