Completed
Push — master ( 7f63d4...d30d0e )
by Julián
04:18
created

RelationalBuilder::getCacheDriver()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 4
nop 2
1
<?php
2
3
/*
4
 * doctrine-manager-builder (https://github.com/juliangut/doctrine-manager-builder).
5
 * Doctrine2 managers builder.
6
 *
7
 * @license BSD-3-Clause
8
 * @link https://github.com/juliangut/doctrine-manager-builder
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
namespace Jgut\Doctrine\ManagerBuilder;
13
14
use Doctrine\Common\Annotations\AnnotationReader;
15
use Doctrine\Common\Cache\CacheProvider;
16
use Doctrine\DBAL\Logging\SQLLogger;
17
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
18
use Doctrine\DBAL\Types\Type;
19
use Doctrine\ORM\Cache\CacheConfiguration;
20
use Doctrine\ORM\Configuration;
21
use Doctrine\ORM\EntityManager;
22
use Doctrine\ORM\EntityRepository;
23
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
24
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
25
use Doctrine\ORM\Mapping\Driver\XmlDriver;
26
use Doctrine\ORM\Mapping\Driver\YamlDriver;
27
use Doctrine\ORM\Mapping\NamingStrategy;
28
use Doctrine\ORM\Mapping\QuoteStrategy;
29
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
30
use Doctrine\ORM\Repository\RepositoryFactory;
31
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
32
use Doctrine\ORM\Version;
33
use Symfony\Component\Console\Command\Command;
34
use Symfony\Component\Console\Helper\HelperSet;
35
36
/**
37
 * Doctrine RDBMS Entity Manager builder.
38
 *
39
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
40
 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
41
 */
