Completed
Push — master ( 3cd474...762345 )
by Dominik
04:08
created

getOrmMappingDriverFactorySimpleYaml()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 9
Ratio 100 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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