Passed
Pull Request — master (#1448)
by Asmir
02:55
created

EnumPropertiesDriver::loadMetadataForClass()   B

Complexity

Conditions 8
Paths 11

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 8
eloc 15
nc 11
nop 1
dl 0
loc 29
rs 8.4444
c 1
b 0
f 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\ExpressionPropertyMetadata;
9
use JMS\Serializer\Metadata\PropertyMetadata;
10
use JMS\Serializer\Metadata\StaticPropertyMetadata;
11
use JMS\Serializer\Metadata\VirtualPropertyMetadata;
12
use Metadata\ClassMetadata;
13
use Metadata\Driver\DriverInterface;
14
use ReflectionClass;
15
use ReflectionException;
16
use ReflectionProperty;
17
18
class EnumPropertiesDriver implements DriverInterface
19
{
20
    /**
21
     * @var DriverInterface
22
     */
23
    protected $delegate;
24
25
    public function __construct(DriverInterface $delegate)
26
    {
27
        $this->delegate = $delegate;
28
    }
29
30
    public function loadMetadataForClass(ReflectionClass $class): ?ClassMetadata
31
    {
32
        $classMetadata = $this->delegate->loadMetadataForClass($class);
33
        \assert($classMetadata instanceof SerializerClassMetadata);
34
35
        if (null === $classMetadata) {
36
            return null;
37
        }
38
39
        // We base our scan on the internal driver's property list so that we
40
        // respect any internal white/blacklisting like in the AnnotationDriver
41
        foreach ($classMetadata->propertyMetadata as $propertyMetadata) {
42
            // If the inner driver provides a type, don't guess anymore.
43
            if ($propertyMetadata->type || $this->isVirtualProperty($propertyMetadata)) {
44
                continue;
45
            }
46
47
            try {
48
                $propertyReflection = $this->getReflection($propertyMetadata);
49
                if ($enum = $this->getEnumReflection($propertyReflection)) {
50
                    $serializerType = ['name' => 'enum', 'params' => [$enum->getName(), $enum->isBacked() ? 'value' : 'name']];
0 ignored issues
show
Bug introduced by
The method isBacked() does not exist on ReflectionEnum. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

50
                    $serializerType = ['name' => 'enum', 'params' => [$enum->getName(), $enum->/** @scrutinizer ignore-call */ isBacked() ? 'value' : 'name']];

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method getName() does not exist on ReflectionEnum. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

50
                    $serializerType = ['name' => 'enum', 'params' => [$enum->/** @scrutinizer ignore-call */ getName(), $enum->isBacked() ? 'value' : 'name']];

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
51
                    $propertyMetadata->setType($serializerType);
0 ignored issues
show
introduced by
The method setType() does not exist on Metadata\PropertyMetadata. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

51
                    $propertyMetadata->/** @scrutinizer ignore-call */ 
52
                                       setType($serializerType);
Loading history...
52
                }
53
            } catch (ReflectionException $e) {
54
                continue;
55
            }
56
        }
57
58
        return $classMetadata;
59
    }
60
61
    private function isVirtualProperty(PropertyMetadata $propertyMetadata): bool
62
    {
63
        return $propertyMetadata instanceof VirtualPropertyMetadata
64
            || $propertyMetadata instanceof StaticPropertyMetadata
65
            || $propertyMetadata instanceof ExpressionPropertyMetadata;
66
    }
67
68
    private function getReflection(PropertyMetadata $propertyMetadata): ReflectionProperty
69
    {
70
        return new ReflectionProperty($propertyMetadata->class, $propertyMetadata->name);
71
    }
72
73
    private function getEnumReflection(ReflectionProperty $propertyReflection): ?\ReflectionEnum
74
    {
75
        $reflectionType = $propertyReflection->getType();
76
77
        if (!($reflectionType instanceof \ReflectionNamedType)) {
78
            return null;
79
        }
80
81
        return enum_exists($reflectionType->getName()) ? new \ReflectionEnum($reflectionType->getName()) : null;
82
    }
83
}
84