Test Failed
Push — master ( 43950e...c3c926 )
by Dominik
01:51
created

DoctrineOrmServiceProvider   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 454
Duplicated Lines 5.95 %

Coupling/Cohesion

Components 1
Dependencies 19

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 19
dl 27
loc 454
ccs 177
cts 177
cp 1
rs 9.68
c 0
b 0
f 0

23 Methods

Rating   Name   Duplication   Size   Complexity  
A register() 0 23 1
A getOrmEmDefinition() 0 8 1
A getOrmEmConfigDefinition() 0 8 1
A getOrmEmDefaultOptions() 0 26 1
A getOrmEmsDefinition() 0 25 3
B getOrmEmsConfigServiceProvider() 0 64 2
A getCache() 9 9 1
A assignSecondLevelCache() 0 21 2
B getOrmEmsOptionsInitializerDefinition() 0 30 6
A getOrmEntityListenerResolverDefinition() 0 6 1
A getOrmManagerRegistryDefintion() 0 6 1
A getOrmMappingDriverFactoryAnnotation() 0 6 1
A getOrmMappingDriverFactoryClassMap() 0 6 1
A getOrmMappingDriverFactoryPhp() 0 6 1
A getOrmMappingDriverFactorySimpleYaml() 9 9 1
A getOrmMappingDriverFactorySimpleXml() 9 9 1
A getOrmMappingDriverFactoryStaticPhp() 0 6 1
A getOrmMappingDriverFactoryYaml() 0 6 1
A getOrmMappingDriverFactoryXml() 0 6 1
A getOrmMappingDriverChainDefinition() 0 17 3
A getOrmRepositoryFactoryDefinition() 0 6 1
A getOrmNamingStrategyDefinition() 0 6 1
A getOrmQuoteStrategyDefinition() 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
namespace Chubbyphp\DoctrineDbServiceProvider\ServiceProvider;
6
7
use Chubbyphp\DoctrineDbServiceProvider\Driver\ClassMapDriver;
8
use Chubbyphp\DoctrineDbServiceProvider\Registry\DoctrineOrmManagerRegistry;
9
use Doctrine\Common\Cache\Cache;
10
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
11
use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver;
12
use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver;
13
use Doctrine\ORM\Cache\CacheConfiguration;
14
use Doctrine\ORM\Cache\DefaultCacheFactory;
15
use Doctrine\ORM\Cache\RegionsConfiguration;
16
use Doctrine\ORM\Configuration;
17
use Doctrine\ORM\EntityManager;
18
use Doctrine\ORM\EntityRepository;
19
use Doctrine\ORM\Mapping\ClassMetadataFactory;
20
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
21
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
22
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
23
use Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver;
24
use Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver;
25
use Doctrine\ORM\Mapping\Driver\XmlDriver;
26
use Doctrine\ORM\Mapping\Driver\YamlDriver;
27
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
28
use Pimple\Container;
29
use Pimple\ServiceProviderInterface;
30
31
/**
32
 * This provider is heavily inspired by
33
 * https://github.com/dflydev/dflydev-doctrine-orm-service-provider/blob/master/src/Dflydev/Provider/DoctrineOrm/DoctrineOrmServiceProvider.php.
34
 */
