Passed
Push — master ( 580240...aaa5f4 )
by Dominik
02:17
created

DoctrineOrmServiceProvider::getOrmCacheFactoryRedisDefinition()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4.0119

Importance

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