Passed
Pull Request — master (#1417)
by Asmir
02:11
created

DefaultValuePropertyDriver   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 64
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 31
c 1
b 0
f 0
dl 0
loc 64
rs 10
wmc 14

4 Methods

Rating   Name   Duplication   Size   Complexity  
B loadMetadataForClass() 0 42 11
A getClassReflection() 0 3 1
A __construct() 0 3 1
A getPropertyReflection() 0 3 1
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