35
final class DoctrineOrmServiceProvider implements ServiceProviderInterface
36
{
37
    /**
38
     * Register ORM service.
39
     *
40
     * @param Container $container
41
     */
42 3
    public function register(Container $container)
43
    {
44 3
        $container['doctrine.orm.em'] = $this->getOrmEmDefinition($container);
45 3
        $container['doctrine.orm.em.config'] = $this->getOrmEmConfigDefinition($container);
46 3
        $container['doctrine.orm.em.default_options'] = $this->getOrmEmDefaultOptions();
47 3
        $container['doctrine.orm.ems'] = $this->getOrmEmsDefinition($container);
48 3
        $container['doctrine.orm.ems.config'] = $this->getOrmEmsConfigServiceProvider($container);
49 3
        $container['doctrine.orm.ems.options.initializer'] = $this->getOrmEmsOptionsInitializerDefinition($container);
50 3
        $container['doctrine.orm.entity.listener_resolver.default'] = $this->getOrmEntityListenerResolverDefinition($container);
51 3
        $container['doctrine.orm.manager_registry'] = $this->getOrmManagerRegistryDefintion($container);
52 3
        $container['doctrine.orm.mapping_driver.factory.annotation'] = $this->getOrmMappingDriverFactoryAnnotation($container);
53 3
        $container['doctrine.orm.mapping_driver.factory.class_map'] = $this->getOrmMappingDriverFactoryClassMap($container);
54 3
        $container['doctrine.orm.mapping_driver.factory.php'] = $this->getOrmMappingDriverFactoryPhp($container);
55 3
        $container['doctrine.orm.mapping_driver.factory.simple_xml'] = $this->getOrmMappingDriverFactorySimpleXml($container);
56 3
        $container['doctrine.orm.mapping_driver.factory.simple_yaml'] = $this->getOrmMappingDriverFactorySimpleYaml($container);
57 3
        $container['doctrine.orm.mapping_driver.factory.static_php'] = $this->getOrmMappingDriverFactoryStaticPhp($container);
58 3
        $container['doctrine.orm.mapping_driver.factory.xml'] = $this->getOrmMappingDriverFactoryXml($container);
59 3
        $container['doctrine.orm.mapping_driver.factory.yaml'] = $this->getOrmMappingDriverFactoryYaml($container);
60 3
        $container['doctrine.orm.mapping_driver_chain'] = $this->getOrmMappingDriverChainDefinition($container);
61 3
        $container['doctrine.orm.repository.factory.default'] = $this->getOrmRepositoryFactoryDefinition($container);
62 3
        $container['doctrine.orm.strategy.naming.default'] = $this->getOrmNamingStrategyDefinition($container);
63 3
        $container['doctrine.orm.strategy.quote.default'] = $this->getOrmQuoteStrategyDefinition($container);
64 3
    }
65
66
    /**
67
     * @param Container $container
68
     *
69
     * @return callable
70
     */
71
    private function getOrmEmDefinition(Container $container): callable
72
    {
73 3
        return function () use ($container) {
74 2
            $ems = $container['doctrine.orm.ems'];
75
76 2
            return $ems[$container['doctrine.orm.ems.default']];
77 3
        };
78
    }
79
80
    /**
81
     * @param Container $container
82
     *
83
     * @return callable
84
     */
85
    private function getOrmEmConfigDefinition(Container $container): callable
86
    {
87 3
        return function () use ($container) {
88 3
            $configs = $container['doctrine.orm.ems.config'];
89
90 3
            return $configs[$container['doctrine.orm.ems.default']];
91 3
        };
92
    }
93
94
    /**
95
     * @return array
96
     */
97 3
    private function getOrmEmDefaultOptions(): array
98
    {
99
        return [
100 3
            'cache.hydration' => ['type' => 'array'],
101
            'cache.metadata' => ['type' => 'array'],
102
            'cache.query' => ['type' => 'array'],
103
            'class_metadata.factory.name' => ClassMetadataFactory::class,
104 3
            'connection' => 'default',
105
            'custom.functions.datetime' => [],
106
            'custom.functions.numeric' => [],
107
            'custom.functions.string' => [],
108
            'custom.hydration_modes' => [],
109 3
            'entity.listener_resolver' => 'default',
110
            'mappings' => [],
111
            'proxies.auto_generate' => true,
112 3
            'proxies.dir' => sys_get_temp_dir().'/doctrine/orm/proxies',
113 3
            'proxies.namespace' => 'DoctrineProxy',
114
            'query_hints' => [],
115
            'repository.default.class' => EntityRepository::class,
116 3
            'repository.factory' => 'default',
117
            'second_level_cache' => ['type' => 'array'],
118
            'second_level_cache.enabled' => false,
119 3
            'strategy.naming' => 'default',
120 3
            'strategy.quote' => 'default',
121
        ];
122
    }
123
124
    /**
125
     * @param Container $container
126
     *
127
     * @return callable
128
     */
129
    private function getOrmEmsDefinition(Container $container): callable
130
    {
131 3
        return function () use ($container) {
132 3
            $container['doctrine.orm.ems.options.initializer']();
133
134 3
            $ems = new Container();
135 3
            foreach ($container['doctrine.orm.ems.options'] as $name => $options) {
136 3
                if ($container['doctrine.orm.ems.default'] === $name) {
137 3
                    $config = $container['doctrine.orm.em.config'];
138
                } else {
139 1
                    $config = $container['doctrine.orm.ems.config'][$name];
140
                }
141
142 3
                $ems[$name] = function () use ($container, $options, $config) {
143 3
                    return EntityManager::create(
144 3
                        $container['doctrine.dbal.dbs'][$options['connection']],
145 3
                        $config,
146 3
                        $container['doctrine.dbal.dbs.event_manager'][$options['connection']]
147
                    );
148 3
                };
149
            }
150
151 3
            return $ems;
152 3
        };
153
    }
154
155
    /**
156
     * @param Container $container
157
     *
158
     * @return callable
159
     */
160
    private function getOrmEmsConfigServiceProvider(Container $container): callable
161
    {
162 3
        return function () use ($container) {
163 3
            $container['doctrine.orm.ems.options.initializer']();
164
165 3
            $configs = new Container();
166 3
            foreach ($container['doctrine.orm.ems.options'] as $name => $options) {
167 3
                $connectionName = $options['connection'];
168
169 3
                $config = new Configuration();
170
171 3
                $config->setSQLLogger($container['doctrine.dbal.dbs.config'][$connectionName]->getSQLLogger());
172
173 3
                $config->setQueryCacheImpl($this->getCache($container, $options['cache.query']));
174 3
                $config->setHydrationCacheImpl($this->getCache($container, $options['cache.hydration']));
175 3
                $config->setMetadataCacheImpl($this->getCache($container, $options['cache.metadata']));
176
177 3
                $config->setResultCacheImpl(
178 3
                    $container['doctrine.dbal.dbs.config'][$connectionName]->getResultCacheImpl()
179
                );
180
181 3
                $config->setClassMetadataFactoryName($options['class_metadata.factory.name']);
182
183 3
                $config->setCustomDatetimeFunctions($options['custom.functions.datetime']);
184 3
                $config->setCustomHydrationModes($options['custom.hydration_modes']);
185 3
                $config->setCustomNumericFunctions($options['custom.functions.numeric']);
186 3
                $config->setCustomStringFunctions($options['custom.functions.string']);
187
188 3
                $config->setEntityListenerResolver(
189
                    $container[
190 3
                        sprintf('doctrine.orm.entity.listener_resolver.%s', $options['entity.listener_resolver'])
191
                    ]
192
                );
193
194 3
                $config->setMetadataDriverImpl(
195 3
                    $container['doctrine.orm.mapping_driver_chain']($config, $options['mappings'])
196
                );
197
198 3
                $config->setAutoGenerateProxyClasses($options['proxies.auto_generate']);
199 3
                $config->setProxyDir($options['proxies.dir']);
200 3
                $config->setProxyNamespace($options['proxies.namespace']);
201
202 3
                $config->setDefaultQueryHints($options['query_hints']);
203
204 3
                $config->setRepositoryFactory(
205 3
                    $container[sprintf('doctrine.orm.repository.factory.%s', $options['repository.factory'])]
206
                );
207 3
                $config->setDefaultRepositoryClassName($options['repository.default.class']);
208
209 3
                $this->assignSecondLevelCache($container, $config, $options);
210
211 3
                $config->setNamingStrategy(
212 3
                    $container[sprintf('doctrine.orm.strategy.naming.%s', $options['strategy.naming'])]
213
                );
214 3
                $config->setQuoteStrategy(
215 3
                    $container[sprintf('doctrine.orm.strategy.quote.%s', $options['strategy.quote'])]
216
                );
217
218 3
                $configs[$name] = $config;
219
            }
220
221 3
            return $configs;
222 3
        };
223
    }
224
225
    /**
226
     * @param Container    $container
227
     * @param string|array $cacheDefinition
228
     *
229
     * @return Cache
230
     */
231 3 View Code Duplication
    private function getCache(Container $container, $cacheDefinition): Cache
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...
232
    {
233 3
        $cacheType = $cacheDefinition['type'];
234 3
        $cacheOptions = $cacheDefinition['options'] ?? [];
235
236 3
        $cacheFactory = $container[sprintf('doctrine.dbal.db.cache_factory.%s', $cacheType)];
237
238 3
        return $cacheFactory($cacheOptions);
239
    }
240
241
    /**
242
     * @param Container     $container
243
     * @param Configuration $config
244
     * @param array         $options
245
     */
246 3
    private function assignSecondLevelCache(Container $container, Configuration $config, array $options)
247
    {
248 3
        if (!$options['second_level_cache.enabled']) {
249 2
            $config->setSecondLevelCacheEnabled(false);
250
251 2
            return;
252
        }
253
254 1
        $regionsCacheConfiguration = new RegionsConfiguration();
255 1
        $factory = new DefaultCacheFactory(
256 1
            $regionsCacheConfiguration,
257 1
            $this->getCache($container, $options['second_level_cache'])
258
        );
259
260 1
        $cacheConfiguration = new CacheConfiguration();
261 1
        $cacheConfiguration->setCacheFactory($factory);
262 1
        $cacheConfiguration->setRegionsConfiguration($regionsCacheConfiguration);
263
264 1
        $config->setSecondLevelCacheEnabled(true);
265 1
        $config->setSecondLevelCacheConfiguration($cacheConfiguration);
266 1
    }
267
268
    /**
269
     * @param Container $container
270
     *
271
     * @return callable
272
     */
273
    private function getOrmEmsOptionsInitializerDefinition(Container $container): callable
274
    {
275 3
        return $container->protect(function () use ($container) {
276 3
            static $initialized = false;
277
278 3
            if ($initialized) {
279 3
                return;
280
            }
281
282 3
            $initialized = true;
283
284 3
            if (!isset($container['doctrine.orm.ems.options'])) {
285 2
                $container['doctrine.orm.ems.options'] = [
286 2
                    'default' => isset($container['doctrine.orm.em.options']) ?
287 1
                        $container['doctrine.orm.em.options'] : [],
288
                ];
289
            }
290
291 3
            $tmp = $container['doctrine.orm.ems.options'];
292 3
            foreach ($tmp as $name => &$options) {
293 3
                $options = array_replace($container['doctrine.orm.em.default_options'], $options);
294
295 3
                if (!isset($container['doctrine.orm.ems.default'])) {
296 3
                    $container['doctrine.orm.ems.default'] = $name;
297
                }
298
            }
299
300 3
            $container['doctrine.orm.ems.options'] = $tmp;
301 3
        });
302
    }
303
304
    /**
305
     * @param Container $container
306
     *
307
     * @return callable
308
     */
309
    private function getOrmEntityListenerResolverDefinition(Container $container): callable
310
    {
311 3
        return function () use ($container) {
312 2
            return new DefaultEntityListenerResolver();
313 3
        };
314
    }
315
316
    /**
317
     * @param Container $container
318
     *
319
     * @return callable
320
     */
321
    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...
322
    {
323 3
        return function ($container) {
324 1
            return new DoctrineOrmManagerRegistry($container);
325 3
        };
326
    }
327
328
    /**
329
     * @param Container $container
330
     *
331
     * @return callable
332
     */
333
    private function getOrmMappingDriverFactoryAnnotation(Container $container): callable
334
    {
335 3
        return $container->protect(function (array $mapping, Configuration $config) {
336 2
            return $config->newDefaultAnnotationDriver((array) $mapping['path'], false);
337 3
        });
338
    }
339
340
    /**
341
     * @param Container $container
342
     *
343
     * @return callable
344
     */
345
    private function getOrmMappingDriverFactoryClassMap(Container $container): callable
346
    {
347 3
        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...
348 1
            return new ClassMapDriver($mapping['map']);
349 3
        });
