Failed Conditions
Push — master ( ee4e26...e98654 )
by Marco
13:06
created

Configuration::getDefaultQueryHint()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM;
6
7
use Doctrine\Common\Annotations\AnnotationReader;
8
use Doctrine\Common\Annotations\AnnotationRegistry;
9
use Doctrine\Common\Annotations\CachedReader;
10
use Doctrine\Common\Cache\ArrayCache;
11
use Doctrine\Common\Cache\Cache as CacheDriver;
12
use Doctrine\Common\Persistence\ObjectRepository;
13
use Doctrine\DBAL\Configuration as DBALConfiguration;
14
use Doctrine\ORM\Cache\CacheConfiguration;
15
use Doctrine\ORM\Mapping\ClassMetadataFactory;
16
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
17
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
18
use Doctrine\ORM\Mapping\Driver\MappingDriver;
19
use Doctrine\ORM\Mapping\EntityListenerResolver;
20
use Doctrine\ORM\Mapping\Factory\DefaultNamingStrategy;
21
use Doctrine\ORM\Mapping\Factory\NamingStrategy;
22
use Doctrine\ORM\Proxy\Factory\ProxyFactory;
23
use Doctrine\ORM\Query\ResultSetMapping;
24
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
25
use Doctrine\ORM\Repository\RepositoryFactory;
26
use ProxyManager\Configuration as ProxyManagerConfiguration;
27
use ProxyManager\Factory\LazyLoadingGhostFactory;
28
use ProxyManager\FileLocator\FileLocator;
29
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
30
use ProxyManager\GeneratorStrategy\FileWriterGeneratorStrategy;
31
32
/**
33
 * Configuration container for all configuration options of Doctrine.
34
 * It combines all configuration options from DBAL & ORM.
35
 *
36
 * {@internal When adding a new configuration option just write a getter/setter pair. }}
37
 */
38
class Configuration extends DBALConfiguration
39
{
40
    /**
41
     * @var ProxyManagerConfiguration|null
42
     */
43
    private $proxyManagerConfiguration;
44
45
    /**
46
     * @var MappingDriver|null
47
     */
48
    private $metadataDriver;
49
50
    /**
51
     * @var CacheDriver|null
52
     */
53
    private $queryCache;
54
55
    /**
56
     * @var CacheDriver|null
57
     */
58
    private $hydrationCache;
59
60
    /**
61
     * @var CacheDriver|null
62
     */
63
    private $metadataCache;
64
65
    /**
66
     * @var string[][]|ResultSetMapping[][] tuples of [$sqlString, $resultSetMapping] indexed by query name
67
     */
68
    private $namedNativeQueries = [];
69
70
    /**
71
     * @var string[][]|ResultSetMapping[][] tuples of [$sqlString, $resultSetMapping] indexed by query name
72
     */
73
    private $customStringFunctions = [];
74
75
    /**
76
     * @var string[][]|ResultSetMapping[][] tuples of [$sqlString, $resultSetMapping] indexed by query name
77
     */
78
    private $customNumericFunctions = [];
79
80
    /**
81
     * @var string[][]|ResultSetMapping[][] tuples of [$sqlString, $resultSetMapping] indexed by query name
82
     */
83
    private $customDatetimeFunctions = [];
84
85
    /**
86
     * @var string[] of hydrator class names, indexed by mode name
87
     */
88
    private $customHydrationModes = [];
89
90
    /**
91
     * @var string
92
     */
93
    private $classMetadataFactoryClassName = ClassMetadataFactory::class;
94
95
    /**
96
     * @var string[] of filter class names, indexed by filter name
97
     */
98
    private $filters;
99
100
    /**
101
     * @var string
102
     */
103
    private $defaultRepositoryClassName = EntityRepository::class;
104
105
    /**
106
     * @var NamingStrategy|null
107
     */
108
    private $namingStrategy;
109
110
    /**
111
     * @var EntityListenerResolver|null
112
     */
113
    private $entityListenerResolver;
114
115
    /**
116
     * @var RepositoryFactory|null
117
     */
118
    private $repositoryFactory;
119
120
    /**
121
     * @var bool
122
     */
123
    private $isSecondLevelCacheEnabled = false;
124
125
    /**
126
     * @var CacheConfiguration|null
127
     */
128
    private $secondLevelCacheConfiguration;
129
130
    /**
131
     * @var mixed[] indexed by hint name
132
     */
133
    private $defaultQueryHints = [];
134
135
    /**
136
     * Sets the directory where Doctrine generates any necessary proxy class files.
137
     */
138 89
    public function setProxyDir(string $directory) : void
139
    {
140 89
        $this->getProxyManagerConfiguration()->setProxiesTargetDir($directory);
141 89
        $this->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS);
142 89
    }
