Completed
Push — master ( b97ce5...b81d5b )
by Julián
08:35
created

getSecondLevelCacheConfiguration()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 0
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
        $platform = $entityManager->getConnection()->getDatabasePlatform();
157
        foreach ($this->getCustomTypes() as $type => $class) {
158
            if (Type::hasType($type)) {
159
                Type::overrideType($type, $class);
160
            } else {
161
                Type::addType($type, $class);
162
            }
163
164
            $platform->registerDoctrineTypeMapping($type, $type);
165
        }
166
167
        return $entityManager;
168
    }
169
170
    /**
171
     * Set up general manager configurations.
172
     *
173
     * @param Configuration $config
174
     */
175
    protected function setUpGeneralConfigurations(Configuration $config)
176
    {
177
        $this->setupAnnotationMetadata();
178
        $config->setMetadataDriverImpl($this->getMetadataMappingDriver());
179
180
        $config->setProxyDir($this->getProxiesPath());
181
        $config->setProxyNamespace($this->getProxiesNamespace());
182
        $config->setAutoGenerateProxyClasses($this->getProxiesAutoGeneration());
183
184
        if ($this->getRepositoryFactory() !== null) {
185
            $config->setRepositoryFactory($this->getRepositoryFactory());
186
        }
187
188
        if ($this->getDefaultRepositoryClass() !== null) {
189
            $config->setDefaultRepositoryClassName($this->getDefaultRepositoryClass());
190
        }
191
192
        $config->setMetadataCacheImpl($this->getMetadataCacheDriver());
193
    }
194
195
    /**
196
     * Set up manager specific configurations.
197
     *
198
     * @param Configuration $config
199
     */
200
    protected function setUpSpecificConfigurations(Configuration $config)
201
    {
202
        $config->setQueryCacheImpl($this->getQueryCacheDriver());
203
        $config->setResultCacheImpl($this->getResultCacheDriver());
204
        $config->setHydrationCacheImpl($this->getHydratorCacheDriver());
205
206
        $config->setNamingStrategy($this->getNamingStrategy());
207
        $config->setQuoteStrategy($this->getQuoteStrategy());
208
209
        if ($this->getSecondLevelCacheConfiguration() !== null) {
210
            $config->setSecondLevelCacheEnabled(true);
211
            $config->setSecondLevelCacheConfiguration($this->getSecondLevelCacheConfiguration());
212
        }
213
214
        $config->setSQLLogger($this->getSQLLogger());
215
        $config->setCustomStringFunctions($this->getCustomStringFunctions());
216
        $config->setCustomNumericFunctions($this->getCustomNumericFunctions());
217
        $config->setCustomDatetimeFunctions($this->getCustomDateTimeFunctions());
218
219
        foreach ($this->getCustomFilters() as $name => $filterClass) {
220
            $config->addFilter($name, $filterClass);
221
        }
222
    }
223
224
    /**
225
     * {@inheritdoc}
226
     */
227
    protected function getAnnotationMappingDriver(array $paths)
228
    {
229
        return new AnnotationDriver(new AnnotationReader, $paths);
230
    }
231
232
    /**
233
     * {@inheritdoc}
234
     */
235
    protected function getXmlMappingDriver(array $paths, $extension = null)
236
    {
237
        $extension = $extension ?: XmlDriver::DEFAULT_FILE_EXTENSION;
238
239
        return new XmlDriver($paths, $extension);
240
    }
241
242
    /**
243
     * {@inheritdoc}
244
     */
245
    protected function getYamlMappingDriver(array $paths, $extension = null)
