Completed
Push — master ( 4695ab...73566d )
by Julián
02:31
created

RelationalBuilder::getDefaultOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 0
1
<?php
2
/**
3
 * doctrine-manager-builder (https://github.com/juliangut/doctrine-manager-builder)
4
 * Doctrine2 managers builder
5
 *
6
 * @license BSD-3-Clause
7
 * @author Julián Gutiérrez <[email protected]>
8
 */
9
10
namespace Jgut\Doctrine\ManagerBuilder;
11
12
use Doctrine\Common\Annotations\AnnotationReader;
13
use Doctrine\Common\Cache\Cache;
14
use Doctrine\DBAL\Logging\SQLLogger;
15
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
16
use Doctrine\DBAL\Types\Type;
17
use Doctrine\ORM\Configuration;
18
use Doctrine\ORM\EntityManager;
19
use Doctrine\ORM\EntityRepository;
20
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
21
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
22
use Doctrine\ORM\Mapping\Driver\XmlDriver;
23
use Doctrine\ORM\Mapping\Driver\YamlDriver;
24
use Doctrine\ORM\Mapping\NamingStrategy;
25
use Doctrine\ORM\Mapping\QuoteStrategy;
26
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
27
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
28
use Symfony\Component\Console\Command\Command;
29
use Symfony\Component\Console\Helper\HelperSet;
30
31
/**
32
 * Doctrine RDBMS Entity Manager builder
33
 */
