DefaultDriverFactory::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 1
nop 3
dl 0
loc 5
ccs 0
cts 0
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace JMS\Serializer\Builder;
6
7
use Doctrine\Common\Annotations\Reader;
8
use JMS\Serializer\Exception\RuntimeException;
9
use JMS\Serializer\Expression\CompilableExpressionEvaluatorInterface;
10
use JMS\Serializer\Metadata\Driver\AnnotationOrAttributeDriver;
11
use JMS\Serializer\Metadata\Driver\DefaultValuePropertyDriver;
12
use JMS\Serializer\Metadata\Driver\EnumPropertiesDriver;
13
use JMS\Serializer\Metadata\Driver\NullDriver;
14
use JMS\Serializer\Metadata\Driver\TypedPropertiesDriver;
15
use JMS\Serializer\Metadata\Driver\XmlDriver;
16
use JMS\Serializer\Metadata\Driver\YamlDriver;
17
use JMS\Serializer\Naming\PropertyNamingStrategyInterface;
18
use JMS\Serializer\Type\Parser;
19
use JMS\Serializer\Type\ParserInterface;
20
use Metadata\Driver\DriverChain;
21
use Metadata\Driver\DriverInterface;
22
use Metadata\Driver\FileLocator;
23
use Symfony\Component\Yaml\Yaml;
24
25
final class DefaultDriverFactory implements DriverFactoryInterface
26 330
{
27
    /**
28 330
     * @var ParserInterface
29 330
     */
30 330
    private $typeParser;
31
32 330
    /**
33
     * @var bool
34 330
     */
35 2
    private $enableEnumSupport = false;
36
37 2
    /**
38 2
     * @var PropertyNamingStrategyInterface
39 2
     */
40 2
    private $propertyNamingStrategy;
41
42
    /**
43
     * @var CompilableExpressionEvaluatorInterface
44 330
     */
45
    private $expressionEvaluator;
46
47
    public function __construct(PropertyNamingStrategyInterface $propertyNamingStrategy, ?ParserInterface $typeParser = null, ?CompilableExpressionEvaluatorInterface $expressionEvaluator = null)
48
    {
49
        $this->typeParser = $typeParser ?: new Parser();
50
        $this->propertyNamingStrategy = $propertyNamingStrategy;
51
        $this->expressionEvaluator = $expressionEvaluator;
52
    }
53
54
    public function enableEnumSupport(bool $enableEnumSupport = true): void
55
    {
56
        $this->enableEnumSupport = $enableEnumSupport;
57
    }
58
59
    public function createDriver(array $metadataDirs, ?Reader $annotationReader = null): DriverInterface
60
    {
61
        if (PHP_VERSION_ID < 80000 && empty($metadataDirs) && !interface_exists(Reader::class)) {
62
            throw new RuntimeException(sprintf('To use "%s", either a list of metadata directories must be provided, the "doctrine/annotations" package installed, or use PHP 8.0 or later.', self::class));
63
        }
64
65
        /*
66
         * Build the sorted list of metadata drivers based on the environment. The final order should be:
67
         *
68
         * - YAML Driver
69
         * - XML Driver
70
         * - Annotations/Attributes Driver
71
         * - Null (Fallback) Driver
72
         */
73
        $metadataDrivers = [];
74
75
        if (PHP_VERSION_ID >= 80000 || $annotationReader instanceof Reader) {
76
            $metadataDrivers[] = new AnnotationOrAttributeDriver($this->propertyNamingStrategy, $this->typeParser, $this->expressionEvaluator, $annotationReader);
77
        }
78
79
        if (!empty($metadataDirs)) {
80
            $fileLocator = new FileLocator($metadataDirs);
81
82
            array_unshift($metadataDrivers, new XmlDriver($fileLocator, $this->propertyNamingStrategy, $this->typeParser, $this->expressionEvaluator));
83
84
            if (class_exists(Yaml::class)) {
85
                array_unshift($metadataDrivers, new YamlDriver($fileLocator, $this->propertyNamingStrategy, $this->typeParser, $this->expressionEvaluator));
86
            }
87
        }
88
89
        $driver = new DriverChain($metadataDrivers);
90
        $driver->addDriver(new NullDriver($this->propertyNamingStrategy));
91
92
        if ($this->enableEnumSupport) {
93
            $driver = new EnumPropertiesDriver($driver);
94
        }
95
96
        $driver = new TypedPropertiesDriver($driver, $this->typeParser);
97
98
        if (PHP_VERSION_ID >= 80000) {
99
            $driver = new DefaultValuePropertyDriver($driver);
100
        }
101
102
        return $driver;
103
    }
104
}
105