Passed
Push — master ( 8394f7...4e48bc )
by Dominik
02:46 queued 23s
created

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