143
144
    /**
145
     * Sets the strategy for automatically generating proxy classes.
146
     *
147
     * @param bool|int $autoGenerate Possible values are constants of Doctrine\ORM\Proxy\Factory\ProxyFactory.
148
     *                               True is converted to AUTOGENERATE_ALWAYS, false to AUTOGENERATE_NEVER.
149
     */
150 2271
    public function setAutoGenerateProxyClasses($autoGenerate) : void
151
    {
152 2271
        $proxyManagerConfig = $this->getProxyManagerConfiguration();
153
154 2271
        switch ((int) $autoGenerate) {
155
            case ProxyFactory::AUTOGENERATE_ALWAYS:
156
            case ProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS:
157 98
                $proxyManagerConfig->setGeneratorStrategy(new FileWriterGeneratorStrategy(
158 98
                    new FileLocator($proxyManagerConfig->getProxiesTargetDir())
159
                ));
160
161 98
                return;
162
            case ProxyFactory::AUTOGENERATE_NEVER:
163
            case ProxyFactory::AUTOGENERATE_EVAL:
164
            default:
165 2188
                $proxyManagerConfig->setGeneratorStrategy(new EvaluatingGeneratorStrategy());
166
167 2188
                return;
168
        }
169
    }
170
171
    /**
172
     * Sets the namespace where proxy classes reside.
173
     */
174 2258
    public function setProxyNamespace(string $namespace) : void
175
    {
176 2258
        $this->getProxyManagerConfiguration()->setProxiesNamespace($namespace);
177 2258
    }
178
179
    /**
180
     * Sets the cache driver implementation that is used for metadata caching.
181
     *
182
     * @todo Force parameter to be a Closure to ensure lazy evaluation
183
     *       (as soon as a metadata cache is in effect, the driver never needs to initialize).
184
     */
185 2254
    public function setMetadataDriverImpl(MappingDriver $metadataDriver) : void
186
    {
187 2254
        $this->metadataDriver = $metadataDriver;
188 2254
    }
189
190
    /**
191
     * Adds a new default annotation driver with a correctly configured annotation reader.
192
     *
193
     * @param string[] $paths
194
     */
195 2244
    public function newDefaultAnnotationDriver(array $paths = []) : AnnotationDriver
196
    {
197 2244
        AnnotationRegistry::registerFile(__DIR__ . '/Annotation/DoctrineAnnotations.php');
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Common\Annotati...egistry::registerFile() has been deprecated: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists') ( Ignorable by Annotation )

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

197
        /** @scrutinizer ignore-deprecated */ AnnotationRegistry::registerFile(__DIR__ . '/Annotation/DoctrineAnnotations.php');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
198
199 2244
        $reader = new CachedReader(new AnnotationReader(), new ArrayCache());
200
201 2244
        return new AnnotationDriver($reader, $paths);
202
    }
203
204
    /**
205
     * Gets the cache driver implementation that is used for the mapping metadata.
206
     */
207 2252
    public function getMetadataDriverImpl() : ?MappingDriver
208
    {
209 2252
        return $this->metadataDriver;
210
    }
