Passed
Push — master ( c02600...f721ff )
by Asmir
03:18 queued 51s
created

DefaultValuePropertyDriver::getClassReflection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace JMS\Serializer\Metadata\Driver;
6
7
use JMS\Serializer\Metadata\ClassMetadata as SerializerClassMetadata;
8
use JMS\Serializer\Metadata\PropertyMetadata;
9
use Metadata\ClassMetadata;
10
use Metadata\Driver\DriverInterface;
11
use ReflectionClass;
12
use ReflectionException;
13
use ReflectionProperty;
14
15
class DefaultValuePropertyDriver implements DriverInterface
16
{
17
    /**
18
     * @var DriverInterface
19
     */
20
    protected $delegate;
21
22
    public function __construct(DriverInterface $delegate)
23
    {
24
        $this->delegate = $delegate;
25
    }
26
27
    public function loadMetadataForClass(ReflectionClass $class): ?ClassMetadata
28
    {
29
        $classMetadata = $this->delegate->loadMetadataForClass($class);
30
        \assert($classMetadata instanceof SerializerClassMetadata);
31
32
        if (null === $classMetadata) {
33
            return null;
34
        }
35
36
        foreach ($classMetadata->propertyMetadata as $key => $propertyMetadata) {
37
            \assert($propertyMetadata instanceof PropertyMetadata);
38
            if (null !== $propertyMetadata->hasDefault) {
39
                continue;
40
            }
41
42
            try {
43
                $propertyReflection = $this->getPropertyReflection($propertyMetadata);
44
                $propertyMetadata->hasDefault = false;
45
                if ($propertyReflection->hasDefaultValue() && $propertyReflection->hasType()) {
46
                    $propertyMetadata->hasDefault = true;
47
                    $propertyMetadata->defaultValue = $propertyReflection->getDefaultValue();
48
                } elseif ($propertyReflection->isPromoted()) {
49
                    // need to get the parameter in the constructor to check for default values
50
                    $classReflection = $this->getClassReflection($propertyMetadata);
51
                    $params = $classReflection->getConstructor()->getParameters();
52
                    foreach ($params as $parameter) {
53
                        if ($parameter->getName() === $propertyMetadata->name) {
54
                            if ($parameter->isDefaultValueAvailable()) {
55
                                $propertyMetadata->hasDefault = true;
56
                                $propertyMetadata->defaultValue = $parameter->getDefaultValue();
57
                            }
58
59
                            break;
60
                        }
61
                    }
62
                }
63
            } catch (ReflectionException $e) {
64
                continue;
65
            }
66
        }
67
68
        return $classMetadata;
69
    }
70
71
    private function getPropertyReflection(PropertyMetadata $propertyMetadata): ReflectionProperty
72
    {
73
        return new ReflectionProperty($propertyMetadata->class, $propertyMetadata->name);
74
    }
75
76
    private function getClassReflection(PropertyMetadata $propertyMetadata): ReflectionClass
77
    {
78
        return new ReflectionClass($propertyMetadata->class);
79
    }
80
}
81