Issues (218)

src/Metadata/Driver/EnumPropertiesDriver.php (2 issues)

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
34
        if (null === $classMetadata) {
35
            return null;
36
        }
37
38
        \assert($classMetadata instanceof SerializerClassMetadata);
39
40
        // We base our scan on the internal driver's property list so that we
41
        // respect any internal allow/blocklist like in the AnnotationDriver
42
        foreach ($classMetadata->propertyMetadata as $propertyMetadata) {
43
            // If the inner driver provides a type, don't guess anymore.
44
            if ($propertyMetadata->type || $this->isVirtualProperty($propertyMetadata)) {
45
                continue;
46
            }
47
48
            try {
49
                $propertyReflection = $this->getReflection($propertyMetadata);
50
                if ($enum = $this->getEnumReflection($propertyReflection)) {
51
                    $serializerType = [
52
                        'name' => 'enum',
53
                        'params' => [
54
                            ['name' => $enum->getName(), 'params' => []],
0 ignored issues
show
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

54
                            ['name' => $enum->/** @scrutinizer ignore-call */ getName(), 'params' => []],

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...
55
                            $enum->isBacked() ? 'value' : 'name',
0 ignored issues
show
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

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