211
212
    /**
213
     * Gets the cache driver implementation that is used for the query cache (SQL cache).
214
     */
215 766
    public function getQueryCacheImpl() : ?CacheDriver
216
    {
217 766
        return $this->queryCache;
218
    }
219
220
    /**
221
     * Sets the cache driver implementation that is used for the query cache (SQL cache).
222
     */
223 2195
    public function setQueryCacheImpl(CacheDriver $queryCache) : void
224
    {
225 2195
        $this->queryCache = $queryCache;
226 2195
    }
227
228
    /**
229
     * Gets the cache driver implementation that is used for the hydration cache (SQL cache).
230
     */
231 1
    public function getHydrationCacheImpl() : ?CacheDriver
232
    {
233 1
        return $this->hydrationCache;
234
    }
235
236
    /**
237
     * Sets the cache driver implementation that is used for the hydration cache (SQL cache).
238
     */
239 1
    public function setHydrationCacheImpl(CacheDriver $hydrationCache) : void
240
    {
241 1
        $this->hydrationCache = $hydrationCache;
242 1
    }
243
244
    /**
245
     * Gets the cache driver implementation that is used for metadata caching.
246
     */
247 2259
    public function getMetadataCacheImpl() : ?CacheDriver
248
    {
249 2259
        return $this->metadataCache;
250
    }
251
252
    /**
253
     * Sets the cache driver implementation that is used for metadata caching.
254
     */
255 2195
    public function setMetadataCacheImpl(CacheDriver $metadataCache) : void
256
    {
257 2195
        $this->metadataCache = $metadataCache;
258 2195
    }
259
260
    /**
261
     * Adds a named native query to the configuration.
262
     */
263 1
    public function addNamedNativeQuery(string $queryName, string $sql, ResultSetMapping $resultSetMapping) : void
264
    {
265 1
        $this->namedNativeQueries[$queryName] = [$sql, $resultSetMapping];
266 1
    }
267
268
    /**
269
     * Gets the components of a previously registered named native query.
270
     *
271
     * @return string[]|ResultSetMapping[] tuple of [$sqlString, $resultSetMaping]
272
     *
273
     * @throws ORMException
274
     */
275 1
    public function getNamedNativeQuery(string $queryName) : array
276
    {
277 1
        if (! isset($this->namedNativeQueries[$queryName])) {
278 1
            throw ORMException::namedNativeQueryNotFound($queryName);
279
        }
280
281 1
        return $this->namedNativeQueries[$queryName];
282
    }
283
284
    /**
285
     * Ensures that this Configuration instance contains settings that are
286
     * suitable for a production environment.
287
     *
288
     * @throws ORMException If a configuration setting has a value that is not
289
     *                      suitable for a production environment.
290
     */
291 6
    public function ensureProductionSettings() : void
292
    {
293 6
        $queryCacheImpl = $this->getQueryCacheImpl();
294
295 6
        if (! $queryCacheImpl) {
296 1
            throw ORMException::queryCacheNotConfigured();
297
        }
298
299 5
        if ($queryCacheImpl instanceof ArrayCache) {
300 1
            throw ORMException::queryCacheUsesNonPersistentCache($queryCacheImpl);
301
        }
302
303 4
        $metadataCacheImpl = $this->getMetadataCacheImpl();
304
305 4
        if (! $metadataCacheImpl) {
306 1
            throw ORMException::metadataCacheNotConfigured();
307
        }
308
309 3
        if ($metadataCacheImpl instanceof ArrayCache) {
310 1
            throw ORMException::metadataCacheUsesNonPersistentCache($metadataCacheImpl);
311
        }
312
313 2
        if ($this->getProxyManagerConfiguration()->getGeneratorStrategy() instanceof EvaluatingGeneratorStrategy) {
314 1
            throw ORMException::proxyClassesAlwaysRegenerating();
315
        }
316 1
    }
