Passed
Push — master ( 5778d3...f5b0ef )
by Dominik
02:17
created

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