Completed
Push — master ( dcec3d...a10d87 )
by Dominik
05:13
created

getOrmEmsConfigServiceProvider()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 62
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 36
c 1
b 0
f 0
dl 0
loc 62
ccs 35
cts 35
cp 1
rs 9.344
cc 2
nc 1
nop 1
crap 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\EventManager;
11
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
12
use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver;
13
use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver;
14
use Doctrine\DBAL\Connection;
15
use Doctrine\ORM\Cache\CacheConfiguration;
16
use Doctrine\ORM\Cache\DefaultCacheFactory;
17
use Doctrine\ORM\Cache\RegionsConfiguration;
18
use Doctrine\ORM\Configuration;
19
use Doctrine\ORM\EntityManager;
20
use Doctrine\ORM\EntityRepository;
21
use Doctrine\ORM\Mapping\ClassMetadataFactory;
22
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
23
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
24
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
25
use Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver;
26
use Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver;
27
use Doctrine\ORM\Mapping\Driver\XmlDriver;
28
use Doctrine\ORM\Mapping\Driver\YamlDriver;
29
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
30
use Pimple\Container;
31
use Pimple\ServiceProviderInterface;
32
33
/**
34
 * This provider is heavily inspired by
35
 * https://github.com/dflydev/dflydev-doctrine-orm-service-provider/blob/master/src/Dflydev/Provider/DoctrineOrm/DoctrineOrmServiceProvider.php.
36
 */