317
318
    /**
319
     * Registers a custom DQL function that produces a string value.
320
     * Such a function can then be used in any DQL statement in any place where string
321
     * functions are allowed.
322
     *
323
     * DQL function names are case-insensitive.
324
     *
325
     * @param string|callable $classNameOrFactory Class name or a callable that returns the function.
326
     */
327 4
    public function addCustomStringFunction(string $functionName, $classNameOrFactory) : void
328
    {
329 4
        $this->customStringFunctions[\strtolower($functionName)] = $classNameOrFactory;
330 4
    }
331
332
    /**
333
     * Gets the implementation class name of a registered custom string DQL function.
334
     *
335
     * @return string|callable|null
336
     */
337 157
    public function getCustomStringFunction(string $functionName)
338
    {
339 157
        return $this->customStringFunctions[\strtolower($functionName)] ?? null;
340
    }
341
342
    /**
343
     * Sets a map of custom DQL string functions.
344
     *
345
     * Keys must be function names and values the FQCN of the implementing class.
346
     * The function names will be case-insensitive in DQL.
347
     *
348
     * Any previously added string functions are discarded.
349
     *
350
     * @param string[]|callable[] $functions The map of custom DQL string functions.
351
     */
352 1
    public function setCustomStringFunctions(array $functions) : void
353
    {
354 1
        foreach ($functions as $name => $className) {
355 1
            $this->addCustomStringFunction($name, $className);
356
        }
357 1
    }
358
359
    /**
360
     * Registers a custom DQL function that produces a numeric value.
361
     * Such a function can then be used in any DQL statement in any place where numeric
362
     * functions are allowed.
363
     *
364
     * DQL function names are case-insensitive.
365
     *
366
     * @param string|callable $classNameOrFactory Class name or a callable that returns the function.
367
     */
368 3
    public function addCustomNumericFunction(string $functionName, $classNameOrFactory) : void
369
    {
370 3
        $this->customNumericFunctions[\strtolower($functionName)] = $classNameOrFactory;
371 3
    }
372
373
    /**
374
     * Gets the implementation class name of a registered custom numeric DQL function.
375
     *
376
     * @return string|callable|null
377
     */
378 155
    public function getCustomNumericFunction(string $functionName)
379
    {
380 155
        return $this->customNumericFunctions[\strtolower($functionName)] ?? null;
381
    }
382
383
    /**
384
     * Sets a map of custom DQL numeric functions.
385
     *
386
     * Keys must be function names and values the FQCN of the implementing class.
387
     * The function names will be case-insensitive in DQL.
388
     *
389
     * Any previously added numeric functions are discarded.
390
     *
391
     * @param string[]|callable[] $functions The map of custom DQL numeric functions.
392
     */
393 2
    public function setCustomNumericFunctions(array $functions) : void
394
    {
395 2
        foreach ($functions as $name => $className) {
396 1
            $this->addCustomNumericFunction($name, $className);
397
        }
398 2
    }
399
400
    /**
401
     * Registers a custom DQL function that produces a date/time value.
402
     * Such a function can then be used in any DQL statement in any place where date/time
403
     * functions are allowed.
404
     *
405
     * DQL function names are case-insensitive.
406
     *
407
     * @param string|callable $classNameOrFactory Class name or a callable that returns the function.
408
     */
409 1
    public function addCustomDatetimeFunction(string $functionName, $classNameOrFactory)
410
    {
411 1
        $this->customDatetimeFunctions[\strtolower($functionName)] = $classNameOrFactory;
412 1
    }
413
414
    /**
415
     * Gets the implementation class name of a registered custom date/time DQL function.
416
     *
417
     * @return string|callable|null
418
     */
419 153
    public function getCustomDatetimeFunction(string $functionName)
420
    {
421 153
        return $this->customDatetimeFunctions[\strtolower($functionName)] ?? null;
422
    }