246
    {
247
        $extension = $extension ?: YamlDriver::DEFAULT_FILE_EXTENSION;
248
249
        return new YamlDriver($paths, $extension);
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     *
255
     * @throws \InvalidArgumentException
256
     *
257
     * @return RepositoryFactory|null
258
     */
259
    protected function getRepositoryFactory()
260
    {
261
        if (!array_key_exists('repository_factory', $this->options)) {
262
            return;
263
        }
264
265
        $repositoryFactory = $this->options['repository_factory'];
266
267
        if (!$repositoryFactory instanceof RepositoryFactory) {
268
            throw new \InvalidArgumentException(sprintf(
269
                'Invalid factory class "%s". It must be a Doctrine\ORM\Repository\RepositoryFactory.',
270
                get_class($repositoryFactory)
271
            ));
272
        }
273
274
        return $repositoryFactory;
275
    }
276
277
    /**
278
     * Retrieve query cache driver.
279
     *
280
     * @throws \InvalidArgumentException
281
     *
282
     * @return CacheProvider
283
     */
284
    public function getQueryCacheDriver()
285
    {
286
        if (!$this->queryCacheDriver instanceof CacheProvider) {
287
            $this->queryCacheDriver = $this->getCacheDriver(
288
                (string) $this->getOption('query_cache_namespace'),
289
                $this->getOption('query_cache_driver')
290
            );
291
        }
292
293
        return $this->queryCacheDriver;
294
    }
295
296
    /**
297
     * Set query cache driver.
298
     *
299
     * @param CacheProvider $queryCacheDriver
300
     */
301
    public function setQueryCacheDriver(CacheProvider $queryCacheDriver)
302
    {
303
        $this->queryCacheDriver = $queryCacheDriver;
304
    }
305
306
    /**
307
     * Retrieve result cache driver.
308
     *
309
     * @throws \InvalidArgumentException
310
     *
311
     * @return CacheProvider
312
     */
313
    public function getResultCacheDriver()
314
    {
315
        if (!$this->resultCacheDriver instanceof CacheProvider) {
316
            $this->resultCacheDriver = $this->getCacheDriver(
317
                (string) $this->getOption('result_cache_namespace'),
318
                $this->getOption('result_cache_driver')
319
            );
320
        }
321
322
        return $this->resultCacheDriver;
323
    }
324
325
    /**
326
     * Set result cache driver.
327
     *
328
     * @param CacheProvider $resultCacheDriver
329
     */
330
    public function setResultCacheDriver(CacheProvider $resultCacheDriver)
331
    {
332
        $this->resultCacheDriver = $resultCacheDriver;
333
    }
334
335
    /**
336
     * Retrieve hydrator cache driver.
337
     *
338
     * @throws \InvalidArgumentException
339
     *
340
     * @return CacheProvider
341
     */
342
    public function getHydratorCacheDriver()
343
    {
344
        if (!$this->hydratorCacheDriver instanceof CacheProvider) {
345
            $this->hydratorCacheDriver = $this->getCacheDriver(
346
                (string) $this->getOption('hydrator_cache_namespace'),
347
                $this->getOption('hydrator_cache_driver')
348
            );
349
        }
350
351
        return $this->hydratorCacheDriver;
352
    }
353
354
    /**
355
     * Set hydrator cache driver.
356
     *
357
     * @param CacheProvider $hydratorCacheDriver
358
     */
359
    public function setHydratorCacheDriver(CacheProvider $hydratorCacheDriver)
360
    {
361
        $this->hydratorCacheDriver = $hydratorCacheDriver;
362
    }
363
364
    /**
365
     * Get cache driver.
366
     *
367
     * @param string             $cacheNamespace
368
     * @param CacheProvider|null $cacheDriver
369
     *
370
     * @return CacheProvider
371
     */
372
    protected function getCacheDriver($cacheNamespace, CacheProvider $cacheDriver = null)
373
    {
374
        if (!$cacheDriver instanceof CacheProvider) {
375
            $cacheDriver = clone $this->getMetadataCacheDriver();
376
            $cacheDriver->setNamespace($cacheNamespace);
377
        }
378
379
        if ($cacheDriver->getNamespace() === '') {
380
            $cacheDriver->setNamespace($cacheNamespace);
381
        }
382
383
        return $cacheDriver;
384
    }
385
386
    /**
387
     * Retrieve naming strategy.
388
     *
389
     * @return NamingStrategy
390
     */
391
    protected function getNamingStrategy()
392
    {
393
        if (!$this->namingStrategy instanceof NamingStrategy) {
394
            $namingStrategy = $this->getOption('naming_strategy');
395
396
            if (!$namingStrategy instanceof NamingStrategy) {
397
                $namingStrategy = new UnderscoreNamingStrategy(CASE_LOWER);
398
            }
399
400
            $this->namingStrategy = $namingStrategy;
401
        }
402
403
        return $this->namingStrategy;
404
    }
405
406
    /**
407
     * Retrieve quote strategy.
408
     *
409
     * @throws \InvalidArgumentException
410
     *
411
     * @return QuoteStrategy
412
     */
413
    protected function getQuoteStrategy()
414
    {
415
        if (!$this->quoteStrategy instanceof QuoteStrategy) {
416
            $quoteStrategy = $this->getOption('quote_strategy');
417
418
            if (!$quoteStrategy instanceof QuoteStrategy) {
419
                $quoteStrategy = new DefaultQuoteStrategy;
420
            }
421
422
            $this->quoteStrategy = $quoteStrategy;
423
        }
424
425
        return $this->quoteStrategy;
426
    }
427
428
    /**
429
     * Retrieve second level cache configuration.
430
     *
431
     * @return CacheConfiguration|null
432
     */
433
    protected function getSecondLevelCacheConfiguration()
434
    {
435
        if (!$this->secondCacheConfig instanceof CacheConfiguration) {
436
            $secondCacheConfig = $this->getOption('second_level_cache_configuration');
437
438
            if ($secondCacheConfig instanceof CacheConfiguration) {
439
                $this->secondCacheConfig = $secondCacheConfig;
440
            }
441
        }
442
443
        return $this->secondCacheConfig;
444
    }
445
446
    /**
447
     * Retrieve SQL logger.
448
     *
449
     * @return SQLLogger|null
450
     */
451
    protected function getSQLLogger()
452
    {
453
        if (!$this->SQLLogger instanceof SQLLogger) {
454
            $sqlLogger = $this->getOption('sql_logger');
455
456
            if ($sqlLogger instanceof SQLLogger) {
457
                $this->SQLLogger = $sqlLogger;
458
            }
459
        }
460
461
        return $this->SQLLogger;
462
    }
463
464
    /**
465
     * Retrieve custom DQL string functions.
466
     *
467
     * @return array
468
     */
469
    protected function getCustomStringFunctions()
470
    {
471
        $functions = (array) $this->getOption('custom_string_functions');
472
473
        return array_filter(
474
            $functions,
475
            function ($name) {
476
                return is_string($name);
477
            },
478
            ARRAY_FILTER_USE_KEY
479
        );
480
    }
481
482
    /**
483
     * Retrieve custom DQL numeric functions.
484
     *
485
     * @return array
486
     */
487
    protected function getCustomNumericFunctions()
488
    {
489
        $functions = (array) $this->getOption('custom_numeric_functions');
490
491
        return array_filter(
492
            $functions,
493
            function ($name) {
494
                return is_string($name);
495
            },
496
            ARRAY_FILTER_USE_KEY
497
        );
498
    }
499
500
    /**
501
     * Retrieve custom DQL date time functions.
502
     *
503
     * @return array
504
     */
505
    protected function getCustomDateTimeFunctions()
506
    {
507
        $functions = (array) $this->getOption('custom_datetime_functions');
508
509
        return array_filter(
510
            $functions,
511
            function ($name) {
512
                return is_string($name);
513
            },
514
            ARRAY_FILTER_USE_KEY
515
        );
516
    }
517
518
    /**
519
     * Retrieve custom DBAL types.
520
     *
521
     * @return array
522
     */
523
    protected function getCustomTypes()
524
    {
525
        $types = (array) $this->getOption('custom_types');
526
527
        return array_filter(
528
            $types,
529
            function ($name) {
530
                return is_string($name);
531
            },
532
            ARRAY_FILTER_USE_KEY
533
        );
534
    }
535
536
    /**
537
     * Get custom registered filters.
538
     *
539
     * @return array
540
     */
541
    protected function getCustomFilters()
542
    {
543
        $filters = (array) $this->getOption('custom_filters');
544
545
        return array_filter(
546
            $filters,
547
            function ($name) {
548
                return is_string($name);
549
            },
550
            ARRAY_FILTER_USE_KEY
551
        );
552
    }
553
554
    /**
555
     * {@inheritdoc}
556
     *
557
     * @throws \Doctrine\DBAL\DBALException
558
     * @throws \Doctrine\ORM\ORMException
559
     * @throws \InvalidArgumentException
560
     * @throws \RuntimeException
561
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
562
     * @throws \Symfony\Component\Console\Exception\LogicException
563
     * @throws \UnexpectedValueException
564
     *
565
     * @return Command[]
566
     */
567
    public function getConsoleCommands()
568
    {
569
        $commands = [
570
            // DBAL
571
            new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
572
            new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
573
574
            // ORM
575
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
576
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
577
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
578
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
579
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
580
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
581
            new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
582
            new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
583
            new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
584
            new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
585
            new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
586
            new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
587
            new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
588
            new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
589
            new \Doctrine\ORM\Tools\Console\Command\InfoCommand(),
590
        ];
591
592
        if (Version::compare('2.5') <= 0) {
593
            $commands[] = new \Doctrine\ORM\Tools\Console\Command\MappingDescribeCommand();
594
        }
595
596
        $commandPrefix = (string) $this->getName();
597
598
        if ($commandPrefix !== '') {
599
            $commands = array_map(
600
                function (Command $command) use ($commandPrefix) {
601
                    $commandNames = array_map(
602
                        function ($commandName) use ($commandPrefix) {
603
                            return preg_replace('/^(dbal|orm):/', $commandPrefix . ':$1:', $commandName);
604
                        },
605
                        array_merge([$command->getName()], $command->getAliases())
606
                    );
607
608
                    $command->setName(array_shift($commandNames));
609
                    $command->setAliases($commandNames);
610
611
                    return $command;
612
                },
613
                $commands
614
            );
615
        }
616
617
        return $commands;
618
    }
619
620
    /**
621
     * {@inheritdoc}
622
     *
623
     * @throws \Doctrine\DBAL\DBALException
624
     * @throws \Doctrine\ORM\ORMException
625
     * @throws \InvalidArgumentException
626
     * @throws \RuntimeException
627
     * @throws \UnexpectedValueException
628
     */
629
    public function getConsoleHelperSet()
630
    {
631
        /* @var EntityManager $entityManager */
632
        $entityManager = $this->getManager();
633
634
        return new HelperSet([
635
            'db' => new ConnectionHelper($entityManager->getConnection()),
636
            'em' => new EntityManagerHelper($entityManager),
637
        ]);
638
    }
639
}
640