37
final class DoctrineOrmServiceProvider implements ServiceProviderInterface
38
{
39 3
    public function register(Container $container): void
40
    {
41 3
        $container['doctrine.orm.em'] = $this->getOrmEmDefinition($container);
42 3
        $container['doctrine.orm.em.config'] = $this->getOrmEmConfigDefinition($container);
43 3
        $container['doctrine.orm.em.default_options'] = $this->getOrmEmDefaultOptions();
44 3
        $container['doctrine.orm.em.factory'] = $this->getOrmEmFactory($container);
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();
49 3
        $container['doctrine.orm.manager_registry'] = $this->getOrmManagerRegistryDefintion($container);
50 3
        $container['doctrine.orm.mapping_driver.factory.annotation'] =
51 3
            $this->getOrmMappingDriverFactoryAnnotation($container);
52 3
        $container['doctrine.orm.mapping_driver.factory.class_map'] =
53 3
            $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'] =
56 3
            $this->getOrmMappingDriverFactorySimpleXml($container);
57 3
        $container['doctrine.orm.mapping_driver.factory.simple_yaml'] =
58 3
            $this->getOrmMappingDriverFactorySimpleYaml($container);
59 3
        $container['doctrine.orm.mapping_driver.factory.static_php'] =
60 3
            $this->getOrmMappingDriverFactoryStaticPhp($container);
61 3
        $container['doctrine.orm.mapping_driver.factory.xml'] = $this->getOrmMappingDriverFactoryXml($container);
62 3
        $container['doctrine.orm.mapping_driver.factory.yaml'] = $this->getOrmMappingDriverFactoryYaml($container);
63 3
        $container['doctrine.orm.mapping_driver_chain'] = $this->getOrmMappingDriverChainDefinition($container);
64 3
        $container['doctrine.orm.repository.factory.default'] = $this->getOrmRepositoryFactoryDefinition();
65 3
        $container['doctrine.orm.strategy.naming.default'] = $this->getOrmNamingStrategyDefinition();
66 3
        $container['doctrine.orm.strategy.quote.default'] = $this->getOrmQuoteStrategyDefinition();
67 3
    }
68
69 3
    private function getOrmEmDefinition(Container $container): callable
70
    {
71
        return static 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 3
    private function getOrmEmConfigDefinition(Container $container): callable
79
    {
80
        return static function () use ($container) {
81 3
            $configs = $container['doctrine.orm.ems.config'];
82
83 3
            return $configs[$container['doctrine.orm.ems.default']];
84 3
        };
85
    }
86
87
    /**
88
     * @return array<string, array|string|float|int|bool>
89
     */
90 3
    private function getOrmEmDefaultOptions(): array
91
    {
92
        return [
93 3
            'cache.hydration' => ['type' => 'array'],
94
            'cache.metadata' => ['type' => 'array'],
95
            'cache.query' => ['type' => 'array'],
96
            'class_metadata.factory.name' => ClassMetadataFactory::class,
97 3
            'connection' => 'default',
98
            'custom.functions.datetime' => [],
99
            'custom.functions.numeric' => [],
100
            'custom.functions.string' => [],
101
            'custom.hydration_modes' => [],
102 3
            'entity.listener_resolver' => 'default',
103
            'mappings' => [],
104
            'proxies.auto_generate' => true,
105 3
            'proxies.dir' => sys_get_temp_dir().'/doctrine/orm/proxies',
106 3
            'proxies.namespace' => 'DoctrineProxy',
107
            'query_hints' => [],
108
            'repository.default.class' => EntityRepository::class,
109 3
            'repository.factory' => 'default',
110
            'second_level_cache' => ['type' => 'array'],
111
            'second_level_cache.enabled' => false,
112 3
            'strategy.naming' => 'default',
113 3
            'strategy.quote' => 'default',
114
        ];
115
    }
116
117 3
    private function getOrmEmFactory(Container $container): callable
118
    {
119 3
        return $container->protect(
120
            static function (Connection $connection, Configuration $config, EventManager $eventManager) {
121 3
                return EntityManager::create($connection, $config, $eventManager);
122 3
            }
123
        );
124
    }
125
126 3
    private function getOrmEmsDefinition(Container $container): callable
127
    {
128
        return static function () use ($container) {
129 3
            $container['doctrine.orm.ems.options.initializer']();
130
131 3
            $ems = new Container();
132 3
            foreach ($container['doctrine.orm.ems.options'] as $name => $options) {
133 3
                if ($container['doctrine.orm.ems.default'] === $name) {
134 3
                    $config = $container['doctrine.orm.em.config'];
135
                } else {
136 1
                    $config = $container['doctrine.orm.ems.config'][$name];
137
                }
138
139
                $ems[$name] = static function () use ($container, $options, $config) {
140 3
                    return $container['doctrine.orm.em.factory'](
141 3
                        $container['doctrine.dbal.dbs'][$options['connection']],
142 3
                        $config,
143 3
                        $container['doctrine.dbal.dbs.event_manager'][$options['connection']]
144
                    );
145 3
                };
146
            }
147
148 3
            return $ems;
149 3
        };
150
    }
151
152 3
    private function getOrmEmsConfigServiceProvider(Container $container): callable
153
    {
154
        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 3
    private function getCache(Container $container, array $cacheDefinition): Cache
218
    {
219 3
        $cacheType = $cacheDefinition['type'];
220 3
        $cacheOptions = $cacheDefinition['options'] ?? [];
221
222 3
        $cacheFactory = $container[sprintf('doctrine.dbal.db.cache_factory.%s', $cacheType)];
223
224 3
        return $cacheFactory($cacheOptions);
225
    }
226
227 3
    private function assignSecondLevelCache(Container $container, Configuration $config, array $options): void
228
    {
229 3
        if (!$options['second_level_cache.enabled']) {
230 2
            $config->setSecondLevelCacheEnabled(false);
231
232 2
            return;
233
        }
234
235 1
        $regionsCacheConfiguration = new RegionsConfiguration();
236 1
        $factory = new DefaultCacheFactory(
237 1
            $regionsCacheConfiguration,
238 1
            $this->getCache($container, $options['second_level_cache'])
239
        );
240
241 1
        $cacheConfiguration = new CacheConfiguration();
242 1
        $cacheConfiguration->setCacheFactory($factory);
243 1
        $cacheConfiguration->setRegionsConfiguration($regionsCacheConfiguration);
244
245 1
        $config->setSecondLevelCacheEnabled(true);
246 1
        $config->setSecondLevelCacheConfiguration($cacheConfiguration);
247 1
    }
248
249 3
    private function getOrmEmsOptionsInitializerDefinition(Container $container): callable
250
    {
251
        return $container->protect(static function () use ($container): void {
252 3
            static $initialized = false;
253
254 3
            if ($initialized) {
255 3
                return;
256
            }
257
258 3
            $initialized = true;
259
260 3
            if (!isset($container['doctrine.orm.ems.options'])) {
261 2
                $container['doctrine.orm.ems.options'] = [
262 2
                    'default' => $container['doctrine.orm.em.options'] ?? [],
263
                ];
264
            }
265
266 3
            $tmp = $container['doctrine.orm.ems.options'];
267 3
            foreach ($tmp as $name => &$options) {
268 3
                $options = array_replace($container['doctrine.orm.em.default_options'], $options);
269
270 3
                if (!isset($container['doctrine.orm.ems.default'])) {
271 3
                    $container['doctrine.orm.ems.default'] = $name;
272
                }
273
            }
274
275 3
            $container['doctrine.orm.ems.options'] = $tmp;
276 3
        });
277
    }
278
279 3
    private function getOrmEntityListenerResolverDefinition(): callable
280
    {
281
        return static function () {
282 2
            return new DefaultEntityListenerResolver();
283 3
        };
284
    }
285
286 3
    private function getOrmManagerRegistryDefintion(Container $container): callable
287
    {
288
        return static function () use ($container) {
289 1
            return new DoctrineOrmManagerRegistry($container);
290 3
        };
291
    }
292
293 3
    private function getOrmMappingDriverFactoryAnnotation(Container $container): callable
294
    {
295
        return $container->protect(static function (array $mapping, Configuration $config) {
296 2
            return $config->newDefaultAnnotationDriver((array) $mapping['path'], false);
297 3
        });
298
    }
299
300 3
    private function getOrmMappingDriverFactoryClassMap(Container $container): callable
301
    {
302
        return $container->protect(static function (array $mapping) {
303 1
            return new ClassMapDriver($mapping['map']);
304 3
        });
305
    }
306
307 3
    private function getOrmMappingDriverFactoryPhp(Container $container): callable
308
    {
309
        return $container->protect(static function (array $mapping) {
310 1
            return new PHPDriver($mapping['path']);
311 3
        });
312
    }
313
314 3
    private function getOrmMappingDriverFactorySimpleYaml(Container $container): callable
315
    {
316
        return $container->protect(static function (array $mapping) {
317 1
            return new SimplifiedYamlDriver(
318 1
                [$mapping['path'] => $mapping['namespace']],
319 1
                $mapping['extension'] ?? SimplifiedYamlDriver::DEFAULT_FILE_EXTENSION
320
            );
321 3
        });
322
    }
323
324 3
    private function getOrmMappingDriverFactorySimpleXml(Container $container): callable
325
    {
326
        return $container->protect(static function (array $mapping) {
327 1
            return new SimplifiedXmlDriver(
328 1
                [$mapping['path'] => $mapping['namespace']],
329 1
                $mapping['extension'] ?? SimplifiedXmlDriver::DEFAULT_FILE_EXTENSION
330
            );
331 3
        });
332
    }
333
334 3
    private function getOrmMappingDriverFactoryStaticPhp(Container $container): callable
335
    {
336
        return $container->protect(static function (array $mapping) {
337 1
            return new StaticPHPDriver($mapping['path']);
338 3
        });
339
    }
340
341 3
    private function getOrmMappingDriverFactoryYaml(Container $container): callable
342
    {
343
        return $container->protect(static function (array $mapping) {
344 1
            return new YamlDriver($mapping['path'], $mapping['extension'] ?? YamlDriver::DEFAULT_FILE_EXTENSION);
345 3
        });
346
    }
347
348 3
    private function getOrmMappingDriverFactoryXml(Container $container): callable
349
    {
350
        return $container->protect(static function (array $mapping) {
351 1
            return new XmlDriver($mapping['path'], $mapping['extension'] ?? XmlDriver::DEFAULT_FILE_EXTENSION);
352 3
        });
353
    }
354
355 3
    private function getOrmMappingDriverChainDefinition(Container $container): callable
356
    {
357
        return $container->protect(static function (Configuration $config, array $mappings) use ($container) {
358 3
            $chain = new MappingDriverChain();
359 3
            foreach ($mappings as $mapping) {
360 2
                if (isset($mapping['alias'])) {
361 1
                    $config->addEntityNamespace($mapping['alias'], $mapping['namespace']);
362
                }
363
364 2
                $factoryKey = sprintf('doctrine.orm.mapping_driver.factory.%s', $mapping['type']);
365
366 2
                $chain->addDriver($container[$factoryKey]($mapping, $config), $mapping['namespace']);
367
            }
368
369 3
            return $chain;
370 3
        });
371
    }
372
373 3
    private function getOrmRepositoryFactoryDefinition(): callable
374
    {
375
        return static function () {
376 2
            return new DefaultRepositoryFactory();
377 3
        };
378
    }
379
380 3
    private function getOrmNamingStrategyDefinition(): callable
381
    {
382
        return static function () {
383 2
            return new DefaultNamingStrategy();
384 3
        };
385
    }
386
387 3
    private function getOrmQuoteStrategyDefinition(): callable
388
    {
389
        return static function () {
390 2
            return new DefaultQuoteStrategy();
391 3
        };
392
    }
393
}
394