423
424
    /**
425
     * Sets a map of custom DQL date/time functions.
426
     *
427
     * Keys must be function names and values the FQCN of the implementing class.
428
     * The function names will be case-insensitive in DQL.
429
     *
430
     * Any previously added date/time functions are discarded.
431
     *
432
     * @param iterable|string[] $functions The map of custom DQL date/time functions.
433
     */
434 1
    public function setCustomDatetimeFunctions(array $functions) : void
435
    {
436 1
        foreach ($functions as $name => $className) {
437 1
            $this->addCustomDatetimeFunction($name, $className);
438
        }
439 1
    }
440
441
    /**
442
     * Sets the custom hydrator modes in one pass.
443
     *
444
     * @param iterable|string[] $modes An iterable of string $modeName => string $hydratorClassName
445
     */
446 1
    public function setCustomHydrationModes(iterable $modes) : void
447
    {
448 1
        $this->customHydrationModes = [];
449
450 1
        foreach ($modes as $modeName => $hydrator) {
451 1
            $this->addCustomHydrationMode($modeName, $hydrator);
452
        }
453 1
    }
454
455
    /**
456
     * Gets the hydrator class for the given hydration mode name.
457
     *
458
     * @return string|null The hydrator class name.
459
     */
460 3
    public function getCustomHydrationMode(string $modeName) : ?string
461
    {
462 3
        return $this->customHydrationModes[$modeName] ?? null;
463
    }
464
465
    /**
466
     * Adds a custom hydration mode.
467
     */
468 3
    public function addCustomHydrationMode(string $modeName, string $hydratorClassName) : void
469
    {
470 3
        $this->customHydrationModes[$modeName] = $hydratorClassName;
471 3
    }
472
473
    /**
474
     * Sets a class metadata factory.
475
     */
476 1
    public function setClassMetadataFactoryName(string $classMetadataFactoryClassName) : void
477
    {
478 1
        $this->classMetadataFactoryClassName = $classMetadataFactoryClassName;
479 1
    }
480
481 2250
    public function getClassMetadataFactoryName() : string
482
    {
483 2250
        return $this->classMetadataFactoryClassName;
484
    }
485
486
    /**
487
     * Adds a filter to the list of possible filters.
488
     */
489 46
    public function addFilter(string $filterName, string $filterClassName) : void
490
    {
491 46
        $this->filters[$filterName] = $filterClassName;
492 46
    }
493
494
    /**
495
     * Gets the class name for a given filter name.
496
     *
497
     * @return string|null The class name of the filter
498
     */
499 45
    public function getFilterClassName(string $filterName) : ?string
500
    {
501 45
        return $this->filters[$filterName] ?? null;
502
    }
503
504
    /**
505
     * Sets default repository class.
506
     *
507
     * @throws ORMException If not is a \Doctrine\Common\Persistence\ObjectRepository implementation.
508
     */
509 2
    public function setDefaultRepositoryClassName(string $repositoryClassName) : void
510
    {
511 2
        $reflectionClass = new \ReflectionClass($repositoryClassName);
512
513 2
        if (! $reflectionClass->implementsInterface(ObjectRepository::class)) {
514 1
            throw ORMException::invalidEntityRepository($repositoryClassName);
515
        }
516
517 1
        $this->defaultRepositoryClassName = $repositoryClassName;
518 1
    }
519
520
    /**
521
     * Get default repository class.
522
     */
523 145
    public function getDefaultRepositoryClassName() : string
524
    {
525 145
        return $this->defaultRepositoryClassName;
526
    }
527
528
    /**
529
     * Sets naming strategy.
530
     */
531 3
    public function setNamingStrategy(NamingStrategy $namingStrategy) : void
532
    {
533 3
        $this->namingStrategy = $namingStrategy;
534 3
    }
535
536
    /**
537
     * Gets naming strategy..
538
     */
539 1951
    public function getNamingStrategy() : ?NamingStrategy
540
    {
541 1951
        return $this->namingStrategy
542 1951
            ?? $this->namingStrategy = new DefaultNamingStrategy();
543
    }
