Passed
Push — master ( a25875...d379e9 )
by Dominik
03:08
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\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>
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
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 View Code Duplication
    private function getCache(Container $container, array $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...
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 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...
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 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...
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