Passed
Push — master ( 3969cc...b281ee )
by Asmir
03:28 queued 01:08
created

SerializerBuilder::enableEnumSupport()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3.3332

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 2
cts 3
cp 0.6667
crap 3.3332
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace JMS\Serializer;
6
7
use Doctrine\Common\Annotations\AnnotationReader;
8
use Doctrine\Common\Annotations\CachedReader;
9
use Doctrine\Common\Annotations\PsrCachedReader;
10
use Doctrine\Common\Annotations\Reader;
11
use Doctrine\Common\Cache\FilesystemCache;
12
use JMS\Serializer\Accessor\AccessorStrategyInterface;
13
use JMS\Serializer\Accessor\DefaultAccessorStrategy;
14
use JMS\Serializer\Builder\DefaultDriverFactory;
15
use JMS\Serializer\Builder\DocBlockDriverFactory;
16
use JMS\Serializer\Builder\DriverFactoryInterface;
17
use JMS\Serializer\Construction\ObjectConstructorInterface;
18
use JMS\Serializer\Construction\UnserializeObjectConstructor;
19
use JMS\Serializer\ContextFactory\CallableDeserializationContextFactory;
20
use JMS\Serializer\ContextFactory\CallableSerializationContextFactory;
21
use JMS\Serializer\ContextFactory\DeserializationContextFactoryInterface;
22
use JMS\Serializer\ContextFactory\SerializationContextFactoryInterface;
23
use JMS\Serializer\EventDispatcher\EventDispatcher;
24
use JMS\Serializer\EventDispatcher\EventDispatcherInterface;
25
use JMS\Serializer\EventDispatcher\Subscriber\DoctrineProxySubscriber;
26
use JMS\Serializer\EventDispatcher\Subscriber\EnumSubscriber;
27
use JMS\Serializer\Exception\InvalidArgumentException;
28
use JMS\Serializer\Exception\RuntimeException;
29
use JMS\Serializer\Expression\CompilableExpressionEvaluatorInterface;
30
use JMS\Serializer\Expression\ExpressionEvaluatorInterface;
31
use JMS\Serializer\GraphNavigator\Factory\DeserializationGraphNavigatorFactory;
32
use JMS\Serializer\GraphNavigator\Factory\GraphNavigatorFactoryInterface;
33
use JMS\Serializer\GraphNavigator\Factory\SerializationGraphNavigatorFactory;
34
use JMS\Serializer\Handler\ArrayCollectionHandler;
35
use JMS\Serializer\Handler\DateHandler;
36
use JMS\Serializer\Handler\EnumHandler;
37
use JMS\Serializer\Handler\HandlerRegistry;
38
use JMS\Serializer\Handler\HandlerRegistryInterface;
39
use JMS\Serializer\Handler\IteratorHandler;
40
use JMS\Serializer\Handler\StdClassHandler;
41
use JMS\Serializer\Naming\CamelCaseNamingStrategy;
42
use JMS\Serializer\Naming\PropertyNamingStrategyInterface;
43
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
44
use JMS\Serializer\Type\Parser;
45
use JMS\Serializer\Type\ParserInterface;
46
use JMS\Serializer\Visitor\Factory\DeserializationVisitorFactory;
47
use JMS\Serializer\Visitor\Factory\JsonDeserializationVisitorFactory;
48
use JMS\Serializer\Visitor\Factory\JsonSerializationVisitorFactory;
49
use JMS\Serializer\Visitor\Factory\SerializationVisitorFactory;
50
use JMS\Serializer\Visitor\Factory\XmlDeserializationVisitorFactory;
51
use JMS\Serializer\Visitor\Factory\XmlSerializationVisitorFactory;
52
use Metadata\Cache\CacheInterface;
53
use Metadata\Cache\FileCache;
54
use Metadata\MetadataFactory;
55
use Metadata\MetadataFactoryInterface;
56
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
57
58
/**
59
 * Builder for serializer instances.
60
 *
61
 * This object makes serializer construction a breeze for projects that do not use
62
 * any special dependency injection container.
63
 *
64
 * @author Johannes M. Schmitt <[email protected]>
65
 */