42
class RelationalBuilder extends AbstractManagerBuilder
43
{
44
    /**
45
     * Query cache driver.
46
     *
47
     * @var CacheProvider
48
     */
49
    protected $queryCacheDriver;
50
51
    /**
52
     * Result cache driver.
53
     *
54
     * @var CacheProvider
55
     */
56
    protected $resultCacheDriver;
57
58
    /**
59
     * Hydrator cache driver.
60
     *
61
     * @var CacheProvider
62
     */
63
    protected $hydratorCacheDriver;
64
65
    /**
66
     * Naming strategy.
67
     *
68
     * @var NamingStrategy
69
     */
70
    protected $namingStrategy;
71
72
    /**
73
     * Quote strategy.
74
     *
75
     * @var QuoteStrategy
76
     */
77
    protected $quoteStrategy;
78
79
    /**
80
     * Second level cache configuration.
81
     *
82
     * @var CacheConfiguration
83
     */
84
    protected $secondCacheConfig;
85
86
    /**
87
     * SQL logger.
88
     *
89
     * @var SQLLogger
90
     */
91
    protected $SQLLogger;
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    protected function getDefaultOptions()
97
    {
98
        return [
99
            'connection' => [], // Array or \Doctrine\DBAL\Connection
100
            'proxies_namespace' => 'DoctrineRDBMSORMProxy',
101
            'metadata_cache_namespace' => 'DoctrineRDBMSORMMetadataCache',
102
            'query_cache_namespace' => 'DoctrineRDBMSORMQueryCache',
103
            'result_cache_namespace' => 'DoctrineRDBMSORMResultCache',
104
            'hydrator_cache_namespace' => 'DoctrineRDBMSORMHydratorCache',
105
            'default_repository_class' => EntityRepository::class,
106
            'second_level_cache_enable' => false,
107
        ];
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    protected function wipe()
114
    {
115
        $this->manager = null;
116
        $this->mappingDriver = null;
117
        $this->metadataCacheDriver = null;
118
        $this->eventManager = null;
119
        $this->queryCacheDriver = null;
120
        $this->resultCacheDriver = null;
121
        $this->namingStrategy = null;
122
        $this->quoteStrategy = null;
123
        $this->SQLLogger = null;
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     *
129
     * @throws \Doctrine\DBAL\DBALException
130
     * @throws \Doctrine\ORM\ORMException
131
     * @throws \InvalidArgumentException
132
     * @throws \RuntimeException
133
     * @throws \UnexpectedValueException
134
     *
135
     * @return EntityManager
136
     */
137
    protected function buildManager()
138
    {
139
        $config = new Configuration();
140
141
        $this->setUpGeneralConfigurations($config);
142
        $this->setUpSpecificConfigurations($config);
143
144
        $eventManager = $this->getEventManager();
145
        if ($this->getEventSubscribers() !== null) {
146
            /* @var array $eventSubscribers */
147
            $eventSubscribers = $this->getEventSubscribers();
148
149
            foreach ($eventSubscribers as $eventSubscriber) {
150
                $eventManager->addEventSubscriber($eventSubscriber);
151
            }
152
        }
153
154
        $entityManager = EntityManager::create($this->getOption('connection'), $config, $eventManager);
155
156
        $customMappingTypes = $this->getCustomMappingTypes();
157
158
        $platform = $entityManager->getConnection()->getDatabasePlatform();
159
        foreach ($this->getCustomTypes() as $type => $class) {
160
            if (Type::hasType($type)) {
161
                Type::overrideType($type, $class);
162
            } else {
163
                Type::addType($type, $class);
164
            }
165
166
            $platform->registerDoctrineTypeMapping(
167
                $type,
168
                array_key_exists($type, $customMappingTypes) ? $customMappingTypes[$type] : $type
169
            );
170
        }
171
172
        return $entityManager;
173
    }
174
175
    /**
176
     * Set up general manager configurations.
177
     *
178
     * @param Configuration $config
179
     */
180
    protected function setUpGeneralConfigurations(Configuration $config)
181
    {
182
        $this->setupAnnotationMetadata();
183
        $config->setMetadataDriverImpl($this->getMetadataMappingDriver());
184
185
        $config->setProxyDir($this->getProxiesPath());
186
        $config->setProxyNamespace($this->getProxiesNamespace());
187
        $config->setAutoGenerateProxyClasses($this->getProxiesAutoGeneration());
188
189
        if ($this->getRepositoryFactory() !== null) {
190
            $config->setRepositoryFactory($this->getRepositoryFactory());
191
        }
192
193
        if ($this->getDefaultRepositoryClass() !== null) {
194
            $config->setDefaultRepositoryClassName($this->getDefaultRepositoryClass());
195
        }
196
197
        $config->setMetadataCacheImpl($this->getMetadataCacheDriver());
198
    }
199
200
    /**
201
     * Set up manager specific configurations.
202
     *
203
     * @param Configuration $config
204
     */
205
    protected function setUpSpecificConfigurations(Configuration $config)
206
    {
207
        $config->setQueryCacheImpl($this->getQueryCacheDriver());
208
        $config->setResultCacheImpl($this->getResultCacheDriver());
209
        $config->setHydrationCacheImpl($this->getHydratorCacheDriver());
210
211
        $config->setNamingStrategy($this->getNamingStrategy());
212
        $config->setQuoteStrategy($this->getQuoteStrategy());
213
214
        if ($this->getSecondLevelCacheConfiguration() !== null) {
215
            $config->setSecondLevelCacheEnabled(true);
216
            $config->setSecondLevelCacheConfiguration($this->getSecondLevelCacheConfiguration());
217
        }
218
219
        $config->setSQLLogger($this->getSQLLogger());
220
        $config->setCustomStringFunctions($this->getCustomStringFunctions());
221
        $config->setCustomNumericFunctions($this->getCustomNumericFunctions());
222
        $config->setCustomDatetimeFunctions($this->getCustomDateTimeFunctions());
223
224
        foreach ($this->getCustomFilters() as $name => $filterClass) {
225
            $config->addFilter($name, $filterClass);
226
        }
227
    }
228
229
    /**
230
     * {@inheritdoc}
231
     */
232
    protected function getAnnotationMappingDriver(array $paths)
233
    {
234
        return new AnnotationDriver(new AnnotationReader, $paths);
235
    }
236
237
    /**
238
     * {@inheritdoc}
239
     */
240
    protected function getXmlMappingDriver(array $paths, $extension = null)
241
    {
242
        $extension = $extension ?: XmlDriver::DEFAULT_FILE_EXTENSION;
243
244
        return new XmlDriver($paths, $extension);
245
    }
246
247
    /**
248
     * {@inheritdoc}
249
     */
250
    protected function getYamlMappingDriver(array $paths, $extension = null)
251
    {
252
        $extension = $extension ?: YamlDriver::DEFAULT_FILE_EXTENSION;
253
254
        return new YamlDriver($paths, $extension);
255
    }
256
257
    /**
258
     * {@inheritdoc}
259
     *
260
     * @throws \InvalidArgumentException
261
     *
262
     * @return RepositoryFactory|null
263
     */
264
    protected function getRepositoryFactory()
265
    {
266
        if (!array_key_exists('repository_factory', $this->options)) {
267
            return;
268
        }
269
270
        $repositoryFactory = $this->options['repository_factory'];
271
272
        if (!$repositoryFactory instanceof RepositoryFactory) {
273
            throw new \InvalidArgumentException(sprintf(
274
                'Invalid factory class "%s". It must be a Doctrine\ORM\Repository\RepositoryFactory.',
275
                get_class($repositoryFactory)
276
            ));
277
        }
278
279
        return $repositoryFactory;
280
    }
281
282
    /**
283
     * Retrieve query cache driver.
284
     *
285
     * @throws \InvalidArgumentException
286
     *
287
     * @return CacheProvider
288
     */
289
    public function getQueryCacheDriver()
290
    {
291
        if (!$this->queryCacheDriver instanceof CacheProvider) {
292
            $this->queryCacheDriver = $this->getCacheDriver(
293
                (string) $this->getOption('query_cache_namespace'),
294
                $this->getOption('query_cache_driver')
295
            );
296
        }
297
298
        return $this->queryCacheDriver;
299
    }
300
301
    /**
302
     * Set query cache driver.
303
     *
304
     * @param CacheProvider $queryCacheDriver
305
     */
306
    public function setQueryCacheDriver(CacheProvider $queryCacheDriver)
307
    {
308
        $this->queryCacheDriver = $queryCacheDriver;
309
    }
310
311
    /**
312
     * Retrieve result cache driver.
313
     *
314
     * @throws \InvalidArgumentException
315
     *
316
     * @return CacheProvider
317
     */
318
    public function getResultCacheDriver()
319
    {
320
        if (!$this->resultCacheDriver instanceof CacheProvider) {
321
            $this->resultCacheDriver = $this->getCacheDriver(
322
                (string) $this->getOption('result_cache_namespace'),
323
                $this->getOption('result_cache_driver')
324
            );
325
        }
326
327
        return $this->resultCacheDriver;
328
    }
329
330
    /**
331
     * Set result cache driver.
332
     *
333
     * @param CacheProvider $resultCacheDriver
334
     */
335
    public function setResultCacheDriver(CacheProvider $resultCacheDriver)
336
    {
337
        $this->resultCacheDriver = $resultCacheDriver;
338
    }
339
340
    /**
341
     * Retrieve hydrator cache driver.
342
     *
343
     * @throws \InvalidArgumentException
344
     *
345
     * @return CacheProvider
346
     */
347
    public function getHydratorCacheDriver()
348
    {
349
        if (!$this->hydratorCacheDriver instanceof CacheProvider) {
350
            $this->hydratorCacheDriver = $this->getCacheDriver(
351
                (string) $this->getOption('hydrator_cache_namespace'),
352
                $this->getOption('hydrator_cache_driver')
353
            );
354
        }
355
356
        return $this->hydratorCacheDriver;
357
    }
358
359
    /**
360
     * Set hydrator cache driver.
361
     *
362
     * @param CacheProvider $hydratorCacheDriver
363
     */
364
    public function setHydratorCacheDriver(CacheProvider $hydratorCacheDriver)
365
    {
366
        $this->hydratorCacheDriver = $hydratorCacheDriver;
367
    }
368
369
    /**
370
     * Get cache driver.
371
     *
372
     * @param string             $cacheNamespace
373
     * @param CacheProvider|null $cacheDriver
374
     *
375
     * @return CacheProvider
376
     */
377
    protected function getCacheDriver($cacheNamespace, CacheProvider $cacheDriver = null)
378
    {
379
        if (!$cacheDriver instanceof CacheProvider) {
380
            $cacheDriver = clone $this->getMetadataCacheDriver();
381
            $cacheDriver->setNamespace($cacheNamespace);
382
        }
383
384
        if ($cacheDriver->getNamespace() === '') {
385
            $cacheDriver->setNamespace($cacheNamespace);
386
        }
387
388
        return $cacheDriver;
389
    }
390
391
    /**
392
     * Retrieve naming strategy.
393
     *
394
     * @return NamingStrategy
395
     */
396
    protected function getNamingStrategy()
397
    {
398
        if (!$this->namingStrategy instanceof NamingStrategy) {
399
            $namingStrategy = $this->getOption('naming_strategy');
400
401
            if (!$namingStrategy instanceof NamingStrategy) {
402
                $namingStrategy = new UnderscoreNamingStrategy(CASE_LOWER);
403
            }
404
405
            $this->namingStrategy = $namingStrategy;
406
        }
407
408
        return $this->namingStrategy;
409
    }
410
411
    /**
412
     * Retrieve quote strategy.
413
     *
414
     * @throws \InvalidArgumentException
415
     *
416
     * @return QuoteStrategy
417
     */
418
    protected function getQuoteStrategy()
419
    {
420
        if (!$this->quoteStrategy instanceof QuoteStrategy) {
421
            $quoteStrategy = $this->getOption('quote_strategy');
422
423
            if (!$quoteStrategy instanceof QuoteStrategy) {
424
                $quoteStrategy = new DefaultQuoteStrategy;
425
            }
426
427
            $this->quoteStrategy = $quoteStrategy;
428
        }
429
430
        return $this->quoteStrategy;
431
    }
432
433
    /**
434
     * Retrieve second level cache configuration.
435
     *
436
     * @return CacheConfiguration|null
437
     */
438
    protected function getSecondLevelCacheConfiguration()
439
    {
440
        if (!$this->secondCacheConfig instanceof CacheConfiguration) {
441
            $secondCacheConfig = $this->getOption('second_level_cache_configuration');
442
443
            if ($secondCacheConfig instanceof CacheConfiguration) {
444
                $this->secondCacheConfig = $secondCacheConfig;
445
            }
446
        }
447
448
        return $this->secondCacheConfig;
449
    }
450
451
    /**
452
     * Retrieve SQL logger.
453
     *
454
     * @return SQLLogger|null
455
     */
456
    protected function getSQLLogger()
457
    {
458
        if (!$this->SQLLogger instanceof SQLLogger) {
459
            $sqlLogger = $this->getOption('sql_logger');
460
461
            if ($sqlLogger instanceof SQLLogger) {
462
                $this->SQLLogger = $sqlLogger;
463
            }
464
        }
465
466
        return $this->SQLLogger;
467
    }
468
469
    /**
470
     * Retrieve custom DQL string functions.
471
     *
472
     * @return array
473
     */
474
    protected function getCustomStringFunctions()
475
    {
476
        $functions = (array) $this->getOption('custom_string_functions');
477
478
        return array_filter(
479
            $functions,
480
            function ($name) {
481
                return is_string($name);
482
            },
483
            ARRAY_FILTER_USE_KEY
484
        );
485
    }
486
487
    /**
488
     * Retrieve custom DQL numeric functions.
489
     *
490
     * @return array
491
     */
492
    protected function getCustomNumericFunctions()
493
    {
494
        $functions = (array) $this->getOption('custom_numeric_functions');
495
496
        return array_filter(
497
            $functions,
498
            function ($name) {
499
                return is_string($name);
500
            },
501
            ARRAY_FILTER_USE_KEY
502
        );
503
    }
504
505
    /**
506
     * Retrieve custom DQL date time functions.
507
     *
508
     * @return array
509
     */
510
    protected function getCustomDateTimeFunctions()
511
    {
512
        $functions = (array) $this->getOption('custom_datetime_functions');
513
514
        return array_filter(
515
            $functions,
516
            function ($name) {
517
                return is_string($name);
518
            },
519
            ARRAY_FILTER_USE_KEY
520
        );
521
    }
522
523
    /**
524
     * Retrieve custom DBAL types.
525
     *
526
     * @return array
527
     */
528
    protected function getCustomTypes()
529
    {
530
        $types = (array) $this->getOption('custom_types');
531
532
        return array_filter(
533
            $types,
534
            function ($name) {
535
                return is_string($name);
536
            },
537
            ARRAY_FILTER_USE_KEY
538
        );
539
    }
540
541
    /**
542
     * Retrieve custom DBAL mapping types.
543
     *
544
     * @return array
545
     */
546
    protected function getCustomMappingTypes()
547
    {
548
        $mappingTypes = (array) $this->getOption('custom_mapping_types');
549
550
        return array_filter(
551
            $mappingTypes,
552
            function ($name) {
553
                return is_string($name);
554
            },
555
            ARRAY_FILTER_USE_KEY
556
        );
557
    }
558
559
    /**
560
     * Get custom registered filters.
561
     *
562
     * @return array
563
     */
564
    protected function getCustomFilters()
565
    {
566
        $filters = (array) $this->getOption('custom_filters');
567
568
        return array_filter(
569
            $filters,
570
            function ($name) {
571
                return is_string($name);
572
            },
573
            ARRAY_FILTER_USE_KEY
574
        );
575
    }
576
577
    /**
578
     * {@inheritdoc}
579
     *
580
     * @throws \Doctrine\DBAL\DBALException
581
     * @throws \Doctrine\ORM\ORMException
582
     * @throws \InvalidArgumentException
583
     * @throws \RuntimeException
584
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
585
     * @throws \Symfony\Component\Console\Exception\LogicException
586
     * @throws \UnexpectedValueException
587
     *
588
     * @return Command[]
589
     */
590
    public function getConsoleCommands()
591
    {
592
        $commands = [
593
            // DBAL
594
            new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
595
            new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
596
597
            // ORM
598
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
599
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
600
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
601
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
602
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
603
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
604
            new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
605
            new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
606
            new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
607
            new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
608
            new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
609
            new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
610
            new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
611
            new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
612
            new \Doctrine\ORM\Tools\Console\Command\InfoCommand(),
613
        ];
614
615
        if (Version::compare('2.5') <= 0) {
616
            $commands[] = new \Doctrine\ORM\Tools\Console\Command\MappingDescribeCommand();
617
        }
618
619
        $helperSet = $this->getConsoleHelperSet();
620
        $commandPrefix = (string) $this->getName();
621
622
        $commands = array_map(
623
            function (Command $command) use ($helperSet, $commandPrefix) {
624
                if ($commandPrefix !== '') {
625
                    $commandNames = array_map(
626
                        function ($commandName) use ($commandPrefix) {
627
                            return preg_replace('/^(dbal|orm):/', '$1:' . $commandPrefix . ':', $commandName);
628
                        },
629
                        array_merge([$command->getName()], $command->getAliases())
630
                    );
631
632
                    $command->setName(array_shift($commandNames));
633
                    $command->setAliases($commandNames);
634
                }
635
636
                $command->setHelperSet($helperSet);
637
638
                return $command;
639
            },
640
            $commands
641
        );
642
643
        return $commands;
644
    }
645
646
    /**
647
     * Get console helper set.
648
     *
649
     * @return \Symfony\Component\Console\Helper\HelperSet
650
     */
651
    protected function getConsoleHelperSet()
652
    {
653
        /* @var EntityManager $entityManager */
654
        $entityManager = $this->getManager();
655
656
        return new HelperSet([
657
            'db' => new ConnectionHelper($entityManager->getConnection()),
658
            'em' => new EntityManagerHelper($entityManager),
659
        ]);
660
    }
661
}
662