Test Failed
Push — master ( b5ac9d...1680f3 )
by Dominik
03:46 queued 11s
created

getOrmEntityListenerResolverDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\DoctrineDbServiceProvider\ServiceFactory;
6
7
use Chubbyphp\Container\Container;
8
use Chubbyphp\Container\ContainerInterface;
9
use Chubbyphp\DoctrineDbServiceProvider\Driver\ClassMapDriver;
10
use Chubbyphp\DoctrineDbServiceProvider\Registry\Psr\DoctrineOrmManagerRegistry;
11
use Doctrine\Common\Cache\Cache;
12
use Doctrine\Common\EventManager;
13
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
14
use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver;
15
use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver;
16
use Doctrine\DBAL\Connection;
17
use Doctrine\ORM\Cache\CacheConfiguration;
18
use Doctrine\ORM\Cache\DefaultCacheFactory;
19
use Doctrine\ORM\Cache\RegionsConfiguration;
20
use Doctrine\ORM\Configuration;
21
use Doctrine\ORM\EntityManager;
22
use Doctrine\ORM\EntityRepository;
23
use Doctrine\ORM\Mapping\ClassMetadataFactory;
24
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
25
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
26
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
27
use Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver;
28
use Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver;
29
use Doctrine\ORM\Mapping\Driver\XmlDriver;
30
use Doctrine\ORM\Mapping\Driver\YamlDriver;
31
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
32
33
final class DoctrineOrmServiceFactory
34
{
35
    public function __invoke(): array
36
    {
37
        return [
38
            'doctrine.orm.em' => $this->getOrmEmDefinition(),
39
            'doctrine.orm.em.config' => $this->getOrmEmConfigDefinition(),
40
            'doctrine.orm.em.default_options' => $this->getOrmEmDefaultOptions(),
41
            'doctrine.orm.em.factory' => $this->getOrmEmFactory(),
42
            'doctrine.orm.ems' => $this->getOrmEmsDefinition(),
43
            'doctrine.orm.ems.config' => $this->getOrmEmsConfigDefinition(),
44
            'doctrine.orm.ems.name' => $this->getOrmEmsNameDefinition(),
45
            'doctrine.orm.ems.options.initializer' => $this->getOrmEmsOptionsInitializerDefinition(),
46
            'doctrine.orm.entity.listener_resolver.default' => $this->getOrmEntityListenerResolverDefinition(),
47
            'doctrine.orm.manager_registry' => $this->getOrmManagerRegistryDefintion(),
48
            'doctrine.orm.mapping_driver.factory.annotation' => $this->getOrmMappingDriverFactoryAnnotation(),
49
            'doctrine.orm.mapping_driver.factory.class_map' => $this->getOrmMappingDriverFactoryClassMap(),
50
            'doctrine.orm.mapping_driver.factory.php' => $this->getOrmMappingDriverFactoryPhp(),
51
            'doctrine.orm.mapping_driver.factory.simple_xml' => $this->getOrmMappingDriverFactorySimpleXml(),
52
            'doctrine.orm.mapping_driver.factory.simple_yaml' => $this->getOrmMappingDriverFactorySimpleYaml(),
53
            'doctrine.orm.mapping_driver.factory.static_php' => $this->getOrmMappingDriverFactoryStaticPhp(),
54
            'doctrine.orm.mapping_driver.factory.xml' => $this->getOrmMappingDriverFactoryXml(),
55
            'doctrine.orm.mapping_driver.factory.yaml' => $this->getOrmMappingDriverFactoryYaml(),
56
            'doctrine.orm.mapping_driver_chain' => $this->getOrmMappingDriverChainDefinition(),
57
            'doctrine.orm.repository.factory.default' => $this->getOrmRepositoryFactoryDefinition(),
58
            'doctrine.orm.strategy.naming.default' => $this->getOrmNamingStrategyDefinition(),
59
            'doctrine.orm.strategy.quote.default' => $this->getOrmQuoteStrategyDefinition(),
60
        ];
61
    }
62
63
    private function getOrmEmDefinition(): \Closure
64
    {
65
        return static function (ContainerInterface $container) {
66
            /** @var ContainerInterface $ems */
67
            $ems = $container->get('doctrine.orm.ems');
68
69
            return $ems->get($container->get('doctrine.orm.ems.default'));
70
        };
71
    }
72
73
    private function getOrmEmConfigDefinition(): \Closure
74
    {
75
        return static function (ContainerInterface $container) {
76
            /** @var ContainerInterface $configs */
77
            $configs = $container->get('doctrine.orm.ems.config');
78
79
            return $configs->get($container->get('doctrine.orm.ems.default'));
80
        };
81
    }
82
83
    private function getOrmEmDefaultOptions(): \Closure
84
    {
85
        return static function () {
86
            return [
87
                'cache.hydration' => ['type' => 'array'],
88
                'cache.metadata' => ['type' => 'array'],
89
                'cache.query' => ['type' => 'array'],
90
                'class_metadata.factory.name' => ClassMetadataFactory::class,
91
                'connection' => 'default',
92
                'custom.functions.datetime' => [],
93
                'custom.functions.numeric' => [],
94
                'custom.functions.string' => [],
95
                'custom.hydration_modes' => [],
96
                'entity.listener_resolver' => 'default',
97
                'mappings' => [],
98
                'proxies.auto_generate' => true,
99
                'proxies.dir' => sys_get_temp_dir().'/doctrine/orm/proxies',
100
                'proxies.namespace' => 'DoctrineProxy',
101
                'query_hints' => [],
102
                'repository.default.class' => EntityRepository::class,
103
                'repository.factory' => 'default',
104
                'second_level_cache' => ['type' => 'array'],
105
                'second_level_cache.enabled' => false,
106
                'strategy.naming' => 'default',
107
                'strategy.quote' => 'default',
108
            ];
109
        };
110
    }
111
112
    private function getOrmEmFactory(): \Closure
113
    {
114
        return static function () {
115
            return static function (Connection $connection, Configuration $config, EventManager $eventManager) {
116
                return EntityManager::create($connection, $config, $eventManager);
117
            };
118
        };
119
    }
120
121
    private function getOrmEmsDefinition(): \Closure
122
    {
123
        return static function (ContainerInterface $container) {
124
            $container->get('doctrine.orm.ems.options.initializer')();
125
126
            $ems = new Container();
127
            foreach ($container->get('doctrine.orm.ems.options') as $name => $options) {
128
                if ($container->get('doctrine.orm.ems.default') === $name) {
129
                    $config = $container->get('doctrine.orm.em.config');
130
                } else {
131
                    $config = $container->get('doctrine.orm.ems.config')->get($name);
132
                }
133
134
                $ems->factory($name, static function () use ($container, $options, $config) {
135
                    return $container->get('doctrine.orm.em.factory')(
136
                        $container->get('doctrine.dbal.dbs')->get($options['connection']),
137
                        $config,
138
                        $container->get('doctrine.dbal.dbs.event_manager')->get($options['connection'])
139
                    );
140
                });
141
            }
142
143
            return $ems;
144
        };
145
    }
146
147
    private function getOrmEmsConfigDefinition(): \Closure
148
    {
149
        return function (ContainerInterface $container) {
150
            $container->get('doctrine.orm.ems.options.initializer')();
151
152
            $configs = new Container();
153
            foreach ($container->get('doctrine.orm.ems.options') as $name => $options) {
154
                $configs->factory($name, function () use ($container, $options) {
155
                    $connectionName = $options['connection'];
156
157
                    $config = new Configuration();
158
159
                    $config->setSQLLogger(
160
                        $container->get('doctrine.dbal.dbs.config')->get($connectionName)->getSQLLogger()
161
                    );
162
163
                    $config->setQueryCacheImpl($this->getCache($container, $options['cache.query']));
164
                    $config->setHydrationCacheImpl($this->getCache($container, $options['cache.hydration']));
165
                    $config->setMetadataCacheImpl($this->getCache($container, $options['cache.metadata']));
166
167
                    $config->setResultCacheImpl(
168
                        $container->get('doctrine.dbal.dbs.config')->get($connectionName)->getResultCacheImpl()
169
                    );
170
171
                    $config->setClassMetadataFactoryName($options['class_metadata.factory.name']);
172
173
                    $config->setCustomDatetimeFunctions($options['custom.functions.datetime']);
174
                    $config->setCustomHydrationModes($options['custom.hydration_modes']);
175
                    $config->setCustomNumericFunctions($options['custom.functions.numeric']);
176
                    $config->setCustomStringFunctions($options['custom.functions.string']);
177
178
                    $config->setEntityListenerResolver(
179
                        $container->get(
180
                            sprintf('doctrine.orm.entity.listener_resolver.%s', $options['entity.listener_resolver'])
181
                        )
182
                    );
183
184
                    $config->setMetadataDriverImpl(
185
                        $container->get('doctrine.orm.mapping_driver_chain')($config, $options['mappings'])
186
                    );
187
188
                    $config->setAutoGenerateProxyClasses($options['proxies.auto_generate']);
189
                    $config->setProxyDir($options['proxies.dir']);
190
                    $config->setProxyNamespace($options['proxies.namespace']);
191
192
                    $config->setDefaultQueryHints($options['query_hints']);
193
194
                    $config->setRepositoryFactory(
195
                        $container->get(sprintf('doctrine.orm.repository.factory.%s', $options['repository.factory']))
196
                    );
197
                    $config->setDefaultRepositoryClassName($options['repository.default.class']);
198
199
                    $this->assignSecondLevelCache($container, $config, $options);
200
201
                    $config->setNamingStrategy(
202
                        $container->get(sprintf('doctrine.orm.strategy.naming.%s', $options['strategy.naming']))
203
                    );
204
                    $config->setQuoteStrategy(
205
                        $container->get(sprintf('doctrine.orm.strategy.quote.%s', $options['strategy.quote']))
206
                    );
207
208
                    return $config;
209
                });
210
            }
211
212
            return $configs;
213
        };
214
    }
215
216
    private function getCache(ContainerInterface $container, array $cacheDefinition): Cache
217
    {
218
        $cacheType = $cacheDefinition['type'];
219
        $cacheOptions = $cacheDefinition['options'] ?? [];
220
221
        $cacheFactory = $container->get(sprintf('doctrine.dbal.db.cache_factory.%s', $cacheType));
222
223
        return $cacheFactory($cacheOptions);
224
    }
225
226
    private function assignSecondLevelCache(ContainerInterface $container, Configuration $config, array $options): void
227
    {
228
        if (!$options['second_level_cache.enabled']) {
229
            $config->setSecondLevelCacheEnabled(false);
230
231
            return;
232
        }
233
234
        $regionsCacheConfiguration = new RegionsConfiguration();
235
        $factory = new DefaultCacheFactory(
236
            $regionsCacheConfiguration,
237
            $this->getCache($container, $options['second_level_cache'])
238
        );
239
240
        $cacheConfiguration = new CacheConfiguration();
241
        $cacheConfiguration->setCacheFactory($factory);
242
        $cacheConfiguration->setRegionsConfiguration($regionsCacheConfiguration);
243
244
        $config->setSecondLevelCacheEnabled(true);
245
        $config->setSecondLevelCacheConfiguration($cacheConfiguration);
246
    }
247
248
    private function getOrmEmsNameDefinition(): \Closure
249
    {
250
        return static function (ContainerInterface $container) {
251
            $container->get('doctrine.orm.ems.options.initializer')();
252
253
            return array_keys($container->get('doctrine.orm.ems.options'));
254
        };
255
    }
256
257
    private function getOrmEmsOptionsInitializerDefinition(): \Closure
258
    {
259
        return static function (ContainerInterface $container) {
260
            return static function () use ($container): void {
261
                static $initialized = false;
262
263
                if ($initialized) {
264
                    return;
265
                }
266
267
                $initialized = true;
268
269
                if (!$container->has('doctrine.orm.ems.options')) {
270
                    $container->factory('doctrine.orm.ems.options', static function (ContainerInterface $container) {
271
                        return [
272
                            'default' => $container->has('doctrine.orm.em.options')
273
                                ? $container->get('doctrine.orm.em.options')
274
                                : [],
275
                        ];
276
                    });
277
                }
278
279
                $tmp = $container->get('doctrine.orm.ems.options');
280
                foreach ($tmp as $name => &$options) {
281
                    $options = array_replace($container->get('doctrine.orm.em.default_options'), $options);
282
283
                    if (!$container->has('doctrine.orm.ems.default')) {
284
                        $container->factory('doctrine.orm.ems.default', static function () use ($name) {
285
                            return $name;
286
                        });
287
                    }
288
                }
289
290
                $container->factory('doctrine.orm.ems.options', static function () use ($tmp) {
291
                    return $tmp;
292
                });
293
            };
294
        };
295
    }
296
297
    private function getOrmEntityListenerResolverDefinition(): \Closure
298
    {
299
        return static function () {
300
            return new DefaultEntityListenerResolver();
301
        };
302
    }
303
304
    private function getOrmManagerRegistryDefintion(): \Closure
305
    {
306
        return static function (ContainerInterface $container) {
307
            return new DoctrineOrmManagerRegistry($container);
308
        };
309
    }
310
311
    private function getOrmMappingDriverFactoryAnnotation(): \Closure
312
    {
313
        return static function () {
314
            return static function (array $mapping, Configuration $config) {
315
                return $config->newDefaultAnnotationDriver($mapping['path'], false);
316
            };
317
        };
318
    }
319
320
    private function getOrmMappingDriverFactoryClassMap(): \Closure
321
    {
322
        return static function () {
323
            return static function (array $mapping) {
324
                return new ClassMapDriver($mapping['map']);
325
            };
326
        };
327
    }
328
329
    private function getOrmMappingDriverFactoryPhp(): \Closure
330
    {
331
        return static function () {
332
            return static function (array $mapping) {
333
                return new PHPDriver($mapping['path']);
334
            };
335
        };
336
    }
337
338
    private function getOrmMappingDriverFactorySimpleYaml(): \Closure
339
    {
340
        return static function () {
341
            return static function (array $mapping) {
342
                return new SimplifiedYamlDriver(
343
                    [$mapping['path'] => $mapping['namespace']],
344
                    $mapping['extension'] ?? SimplifiedYamlDriver::DEFAULT_FILE_EXTENSION
345
                );
346
            };
347
        };
348
    }
349
350
    private function getOrmMappingDriverFactorySimpleXml(): \Closure
351
    {
352
        return static function () {
353
            return static function (array $mapping) {
354
                return new SimplifiedXmlDriver(
355
                    [$mapping['path'] => $mapping['namespace']],
356
                    $mapping['extension'] ?? SimplifiedXmlDriver::DEFAULT_FILE_EXTENSION
357
                );
358
            };
359
        };
360
    }
361
362
    private function getOrmMappingDriverFactoryStaticPhp(): \Closure
363
    {
364
        return static function () {
365
            return static function (array $mapping) {
366
                return new StaticPHPDriver($mapping['path']);
367
            };
368
        };
369
    }
370
371
    private function getOrmMappingDriverFactoryYaml(): \Closure
372
    {
373
        return static function () {
374
            return static function (array $mapping) {
375
                return new YamlDriver($mapping['path'], $mapping['extension'] ?? YamlDriver::DEFAULT_FILE_EXTENSION);
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\ORM\Mapping\Driver\YamlDriver has been deprecated: 2.7 This class is being removed from the ORM and won't have any replacement ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

375
                return /** @scrutinizer ignore-deprecated */ new YamlDriver($mapping['path'], $mapping['extension'] ?? YamlDriver::DEFAULT_FILE_EXTENSION);
Loading history...
376
            };
377
        };
378
    }
379
380
    private function getOrmMappingDriverFactoryXml(): \Closure
381
    {
382
        return static function () {
383
            return static function (array $mapping) {
384
                return new XmlDriver($mapping['path'], $mapping['extension'] ?? XmlDriver::DEFAULT_FILE_EXTENSION);
385
            };
386
        };
387
    }
388
389
    private function getOrmMappingDriverChainDefinition(): \Closure
390
    {
391
        return static function (ContainerInterface $container) {
392
            return static function (Configuration $config, array $mappings) use ($container) {
393
                $chain = new MappingDriverChain();
394
                foreach ($mappings as $mapping) {
395
                    if (isset($mapping['alias'])) {
396
                        $config->addEntityNamespace($mapping['alias'], $mapping['namespace']);
397
                    }
398
399
                    $factoryKey = sprintf('doctrine.orm.mapping_driver.factory.%s', $mapping['type']);
400
401
                    $chain->addDriver($container->get($factoryKey)($mapping, $config), $mapping['namespace']);
402
                }
403
404
                return $chain;
405
            };
406
        };
407
    }
408
409
    private function getOrmRepositoryFactoryDefinition(): \Closure
410
    {
411
        return static function () {
412
            return new DefaultRepositoryFactory();
413
        };
414
    }
415
416
    private function getOrmNamingStrategyDefinition(): \Closure
417
    {
418
        return static function () {
419
            return new DefaultNamingStrategy();
420
        };
421
    }
422
423
    private function getOrmQuoteStrategyDefinition(): \Closure
424
    {
425
        return static function () {
426
            return new DefaultQuoteStrategy();
427
        };
428
    }
429
}
430