66
final class SerializerBuilder
67
{
68
    /**
69
     * @var string[]
70
     */
71
    private $metadataDirs = [];
72
73
    /**
74
     * @var HandlerRegistryInterface
75
     */
76
    private $handlerRegistry;
77
78
    /**
79
     * @var bool
80
     */
81
    private $handlersConfigured = false;
82
83
    /**
84
     * @var EventDispatcherInterface
85
     */
86
    private $eventDispatcher;
87
88
    /**
89
     * @var bool
90
     */
91
    private $enableEnumSupport = false;
92
93
    /**
94
     * @var bool
95
     */
96 330
    private $listenersConfigured = false;
97
98 330
    /**
99
     * @var ObjectConstructorInterface
100
     */
101 330
    private $objectConstructor;
102
103 330
    /**
104 330
     * @var SerializationVisitorFactory[]
105 330
     */
106 330
    private $serializationVisitors;
107 330
108
    /**
109 330
     * @var DeserializationVisitorFactory[]
110 284
     */
111
    private $deserializationVisitors;
112 330
113 284
    /**
114
     * @var bool
115 330
     */
116
    private $deserializationVisitorsAdded = false;
117
118
    /**
119
     * @var bool
120
     */
121
    private $serializationVisitorsAdded = false;
122
123 330
    /**
124
     * @var PropertyNamingStrategyInterface
125 330
     */
126 330
    private $propertyNamingStrategy;
127
128 330
    /**
129
     * @var bool
130
     */
131 25
    private $debug = false;
132
133 25
    /**
134
     * @var string
135 25
     */
136
    private $cacheDir;
137
138 1
    /**
139
     * @var AnnotationReader
140 1
     */
141
    private $annotationReader;
142 1
143
    /**
144
     * @var bool
145
     */
146
    private $includeInterfaceMetadata = false;
147
148
    /**
149
     * @var DriverFactoryInterface
150
     */
151
    private $driverFactory;
152
153
    /**
154
     * @var SerializationContextFactoryInterface
155
     */
156
    private $serializationContextFactory;
157
158
    /**
159 1
     * @var DeserializationContextFactoryInterface
160
     */
161 1
    private $deserializationContextFactory;
162 1
163
    /**
164 1
     * @var ParserInterface
165
     */
166
    private $typeParser;
167
168 1
    /**
169
     * @var ExpressionEvaluatorInterface
170 1
     */
171
    private $expressionEvaluator;
172
173 71
    /**
174
     * @var AccessorStrategyInterface
175 71
     */
176 71
    private $accessorStrategy;
177 71
178 71
    /**
179
     * @var CacheInterface
180 71
     */
181
    private $metadataCache;
182
183 3
    /**
184
     * @var bool
185 3
     */
186 3
    private $docBlockTyperResolver;
187
188 3
    /**
189
     * @param mixed ...$args
190
     *
191 73
     * @return SerializerBuilder
192
     */
193 73
    public static function create(...$args): self
194 73
    {
195
        return new static(...$args);
0 ignored issues
show
Bug introduced by
$args is expanded, but the parameter $handlerRegistry of JMS\Serializer\SerializerBuilder::__construct() does not expect variable arguments. ( Ignorable by Annotation )

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

195
        return new static(/** @scrutinizer ignore-type */ ...$args);
Loading history...
196 73
    }
197
198
    public function __construct(?HandlerRegistryInterface $handlerRegistry = null, ?EventDispatcherInterface $eventDispatcher = null)
199 1
    {
200
        $this->typeParser = new Parser();
201 1
        $this->handlerRegistry = $handlerRegistry ?: new HandlerRegistry();
202 1
        $this->eventDispatcher = $eventDispatcher ?: new EventDispatcher();
203
        $this->serializationVisitors = [];
204 1
        $this->deserializationVisitors = [];
205
206
        if ($handlerRegistry) {
207 4
            $this->handlersConfigured = true;
208
        }
209 4
210
        if ($eventDispatcher) {
211 4
            $this->listenersConfigured = true;
212
        }
213
    }
214
215
    public function setAccessorStrategy(AccessorStrategyInterface $accessorStrategy): self
216
    {
217
        $this->accessorStrategy = $accessorStrategy;
218
219
        return $this;
220
    }
221 2
222
    private function getAccessorStrategy(): AccessorStrategyInterface
223 2
    {
224 2
        if (!$this->accessorStrategy) {
225
            $this->accessorStrategy = new DefaultAccessorStrategy($this->expressionEvaluator);
226 2
        }
227
228
        return $this->accessorStrategy;
229
    }
230
231
    public function setExpressionEvaluator(ExpressionEvaluatorInterface $expressionEvaluator): self
232
    {
233
        $this->expressionEvaluator = $expressionEvaluator;
234
235
        return $this;
236
    }
237 329
238
    public function setTypeParser(ParserInterface $parser): self
239 329
    {
240 329
        $this->typeParser = $parser;
241 329
242 329
        return $this;
243
    }
244
245 329
    public function setAnnotationReader(Reader $reader): self
246
    {
247
        $this->annotationReader = $reader;
0 ignored issues
show
Documentation Bug introduced by
$reader is of type Doctrine\Common\Annotations\Reader, but the property $annotationReader was declared to be of type Doctrine\Common\Annotations\AnnotationReader. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
248 329
249
        return $this;
250 329
    }
251 329
252 329
    public function setDebug(bool $bool): self
253 329
    {
254
        $this->debug = $bool;
255
256 329
        return $this;
257
    }
258
259
    public function setCacheDir(string $dir): self
260
    {
261
        if (!is_dir($dir)) {
262
            $this->createDir($dir);
263
        }
264 1
265
        if (!is_writable($dir)) {
266 1
            throw new InvalidArgumentException(sprintf('The cache directory "%s" is not writable.', $dir));
267
        }
268 1
269
        $this->cacheDir = $dir;
270
271
        return $this;
272
    }
273
274
    public function addDefaultHandlers(): self
275
    {
276
        $this->handlersConfigured = true;
277
        $this->handlerRegistry->registerSubscribingHandler(new DateHandler());
278
        $this->handlerRegistry->registerSubscribingHandler(new StdClassHandler());
279
        $this->handlerRegistry->registerSubscribingHandler(new ArrayCollectionHandler());
280
        $this->handlerRegistry->registerSubscribingHandler(new IteratorHandler());
281
282 2
        if ($this->enableEnumSupport) {
283
            $this->handlerRegistry->registerSubscribingHandler(new EnumHandler());
284 2
        }
285 2
286 2
        return $this;
287
    }
288
289
    public function configureHandlers(\Closure $closure): self
290 2
    {
291
        $this->handlersConfigured = true;
292 2
        $closure($this->handlerRegistry);
293
294
        return $this;
295
    }
296
297
    public function addDefaultListeners(): self
298
    {
299
        $this->listenersConfigured = true;
300
        $this->eventDispatcher->addSubscriber(new DoctrineProxySubscriber());
301
        if ($this->enableEnumSupport) {
302
            $this->eventDispatcher->addSubscriber(new EnumSubscriber());
303
        }
304
305
        return $this;
306
    }
307
308
    public function configureListeners(\Closure $closure): self
309
    {
310
        $this->listenersConfigured = true;
311
        $closure($this->eventDispatcher);
312
313
        return $this;
314
    }
315
316
    public function setObjectConstructor(ObjectConstructorInterface $constructor): self
317
    {
318
        $this->objectConstructor = $constructor;
319
320
        return $this;
321
    }
322
323
    public function setPropertyNamingStrategy(PropertyNamingStrategyInterface $propertyNamingStrategy): self
324
    {
325
        $this->propertyNamingStrategy = $propertyNamingStrategy;
326
327
        return $this;
328
    }
329
330
    public function setSerializationVisitor(string $format, SerializationVisitorFactory $visitor): self
331
    {
332
        $this->serializationVisitorsAdded = true;
333
        $this->serializationVisitors[$format] = $visitor;
334
335
        return $this;
336
    }
337
338
    public function setDeserializationVisitor(string $format, DeserializationVisitorFactory $visitor): self
339
    {
340
        $this->deserializationVisitorsAdded = true;
341
        $this->deserializationVisitors[$format] = $visitor;
342
343
        return $this;
344
    }
345
346
    public function addDefaultSerializationVisitors(): self
347
    {
348
        $this->serializationVisitorsAdded = true;
349
        $this->serializationVisitors = [
350
            'xml' => new XmlSerializationVisitorFactory(),
351
            'json' => new JsonSerializationVisitorFactory(),
352
        ];
353
354
        return $this;
355
    }
356
357
    public function addDefaultDeserializationVisitors(): self
358
    {
359
        $this->deserializationVisitorsAdded = true;
360
        $this->deserializationVisitors = [
361
            'xml' => new XmlDeserializationVisitorFactory(),
362
            'json' => new JsonDeserializationVisitorFactory(),
363
        ];
364
365
        return $this;
366
    }
367
368
    /**
369
     * @param bool $include Whether to include the metadata from the interfaces
370
     *
371
     * @return SerializerBuilder
372
     */
373
    public function includeInterfaceMetadata(bool $include): self
374
    {
375
        $this->includeInterfaceMetadata = $include;
376
377
        return $this;
378 13
    }
379
380 13
    /**
381
     * Sets a map of namespace prefixes to directories.
382 13
     *
383
     * This method overrides any previously defined directories.
384
     *
385
     * @param array <string,string> $namespacePrefixToDirMap
0 ignored issues
show
Documentation Bug introduced by
The doc comment <string,string> at position 0 could not be parsed: Unknown type name '<' at position 0 in <string,string>.
Loading history...
386
     *
387
     * @return SerializerBuilder
388
     *
389
     * @throws InvalidArgumentException When a directory does not exist.
390 5
     */
391
    public function setMetadataDirs(array $namespacePrefixToDirMap): self
392 5
    {
393 3
        foreach ($namespacePrefixToDirMap as $dir) {
394 2
            if (!is_dir($dir)) {
395 2
                throw new InvalidArgumentException(sprintf('The directory "%s" does not exist.', $dir));
396 2
            }
397
        }
398
399
        $this->metadataDirs = $namespacePrefixToDirMap;
400
401
        return $this;
402 5
    }
403
404
    /**
405
     * Adds a directory where the serializer will look for class metadata.
406
     *
407
     * The namespace prefix will make the names of the actual metadata files a bit shorter. For example, let's assume
408
     * that you have a directory where you only store metadata files for the ``MyApplication\Entity`` namespace.
409
     *
410 3
     * If you use an empty prefix, your metadata files would need to look like:
411
     *
412 3
     * ``my-dir/MyApplication.Entity.SomeObject.yml``
413 3
     * ``my-dir/MyApplication.Entity.OtherObject.xml``
414
     *
415
     * If you use ``MyApplication\Entity`` as prefix, your metadata files would need to look like:
416
     *
417
     * ``my-dir/SomeObject.yml``
418
     * ``my-dir/OtherObject.yml``
419
     *
420
     * Please keep in mind that you currently may only have one directory per namespace prefix.
421
     *
422 3
     * @param string $dir             The directory where metadata files are located.
423
     * @param string $namespacePrefix An optional prefix if you only store metadata for specific namespaces in this directory.
424
     *
425
     * @return SerializerBuilder
426
     *
427
     * @throws InvalidArgumentException When a directory does not exist.
428
     * @throws InvalidArgumentException When a directory has already been registered.
429
     */
430
    public function addMetadataDir(string $dir, string $namespacePrefix = ''): self
431 330
    {
432
        if (!is_dir($dir)) {
433 330
            throw new InvalidArgumentException(sprintf('The directory "%s" does not exist.', $dir));
434 330
        }
435 330
436
        if (isset($this->metadataDirs[$namespacePrefix])) {
437 330
            throw new InvalidArgumentException(sprintf('There is already a directory configured for the namespace prefix "%s". Please use replaceMetadataDir() to override directories.', $namespacePrefix));
438 1
        }
439 1
440 1
        $this->metadataDirs[$namespacePrefix] = $dir;
441
442
        return $this;
443
    }
444 330
445 318
    /**
446 318
     * Adds a map of namespace prefixes to directories.
447
     *
448
     * @param array <string,string> $namespacePrefixToDirMap
0 ignored issues
show
Documentation Bug introduced by
The doc comment <string,string> at position 0 could not be parsed: Unknown type name '<' at position 0 in <string,string>.
Loading history...
449 330
     *
450 330
     * @return SerializerBuilder
451
     */
452 330
    public function addMetadataDirs(array $namespacePrefixToDirMap): self
453
    {
454 330
        foreach ($namespacePrefixToDirMap as $prefix => $dir) {
455
            $this->addMetadataDir($dir, $prefix);
456 330
        }
457 1
458 1
        return $this;
459
    }
460
461 330
    /**
462 71
     * Similar to addMetadataDir(), but overrides an existing entry.
463
     *
464
     * @return SerializerBuilder
465 330
     *
466 73
     * @throws InvalidArgumentException When a directory does not exist.
467
     * @throws InvalidArgumentException When no directory is configured for the ns prefix.
468
     */
469 330
    public function replaceMetadataDir(string $dir, string $namespacePrefix = ''): self
470 329
    {
471 329
        if (!is_dir($dir)) {
472
            throw new InvalidArgumentException(sprintf('The directory "%s" does not exist.', $dir));
473
        }
474 330
475 330
        if (!isset($this->metadataDirs[$namespacePrefix])) {
476
            throw new InvalidArgumentException(sprintf('There is no directory configured for namespace prefix "%s". Please use addMetadataDir() for adding new directories.', $namespacePrefix));
477
        }
478 330
479 330
        $this->metadataDirs[$namespacePrefix] = $dir;
480 330
481 330
        return $this;
482 330
    }
483 330
484 330
    public function setMetadataDriverFactory(DriverFactoryInterface $driverFactory): self
485 330
    {
486
        $this->driverFactory = $driverFactory;
487
488 330
        return $this;
489
    }
490
491 330
    /**
492
     * @param SerializationContextFactoryInterface|callable $serializationContextFactory
493 330
     */
494 330
    public function setSerializationContextFactory($serializationContextFactory): self
495 330
    {
496 330
        if ($serializationContextFactory instanceof SerializationContextFactoryInterface) {
497 330
            $this->serializationContextFactory = $serializationContextFactory;
498 330
        } elseif (is_callable($serializationContextFactory)) {
499
            $this->serializationContextFactory = new CallableSerializationContextFactory(
500
                $serializationContextFactory
501
            );
502 330
        } else {
503
            throw new InvalidArgumentException('expected SerializationContextFactoryInterface or callable.');
504 330
        }
505 330
506 330
        return $this;
507 330
    }
508 330
509 330
    /**
510 330
     * @param DeserializationContextFactoryInterface|callable $deserializationContextFactory
511
     */
512
    public function setDeserializationContextFactory($deserializationContextFactory): self
513
    {
514 318
        if ($deserializationContextFactory instanceof DeserializationContextFactoryInterface) {
515
            $this->deserializationContextFactory = $deserializationContextFactory;
516 318
        } elseif (is_callable($deserializationContextFactory)) {
517
            $this->deserializationContextFactory = new CallableDeserializationContextFactory(
518
                $deserializationContextFactory
519
            );
520 318
        } else {
521 318
            throw new InvalidArgumentException('expected DeserializationContextFactoryInterface or callable.');
522
        }
523 1
524
        return $this;
525 1
    }
526
527
    public function enableEnumSupport(bool $enableEnumSupport = true): void
528
    {
529 1
        if ($enableEnumSupport && PHP_VERSION_ID < 80100) {
530
            throw new InvalidArgumentException('Enum support can be enabled only on PHP 8.1 or higher.');
531
        }
532 1
533
        $this->enableEnumSupport = $enableEnumSupport;
534
    }
535
536
    public function setMetadataCache(CacheInterface $cache): self
537
    {
538
        $this->metadataCache = $cache;
539
540
        return $this;
541
    }
542
543
    public function setDocBlockTypeResolver(bool $docBlockTypeResolver): self
544
    {
545
        $this->docBlockTyperResolver = $docBlockTypeResolver;
546
547
        return $this;
548
    }
549
550
    public function build(): Serializer
551
    {
552
        $annotationReader = $this->annotationReader;
553
        if (null === $annotationReader) {
554
            $annotationReader = new AnnotationReader();
555
            $annotationReader = $this->decorateAnnotationReader($annotationReader);
556
        }
557
558
        if (null === $this->driverFactory) {
559
            $this->initializePropertyNamingStrategy();
560
            $this->driverFactory = new DefaultDriverFactory(
561
                $this->propertyNamingStrategy,
562
                $this->typeParser,
563
                $this->expressionEvaluator instanceof CompilableExpressionEvaluatorInterface ? $this->expressionEvaluator : null
564
            );
565
            $this->driverFactory->enableEnumSupport($this->enableEnumSupport);
566
        }
567
568
        if ($this->docBlockTyperResolver) {
569
            $this->driverFactory = new DocBlockDriverFactory($this->driverFactory, $this->typeParser);
570
        }
571
572
        $metadataDriver = $this->driverFactory->createDriver($this->metadataDirs, $annotationReader);
573
        $metadataFactory = new MetadataFactory($metadataDriver, null, $this->debug);
574
575
        $metadataFactory->setIncludeInterfaces($this->includeInterfaceMetadata);
576
577
        if (null !== $this->metadataCache) {
578
            $metadataFactory->setCache($this->metadataCache);
579
        } elseif (null !== $this->cacheDir) {
580
            $this->createDir($this->cacheDir . '/metadata');
581
            $metadataFactory->setCache(new FileCache($this->cacheDir . '/metadata'));
582
        }
583
584
        if (!$this->handlersConfigured) {
585
            $this->addDefaultHandlers();
586
        }
587
588
        if (!$this->listenersConfigured) {
589
            $this->addDefaultListeners();
590
        }
591
592
        if (!$this->serializationVisitorsAdded) {
593
            $this->addDefaultSerializationVisitors();
594
        }
595
596
        if (!$this->deserializationVisitorsAdded) {
597
            $this->addDefaultDeserializationVisitors();
598
        }
599
600
        $navigatorFactories = [
601
            GraphNavigatorInterface::DIRECTION_SERIALIZATION => $this->getSerializationNavigatorFactory($metadataFactory),
602
            GraphNavigatorInterface::DIRECTION_DESERIALIZATION => $this->getDeserializationNavigatorFactory($metadataFactory),
603
        ];
604
605
        return new Serializer(
606
            $metadataFactory,
607
            $navigatorFactories,
608
            $this->serializationVisitors,
609
            $this->deserializationVisitors,
610
            $this->serializationContextFactory,
611
            $this->deserializationContextFactory,
612
            $this->typeParser
613
        );
614
    }
615
616
    private function getSerializationNavigatorFactory(MetadataFactoryInterface $metadataFactory): GraphNavigatorFactoryInterface
617
    {
618
        return new SerializationGraphNavigatorFactory(
619
            $metadataFactory,
620
            $this->handlerRegistry,
621
            $this->getAccessorStrategy(),
622
            $this->eventDispatcher,
623
            $this->expressionEvaluator
624
        );
625
    }
626
627
    private function getDeserializationNavigatorFactory(MetadataFactoryInterface $metadataFactory): GraphNavigatorFactoryInterface
628
    {
629
        return new DeserializationGraphNavigatorFactory(
630
            $metadataFactory,
631
            $this->handlerRegistry,
632
            $this->objectConstructor ?: new UnserializeObjectConstructor(),
633
            $this->getAccessorStrategy(),
634
            $this->eventDispatcher,
635
            $this->expressionEvaluator
636
        );
637
    }
638
639
    private function initializePropertyNamingStrategy(): void
640
    {
641
        if (null !== $this->propertyNamingStrategy) {
642
            return;
643
        }
644
645
        $this->propertyNamingStrategy = new SerializedNameAnnotationStrategy(new CamelCaseNamingStrategy());
646
    }
647
648
    private function createDir(string $dir): void
649
    {
650
        if (is_dir($dir)) {
651
            return;
652
        }
653
654
        if (false === @mkdir($dir, 0777, true) && false === is_dir($dir)) {
655
            throw new RuntimeException(sprintf('Could not create directory "%s".', $dir));
656
        }
657
    }
658
659
    private function decorateAnnotationReader(Reader $annotationReader): Reader
660
    {
661
        if (null !== $this->cacheDir) {
662
            $this->createDir($this->cacheDir . '/annotations');
663
            if (class_exists(FilesystemAdapter::class)) {
664
                $annotationsCache = new FilesystemAdapter('', 0, $this->cacheDir . '/annotations');
665
                $annotationReader = new PsrCachedReader($annotationReader, $annotationsCache, $this->debug);
666
            } elseif (class_exists(FilesystemCache::class) && class_exists(CachedReader::class)) {
667
                $annotationsCache = new FilesystemCache($this->cacheDir . '/annotations');
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\Common\Cache\FilesystemCache has been deprecated: Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0 ( Ignorable by Annotation )

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

667
                $annotationsCache = /** @scrutinizer ignore-deprecated */ new FilesystemCache($this->cacheDir . '/annotations');
Loading history...
668
                $annotationReader = new CachedReader($annotationReader, $annotationsCache, $this->debug);
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\Common\Annotations\CachedReader has been deprecated: the CachedReader is deprecated and will be removed in version 2.0.0 of doctrine/annotations. Please use the {@see \Doctrine\Common\Annotations\PsrCachedReader} instead. ( Ignorable by Annotation )

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

668
                $annotationReader = /** @scrutinizer ignore-deprecated */ new CachedReader($annotationReader, $annotationsCache, $this->debug);
Loading history...
669
            }
670
        }
671
672
        return $annotationReader;
673
    }
674
}
675