Completed
Push — master ( cde619...14b33f )
by Julián
08:25
created

RelationalBuilder::getHydratorCacheDriver()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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