Test Failed
Push — master ( 881a81...43950e )
by Dominik
03:29
created

getOrmMappingDriverFactoryClassMap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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