350
    }
351
352
    /**
353
     * @param Container $container
354
     *
355
     * @return callable
356
     */
357
    private function getOrmMappingDriverFactoryPhp(Container $container): callable
358
    {
359 3
        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...
360 1
            return new PHPDriver($mapping['path']);
361 3
        });
362
    }
363
364
    /**
365
     * @param Container $container
366
     *
367
     * @return callable
368
     */
369 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...
370
    {
371 3
        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...
372 1
            return new SimplifiedYamlDriver(
373 1
                [$mapping['path'] => $mapping['namespace']],
374 1
                $mapping['extension'] ?? SimplifiedYamlDriver::DEFAULT_FILE_EXTENSION
375
            );
376 3
        });
377
    }
378
379
    /**
380
     * @param Container $container
381
     *
382
     * @return callable
383
     */
384 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...
385
    {
386 3
        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...
387 1
            return new SimplifiedXmlDriver(
388 1
                [$mapping['path'] => $mapping['namespace']],
389 1
                $mapping['extension'] ?? SimplifiedXmlDriver::DEFAULT_FILE_EXTENSION
390
            );
391 3
        });
392
    }
393
394
    /**
395
     * @param Container $container
396
     *
397
     * @return callable
398
     */
399
    private function getOrmMappingDriverFactoryStaticPhp(Container $container): callable