544
545
    /**
546
     * Set the entity listener resolver.
547
     */
548 1
    public function setEntityListenerResolver(EntityListenerResolver $resolver) : void
549
    {
550 1
        $this->entityListenerResolver = $resolver;
551 1
    }
552
553
    /**
554
     * Get the entity listener resolver.
555
     */
556 2250
    public function getEntityListenerResolver() : EntityListenerResolver
557
    {
558 2250
        return $this->entityListenerResolver
559 2250
            ?? $this->entityListenerResolver = new DefaultEntityListenerResolver();
560
    }
561
562
    /**
563
     * Set the entity repository factory.
564
     */
565
    public function setRepositoryFactory(RepositoryFactory $repositoryFactory) : void
566
    {
567
        $this->repositoryFactory = $repositoryFactory;
568
    }
569
570
    /**
571
     * Get the entity repository factory.
572
     */
573 2249
    public function getRepositoryFactory() : RepositoryFactory
574
    {
575 2249
        return $this->repositoryFactory
576 2249
            ?? $this->repositoryFactory = new DefaultRepositoryFactory();
577
    }
578
579 2249
    public function isSecondLevelCacheEnabled() : bool
580
    {
581 2249
        return $this->isSecondLevelCacheEnabled;
582
    }
583
584 279
    public function setSecondLevelCacheEnabled(bool $flag = true) : void
585
    {
586 279
        $this->isSecondLevelCacheEnabled = $flag;
587 279
    }
588
589 280
    public function setSecondLevelCacheConfiguration(CacheConfiguration $cacheConfig) : void
590
    {
591 280
        $this->secondLevelCacheConfiguration = $cacheConfig;
592 280
    }
593
594 280
    public function getSecondLevelCacheConfiguration() : ?CacheConfiguration
595
    {
596 280
        if ($this->isSecondLevelCacheEnabled && ! $this->secondLevelCacheConfiguration) {
597
            $this->secondLevelCacheConfiguration = new CacheConfiguration();
598
        }
599
600 280
        return $this->secondLevelCacheConfiguration;
601
    }
602
603
    /**
604
     * Returns query hints, which will be applied to every query in application
605
     *
606
     * @return mixed[]
607
     */
608 971
    public function getDefaultQueryHints() : array
609
    {
610 971
        return $this->defaultQueryHints;
611
    }
612
613
    /**
614
     * Sets array of query hints, which will be applied to every query in application
615
     *
616
     * @param mixed[] $defaultQueryHints
617
     */
618 1
    public function setDefaultQueryHints(array $defaultQueryHints) : void
619
    {
620 1
        $this->defaultQueryHints = $defaultQueryHints;
621 1
    }
622
623
    /**
624
     * Gets the value of a default query hint. If the hint name is not recognized, FALSE is returned.
625
     *
626
     * @return mixed The value of the hint or FALSE, if the hint name is not recognized.
627
     */
628
    public function getDefaultQueryHint(string $hintName)
629
    {
630
        return $this->defaultQueryHints[$hintName] ?? false;
631
    }
632
633
    /**
634
     * Sets a default query hint. If the hint name is not recognized, it is silently ignored.
635
     *
636
     * @param mixed $value The value of the hint.
637
     */
638 1
    public function setDefaultQueryHint(string $hintName, $value) : void
639
    {
640 1
        $this->defaultQueryHints[$hintName] = $value;
641 1
    }
642
643 2250
    public function buildGhostObjectFactory() : LazyLoadingGhostFactory
644
    {
645 2250
        return new LazyLoadingGhostFactory(clone $this->getProxyManagerConfiguration());
646
    }
647
648 2273
    public function getProxyManagerConfiguration() : ProxyManagerConfiguration
649
    {
650 2273
        return $this->proxyManagerConfiguration
651 2273
            ?? $this->proxyManagerConfiguration = new ProxyManagerConfiguration();
652
    }
653
}
654