Completed
Pull Request — master (#1214)
by
unknown
14:01
created

DocBlockDriver::getReflection()   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
nc 1
nop 1
dl 0
loc 3
rs 10
c 1
b 0
f 0
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\ExpressionPropertyMetadata;
9
use JMS\Serializer\Metadata\PropertyMetadata;
10
use JMS\Serializer\Metadata\StaticPropertyMetadata;
11
use JMS\Serializer\Metadata\VirtualPropertyMetadata;
12
use JMS\Serializer\Type\Parser;
13
use JMS\Serializer\Type\ParserInterface;
14
use Metadata\ClassMetadata;
15
use Metadata\Driver\DriverInterface;
16
use ReflectionClass;
17
use ReflectionException;
18
use ReflectionProperty;
19
20
class DocBlockDriver implements DriverInterface
21
{
22
    /**
23
     * @var DriverInterface
24
     */
25
    protected $delegate;
26
27
    /**
28
     * @var ParserInterface
29
     */
30
    protected $typeParser;
31
    /**
32
     * @var DocBlockTypeResolver
33
     */
34
    private $docBlockTypeResolver;
35
36
    public function __construct(DriverInterface $delegate, ?ParserInterface $typeParser = null)
37
    {
38
        $this->delegate = $delegate;
39
        $this->typeParser = $typeParser ?: new Parser();
40
        $this->docBlockTypeResolver = new DocBlockTypeResolver();
41
    }
42
43
    public function loadMetadataForClass(ReflectionClass $class): ?ClassMetadata
44
    {
45
        /** @var SerializerClassMetadata $classMetadata */
46
        $classMetadata = $this->delegate->loadMetadataForClass($class);
47
48
        if (null === $classMetadata) {
49
            return null;
50
        }
51
        // We base our scan on the internal driver's property list so that we
52
        // respect any internal white/blacklisting like in the AnnotationDriver
53
        foreach ($classMetadata->propertyMetadata as $key => $propertyMetadata) {
54
            /** @var $propertyMetadata PropertyMetadata */
55
56
            // If the inner driver provides a type, don't guess anymore.
57
            if ($propertyMetadata->type || $this->isVirtualProperty($propertyMetadata)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $propertyMetadata->type of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
58
                continue;
59
            }
60
61
            try {
62
                $propertyReflection = $this->getReflection($propertyMetadata);
63
64
                $type = $this->docBlockTypeResolver->getPropertyDocblockTypeHint($propertyReflection);
65
                if (!is_null($type)) {
66
                    $propertyMetadata->setType($this->typeParser->parse($type));
67
                }
68
            } catch (ReflectionException $e) {
69
                continue;
70
            }
71
        }
72
73
        return $classMetadata;
74
    }
75
76
    private function isVirtualProperty(PropertyMetadata $propertyMetadata): bool
77
    {
78
        return $propertyMetadata instanceof VirtualPropertyMetadata
79
            || $propertyMetadata instanceof StaticPropertyMetadata
80
            || $propertyMetadata instanceof ExpressionPropertyMetadata;
81
    }
82
83
    private function getReflection(PropertyMetadata $propertyMetadata): ReflectionProperty
84
    {
85
        return new ReflectionProperty($propertyMetadata->class, $propertyMetadata->name);
86
    }
87
}
88