400
    {
401 3
        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...
402 1
            return new StaticPHPDriver($mapping['path']);
403 3
        });
404
    }
405
406
    /**
407
     * @param Container $container
408
     *
409
     * @return callable
410
     */
411
    private function getOrmMappingDriverFactoryYaml(Container $container): callable
412
    {
413 3
        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...
414 1
            return new YamlDriver($mapping['path'], $mapping['extension'] ?? YamlDriver::DEFAULT_FILE_EXTENSION);
415 3
        });
416
    }
417
418
    /**
419
     * @param Container $container
420
     *
421
     * @return callable
422
     */
423
    private function getOrmMappingDriverFactoryXml(Container $container): callable
424
    {
425 3
        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...
426 1
            return new XmlDriver($mapping['path'], $mapping['extension'] ?? XmlDriver::DEFAULT_FILE_EXTENSION);
427 3
        });
428
    }
429
430
    /**
431
     * @param Container $container
432
     *
433
     * @return callable
434
     */
435
    private function getOrmMappingDriverChainDefinition(Container $container): callable
436
    {
437 3
        return $container->protect(function (Configuration $config, array $mappings) use ($container) {
438 3
            $chain = new MappingDriverChain();
439 3
            foreach ($mappings as $mapping) {
440 2
                if (isset($mapping['alias'])) {
441 1
                    $config->addEntityNamespace($mapping['alias'], $mapping['namespace']);
442
                }
443
444 2
                $factoryKey = sprintf('doctrine.orm.mapping_driver.factory.%s', $mapping['type']);
445
446 2
                $chain->addDriver($container[$factoryKey]($mapping, $config), $mapping['namespace']);
447
            }
448
449 3
            return $chain;
450 3
        });
451
    }
452
453
    /**
454
     * @param Container $container
455
     *
456
     * @return callable
457
     */
458
    private function getOrmRepositoryFactoryDefinition(Container $container): callable
459
    {
460 3
        return function () use ($container) {
461 2
            return new DefaultRepositoryFactory();
462 3
        };
463
    }
464
465
    /**
466
     * @param Container $container
467
     *
468
     * @return callable
469
     */
470
    private function getOrmNamingStrategyDefinition(Container $container): callable
471
    {
472 3
        return function () use ($container) {
473 2
            return new DefaultNamingStrategy();
474 3
        };
475
    }
476
477
    /**
478
     * @param Container $container
479
     *
480
     * @return callable
481
     */
482
    private function getOrmQuoteStrategyDefinition(Container $container): callable
483
    {
484 3
        return function () use ($container) {
485 2
            return new DefaultQuoteStrategy();
486 3
        };
487
    }
488
}
489