Completed
Push — master ( e8736f...fa04ac )
by Dominik
04:15
created

getOrmNamingStrategyDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

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