Passed
Pull Request — master (#1400)
by
unknown
05:37 queued 02:43
created

SerializerBuilder   F

Complexity

Total Complexity 70

Size/Duplication

Total Lines 585
Duplicated Lines 0 %

Test Coverage

Coverage 75.9%

Importance

Changes 7
Bugs 0 Features 0
Metric Value
eloc 200
c 7
b 0
f 0
dl 0
loc 585
ccs 148
cts 195
cp 0.759
rs 2.8
wmc 70

35 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 3 1
A getDeserializationNavigatorFactory() 0 9 2
A addDefaultDeserializationVisitors() 0 9 1
A replaceMetadataDir() 0 13 3
A initializePropertyNamingStrategy() 0 7 2
A setDebug() 0 5 1
A getSerializationNavigatorFactory() 0 8 1
A setDeserializationVisitor() 0 6 1
A setMetadataDriverFactory() 0 5 1
A setSerializationVisitor() 0 6 1
A setPropertyNamingStrategy() 0 5 1
D build() 0 62 11
A setAnnotationReader() 0 5 1
A setTypeParser() 0 5 1
A addDefaultListeners() 0 6 1
A setDocBlockTypeResolver() 0 5 1
A decorateAnnotationReader() 0 14 3
A setDeserializationContextFactory() 0 13 3
A __construct() 0 14 5
A includeInterfaceMetadata() 0 5 1
A setMetadataDirs() 0 11 3
A createDir() 0 8 4
A setExpressionEvaluator() 0 5 1
A getAccessorStrategy() 0 7 2
A addMetadataDir() 0 13 3
A setAccessorStrategy() 0 5 1
A addDefaultSerializationVisitors() 0 9 1
A setMetadataCache() 0 5 1
A addDefaultHandlers() 0 9 1
A configureListeners() 0 6 1
A configureHandlers() 0 6 1
A setSerializationContextFactory() 0 13 3
A setCacheDir() 0 13 3
A setObjectConstructor() 0 5 1
A addMetadataDirs() 0 7 2

How to fix   Complexity   

Complex Class

Complex classes like SerializerBuilder often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SerializerBuilder, and based on these observations, apply Extract Interface, too.

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\Exception\InvalidArgumentException;
27
use JMS\Serializer\Exception\RuntimeException;
28
use JMS\Serializer\Expression\CompilableExpressionEvaluatorInterface;
29
use JMS\Serializer\Expression\ExpressionEvaluatorInterface;
30
use JMS\Serializer\GraphNavigator\Factory\DeserializationGraphNavigatorFactory;
31
use JMS\Serializer\GraphNavigator\Factory\GraphNavigatorFactoryInterface;
32
use JMS\Serializer\GraphNavigator\Factory\SerializationGraphNavigatorFactory;
33
use JMS\Serializer\Handler\ArrayCollectionHandler;
34
use JMS\Serializer\Handler\DateHandler;
35
use JMS\Serializer\Handler\HandlerRegistry;
36
use JMS\Serializer\Handler\HandlerRegistryInterface;
37
use JMS\Serializer\Handler\IteratorHandler;
38
use JMS\Serializer\Handler\StdClassHandler;
39
use JMS\Serializer\Naming\CamelCaseNamingStrategy;
40
use JMS\Serializer\Naming\PropertyNamingStrategyInterface;
41
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
42
use JMS\Serializer\Type\Parser;
43
use JMS\Serializer\Type\ParserInterface;
44
use JMS\Serializer\Visitor\Factory\DeserializationVisitorFactory;
45
use JMS\Serializer\Visitor\Factory\JsonDeserializationVisitorFactory;
46
use JMS\Serializer\Visitor\Factory\JsonSerializationVisitorFactory;
47
use JMS\Serializer\Visitor\Factory\SerializationVisitorFactory;
48
use JMS\Serializer\Visitor\Factory\XmlDeserializationVisitorFactory;
49
use JMS\Serializer\Visitor\Factory\XmlSerializationVisitorFactory;
50
use Metadata\Cache\CacheInterface;
51
use Metadata\Cache\FileCache;
52
use Metadata\MetadataFactory;
53
use Metadata\MetadataFactoryInterface;
54
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
55
56
/**
57
 * Builder for serializer instances.
58
 *
59
 * This object makes serializer construction a breeze for projects that do not use
60
 * any special dependency injection container.
61
 *
62
 * @author Johannes M. Schmitt <[email protected]>
63
 */
64
final class SerializerBuilder
65
{
66
    /**
67
     * @var string[]
68
     */
69
    private $metadataDirs = [];
70
71
    /**
72
     * @var HandlerRegistryInterface
73
     */
74
    private $handlerRegistry;
75
76
    /**
77
     * @var bool
78
     */
79
    private $handlersConfigured = false;
80
81
    /**
82
     * @var EventDispatcherInterface
83
     */
84
    private $eventDispatcher;
85
86
    /**
87
     * @var bool
88
     */
89
    private $listenersConfigured = false;
90
91
    /**
92
     * @var ObjectConstructorInterface
93
     */
94
    private $objectConstructor;
95
96 330
    /**
97
     * @var SerializationVisitorFactory[]
98 330
     */
99
    private $serializationVisitors;
100
101 330
    /**
102
     * @var DeserializationVisitorFactory[]
103 330
     */
104 330
    private $deserializationVisitors;
105 330
106 330
    /**
107 330
     * @var bool
108
     */
109 330
    private $deserializationVisitorsAdded = false;
110 284
111
    /**
112 330
     * @var bool
113 284
     */
114
    private $serializationVisitorsAdded = false;
115 330
116
    /**
117
     * @var PropertyNamingStrategyInterface
118
     */
119
    private $propertyNamingStrategy;
120
121
    /**
122
     * @var bool
123 330
     */
124
    private $debug = false;
125 330
126 330
    /**
127
     * @var string
128 330
     */
129
    private $cacheDir;
130
131 25
    /**
132
     * @var AnnotationReader
133 25
     */
134
    private $annotationReader;
135 25
136
    /**
137
     * @var bool
138 1
     */
139
    private $includeInterfaceMetadata = false;
140 1
141
    /**
142 1
     * @var DriverFactoryInterface
143
     */
144
    private $driverFactory;
145
146
    /**
147
     * @var SerializationContextFactoryInterface
148
     */
149
    private $serializationContextFactory;
150
151
    /**
152
     * @var DeserializationContextFactoryInterface
153
     */
154
    private $deserializationContextFactory;
155
156
    /**
157
     * @var ParserInterface
158
     */
159 1
    private $typeParser;
160
161 1
    /**
162 1
     * @var ExpressionEvaluatorInterface
163
     */
164 1
    private $expressionEvaluator;
165
166
    /**
167
     * @var AccessorStrategyInterface
168 1
     */
169
    private $accessorStrategy;
170 1
171
    /**
172
     * @var CacheInterface
173 71
     */
174
    private $metadataCache;
175 71
176 71
    /**
177 71
     * @var bool
178 71
     */
179
    private $docBlockTyperResolver;
180 71
181
    /**
182
     * @param mixed ...$args
183 3
     *
184
     * @return SerializerBuilder
185 3
     */
186 3
    public static function create(...$args): self
187
    {
188 3
        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

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

643
                $annotationsCache = /** @scrutinizer ignore-deprecated */ new FilesystemCache($this->cacheDir . '/annotations');
Loading history...
644
                $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

644
                $annotationReader = /** @scrutinizer ignore-deprecated */ new CachedReader($annotationReader, $annotationsCache, $this->debug);
Loading history...
645
            }
646
        }
647
648
        return $annotationReader;
649
    }
650
}
651