34
class RelationalBuilder extends AbstractManagerBuilder
35
{
36
    /**
37
     * Entity Manager.
38
     *
39
     * @var EntityManager
40
     */
41
    protected $manager;
42
43
    /**
44
     * Query cache driver.
45
     *
46
     * @var Cache
47
     */
48
    protected $queryCacheDriver;
49
50
    /**
51
     * Result cache driver.
52
     *
53
     * @var Cache
54
     */
55
    protected $resultCacheDriver;
56
57
    /**
58
     * Naming strategy.
59
     *
60
     * @var NamingStrategy
61
     */
62
    protected $namingStrategy;
63
64
    /**
65
     * Quote strategy.
66
     *
67
     * @var QuoteStrategy
68
     */
69
    protected $quoteStrategy;
70
71
    /**
72
     * SQL logger.
73
     *
74
     * @var SQLLogger
75
     */
76
    protected $SQLLogger;
77
78
    /**
79
     * {@inheritdoc}
80
     */
81
    protected function getDefaultOptions()
82
    {
83
        return [
84
            'connection' => [], // Array or \Doctrine\DBAL\Connection
85
            'proxies_namespace' => 'DoctrineRDBMSORMProxy',
86
            'metadata_cache_namespace' => 'DoctrineRDBMSORMMetadataCache',
87
            //'query_cache_driver' => null,
88
            'query_cache_namespace' => 'DoctrineRDBMSORMQueryCache',
89
            //'result_cache_driver' => null,
90
            'result_cache_namespace' => 'DoctrineRDBMSORMResultCache',
91
            'default_repository_class' => EntityRepository::class,
92
            //'naming_strategy' => null, // Doctrine\ORM\Mapping\UnderscoreNamingStrategy(CASE_LOWER)
93
            //'quote_strategy' => null, // Doctrine\ORM\Mapping\DefaultQuoteStrategy
94
            //'sql_logger' => null,
95
            //'custom_string_functions' => [],
96
            //'custom_numeric_functions' => [],
97
            //'custom_datetime_functions' => [],
98
            //'custom_types' => [],
99
        ];
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     *
105
     * @throws \Doctrine\DBAL\DBALException
106
     * @throws \Doctrine\ORM\ORMException
107
     * @throws \InvalidArgumentException
108
     * @throws \RuntimeException
109
     * @throws \UnexpectedValueException
110
     *
111
     * @return EntityManager
112
     */
113
    public function getManager($standalone = false, $force = false)
114
    {
115
        if ($force === true) {
116
            $this->wipe();
117
        }
118
119
        if (!$this->manager instanceof EntityManager) {
120
            $this->manager = $this->buildManager($standalone);
121
        }
122
123
        return $this->manager;
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    protected function wipe()
130
    {
131
        parent::wipe();
132
133
        $this->manager = null;
134
        $this->queryCacheDriver = null;
135
        $this->resultCacheDriver = null;
136
        $this->namingStrategy = null;
137
        $this->quoteStrategy = null;
138
        $this->SQLLogger = null;
139
    }
140
141
    /**
142
     * Build new Doctrine entity manager.
143
     *
144
     * @param bool $standalone
145
     *
146
     * @throws \Doctrine\DBAL\DBALException
147
     * @throws \Doctrine\ORM\ORMException
148
     * @throws \InvalidArgumentException
149
     * @throws \RuntimeException
150
     * @throws \UnexpectedValueException
151
     *
152
     * @return EntityManager
153
     */
154
    protected function buildManager($standalone = false)
155
    {
156
        $config = new Configuration();
157
158
        $this->setupAnnotationMetadata($standalone);
159
        $config->setMetadataDriverImpl($this->getMetadataMappingDriver());
160
161
        $config->setProxyDir($this->getProxiesPath());
162
        $config->setProxyNamespace($this->getProxiesNamespace());
163
        $config->setAutoGenerateProxyClasses($this->getProxiesAutoGeneration());
164
165
        $config->setMetadataCacheImpl($this->getMetadataCacheDriver());
166
        $config->setQueryCacheImpl($this->getQueryCacheDriver());
167
        $config->setResultCacheImpl($this->getResultCacheDriver());
168
169
        if ($this->getDefaultRepositoryClass() !== null) {
170
            $config->setDefaultRepositoryClassName($this->getDefaultRepositoryClass());
171
        }
172
173
        $config->setNamingStrategy($this->getNamingStrategy());
174
        $config->setQuoteStrategy($this->getQuoteStrategy());
175
176
        $config->setSQLLogger($this->getSQLLogger());
177
        $config->setCustomStringFunctions($this->getCustomStringFunctions());
178
        $config->setCustomNumericFunctions($this->getCustomNumericFunctions());
179
        $config->setCustomDatetimeFunctions($this->getCustomDateTimeFunctions());
180
181
        $entityManager = EntityManager::create($this->getOption('connection'), $config, $this->getEventManager());
182
183
        $platform = $entityManager->getConnection()->getDatabasePlatform();
184
        foreach ($this->getCustomTypes() as $type => $class) {
185
            Type::addType($type, $class);
186
            $platform->registerDoctrineTypeMapping($type, $type);
187
        }
188
189
        return $entityManager;
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     *
195
     * @return AnnotationDriver
196
     */
197
    protected function getAnnotationMetadataDriver(array $paths)
198
    {
199
        return new AnnotationDriver(new AnnotationReader, $paths);
200
    }
201
202
    /**
203
     * {@inheritdoc}
204
     *
205
     * @return XmlDriver
206
     */
207
    protected function getXmlMetadataDriver(array $paths, $extension = null)
208
    {
209
        return new XmlDriver($paths, $extension ?: XmlDriver::DEFAULT_FILE_EXTENSION);
210
    }
211
212
    /**
213
     * {@inheritdoc}
214
     *
215
     * @return YamlDriver
216
     */
217
    protected function getYamlMetadataDriver(array $paths, $extension = null)
218
    {
219
        return new YamlDriver($paths, $extension ?: YamlDriver::DEFAULT_FILE_EXTENSION);
220
    }
221
222
    /**
223
     * Retrieve query cache driver.
224
     *
225
     * @throws \InvalidArgumentException
226
     *
227
     * @return Cache
228
     */
229
    public function getQueryCacheDriver()
230
    {
231
        if (!$this->queryCacheDriver instanceof Cache) {
232
            $queryCacheDriver = $this->getOption('query_cache_driver');
233
234
            if (!$queryCacheDriver instanceof Cache) {
235
                $queryCacheDriver = clone $this->getCacheDriver();
236
            }
237
238
            if ($queryCacheDriver->getNamespace() === '') {
239
                $queryCacheDriver->setNamespace((string) $this->getOption('query_cache_namespace'));
240
            }
241
242
            $this->queryCacheDriver = $queryCacheDriver;
243
        }
244
245
        return $this->queryCacheDriver;
246
    }
247
248
    /**
249
     * Set query cache driver.
250
     *
251
     * @param Cache $queryCacheDriver
252
     */
253
    public function setQueryCacheDriver(Cache $queryCacheDriver)
254
    {
255
        $this->queryCacheDriver = $queryCacheDriver;
256
    }
257
258
    /**
259
     * Retrieve result cache driver.
260
     *
261
     * @throws \InvalidArgumentException
262
     *
263
     * @return Cache
264
     */
265
    public function getResultCacheDriver()
266
    {
267
        if (!$this->resultCacheDriver instanceof Cache) {
268
            $resultCacheDriver = $this->getOption('result_cache_driver');
269
270
            if (!$resultCacheDriver instanceof Cache) {
271
                $resultCacheDriver = clone $this->getCacheDriver();
272
            }
273
274
            if ($resultCacheDriver->getNamespace() === '') {
275
                $resultCacheDriver->setNamespace((string) $this->getOption('result_cache_namespace'));
276
            }
277
278
            $this->resultCacheDriver = $resultCacheDriver;
279
        }
280
281
        return $this->resultCacheDriver;
282
    }
283
284
    /**
285
     * Set result cache driver.
286
     *
287
     * @param Cache $resultCacheDriver
288
     */
289
    public function setResultCacheDriver(Cache $resultCacheDriver)
290
    {
291
        $this->resultCacheDriver = $resultCacheDriver;
292
    }
293
294
    /**
295
     * Get default repository class name
296
     *
297
     * @return string|null
298
     */
299
    protected function getDefaultRepositoryClass()
300
    {
301
        return array_key_exists('default_repository_class', $this->options)
302
            ? (string) $this->options['default_repository_class']
303
            : null;
304
    }
305
306
    /**
307
     * Retrieve naming strategy.
308
     *
309
     * @return NamingStrategy
310
     */
311
    protected function getNamingStrategy()
312
    {
313
        if (!$this->namingStrategy instanceof NamingStrategy) {
314
            $namingStrategy = $this->getOption('naming_strategy');
315
316
            if (!$namingStrategy instanceof NamingStrategy) {
317
                $namingStrategy = new UnderscoreNamingStrategy(CASE_LOWER);
318
            }
319
320
            $this->namingStrategy = $namingStrategy;
321
        }
322
323
        return $this->namingStrategy;
324
    }
325
326
    /**
327
     * Retrieve quote strategy.
328
     *
329
     * @throws \InvalidArgumentException
330
     *
331
     * @return QuoteStrategy
332
     */
333
    protected function getQuoteStrategy()
334
    {
335
        if (!$this->quoteStrategy instanceof QuoteStrategy) {
336
            $quoteStrategy = $this->getOption('quote_strategy');
337
338
            if (!$quoteStrategy instanceof QuoteStrategy) {
339
                $quoteStrategy = new DefaultQuoteStrategy;
340
            }
341
342
            $this->quoteStrategy = $quoteStrategy;
343
        }
344
345
        return $this->quoteStrategy;
346
    }
347
348
    /**
349
     * Retrieve SQL logger.
350
     *
351
     * @return SQLLogger|null
352
     */
353
    protected function getSQLLogger()
354
    {
355
        if (!$this->SQLLogger instanceof SQLLogger) {
356
            $sqlLogger = $this->getOption('sql_logger');
357
358
            if ($sqlLogger instanceof SQLLogger) {
359
                $this->SQLLogger = $sqlLogger;
360
            }
361
        }
362
363
        return $this->SQLLogger;
364
    }
365
366
    /**
367
     * Retrieve custom DQL string functions.
368
     *
369
     * @return array
370
     */
371
    protected function getCustomStringFunctions()
372
    {
373
        $functions = (array) $this->getOption('custom_string_functions');
374
375
        return array_filter(
376
            $functions,
377
            function ($name) {
378
                return is_string($name);
379
            },
380
            ARRAY_FILTER_USE_KEY
381
        );
382
    }
383
384
    /**
385
     * Retrieve custom DQL numeric functions.
386
     *
387
     * @return array
388
     */
389
    protected function getCustomNumericFunctions()
390
    {
391
        $functions = (array) $this->getOption('custom_numeric_functions');
392
393
        return array_filter(
394
            $functions,
395
            function ($name) {
396
                return is_string($name);
397
            },
398
            ARRAY_FILTER_USE_KEY
399
        );
400
    }
401
402
    /**
403
     * Retrieve custom DQL date time functions.
404
     *
405
     * @return array
406
     */
407
    protected function getCustomDateTimeFunctions()
408
    {
409
        $functions = (array) $this->getOption('custom_datetime_functions');
410
411
        return array_filter(
412
            $functions,
413
            function ($name) {
414
                return is_string($name);
415
            },
416
            ARRAY_FILTER_USE_KEY
417
        );
418
    }
419
420
    /**
421
     * Retrieve custom DBAL types.
422
     *
423
     * @return array
424
     */
425
    protected function getCustomTypes()
426
    {
427
        $types = (array) $this->getOption('custom_types');
428
429
        return array_filter(
430
            $types,
431
            function ($name) {
432
                return is_string($name);
433
            },
434
            ARRAY_FILTER_USE_KEY
435
        );
436
    }
437
438
    /**
439
     * {@inheritdoc}
440
     *
441
     * @throws \Doctrine\DBAL\DBALException
442
     * @throws \Doctrine\ORM\ORMException
443
     * @throws \InvalidArgumentException
444
     * @throws \RuntimeException
445
     * @throws \Symfony\Component\Console\Exception\InvalidArgumentException
446
     * @throws \Symfony\Component\Console\Exception\LogicException
447
     * @throws \UnexpectedValueException
448
     *
449
     * @return Command[]
450
     */
451
    public function getConsoleCommands()
452
    {
453
        $commands = [
454
            // DBAL
455
            new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
456
            new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
457
458
            // ORM
459
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
460
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
461
            new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
462
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
463
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
464
            new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
465
            new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
466
            new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
467
            new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
468
            new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
469
            new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
470
            new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
471
            new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
472
            new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
473
            new \Doctrine\ORM\Tools\Console\Command\InfoCommand(),
474
            new \Doctrine\ORM\Tools\Console\Command\MappingDescribeCommand(),
475
        ];
476
        $commandPrefix = (string) $this->getName();
477
478
        if ($commandPrefix !== '') {
479
            $commands = array_map(
480
                function (Command $command) use ($commandPrefix) {
481
                    $commandNames = array_map(
482
                        function ($commandName) use ($commandPrefix) {
483
                            return preg_replace('/^(dbal|orm):/', $commandPrefix . ':$1:', $commandName);
484
                        },
485
                        array_merge([$command->getName()], $command->getAliases())
486
                    );
487
488
                    $command->setName(array_shift($commandNames));
489
                    $command->setAliases($commandNames);
490
491
                    return $command;
492
                },
493
                $commands
494
            );
495
        }
496
497
        return $commands;
498
    }
499
500
    /**
501
     * {@inheritdoc}
502
     *
503
     * @throws \Doctrine\DBAL\DBALException
504
     * @throws \Doctrine\ORM\ORMException
505
     * @throws \InvalidArgumentException
506
     * @throws \RuntimeException
507
     * @throws \UnexpectedValueException
508
     */
509
    public function getConsoleHelperSet()
510
    {
511
        $entityManager = $this->getManager();
512
513
        return new HelperSet([
514
            'db' => new ConnectionHelper($entityManager->getConnection()),
515
            'em' => new EntityManagerHelper($entityManager),
516
        ]);
517
    }
518
}
519