EnumHandler::serializeEnum()   B
last analyzed

Complexity

Conditions 7
Paths 4

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 7
eloc 7
c 1
b 0
f 1
nc 4
nop 4
dl 0
loc 16
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace JMS\Serializer\Handler;
6
7
use JMS\Serializer\Exception\InvalidMetadataException;
8
use JMS\Serializer\Exception\RuntimeException;
9
use JMS\Serializer\GraphNavigatorInterface;
10
use JMS\Serializer\SerializationContext;
11
use JMS\Serializer\Type\Type;
12
use JMS\Serializer\Visitor\DeserializationVisitorInterface;
13
use JMS\Serializer\Visitor\SerializationVisitorInterface;
14
15
/**
16
 * @phpstan-import-type TypeArray from Type
17
 */
18
final class EnumHandler implements SubscribingHandlerInterface
19
{
20
    /**
21
     * {@inheritdoc}
22
     */
23
    public static function getSubscribingMethods()
24
    {
25
        $methods = [];
26
27
        foreach (['json', 'xml'] as $format) {
28
            $methods[] = [
29
                'type' => 'enum',
30
                'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION,
31
                'format' => $format,
32
                'method' => 'deserializeEnum',
33
            ];
34
            $methods[] = [
35
                'type' => 'enum',
36
                'format' => $format,
37
                'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION,
38
                'method' => 'serializeEnum',
39
            ];
40
        }
41
42
        return $methods;
43
    }
44
45
    /**
46
     * @param TypeArray $type
0 ignored issues
show
Bug introduced by
The type JMS\Serializer\Handler\TypeArray was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
47
     */
48
    public function serializeEnum(
49
        SerializationVisitorInterface $visitor,
0 ignored issues
show
Unused Code introduced by
The parameter $visitor is not used and could be removed. ( Ignorable by Annotation )

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

49
        /** @scrutinizer ignore-unused */ SerializationVisitorInterface $visitor,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
50
        \UnitEnum $enum,
51
        array $type,
52
        SerializationContext $context
53
    ) {
54
        if ((isset($type['params'][1]) && 'value' === $type['params'][1]) || (!isset($type['params'][1]) && $enum instanceof \BackedEnum)) {
55
            if (!$enum instanceof \BackedEnum) {
56
                throw new InvalidMetadataException(sprintf('The type "%s" is not a backed enum, thus you can not use "value" as serialization mode for its value.', get_class($enum)));
57
            }
58
59
            $valueType = isset($type['params'][2]) ? ['name' => $type['params'][2]] : null;
60
61
            return $context->getNavigator()->accept($enum->value, $valueType);
0 ignored issues
show
Bug introduced by
Accessing value on the interface BackedEnum suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
62
        } else {
63
            return $context->getNavigator()->accept($enum->name);
0 ignored issues
show
Bug introduced by
Accessing name on the interface UnitEnum suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
64
        }
65
    }
66
67
    /**
68
     * @param int|string|\SimpleXMLElement $data
69
     * @param TypeArray $type
70
     */
71
    public function deserializeEnum(DeserializationVisitorInterface $visitor, $data, array $type): ?\UnitEnum
0 ignored issues
show
Unused Code introduced by
The parameter $visitor is not used and could be removed. ( Ignorable by Annotation )

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

71
    public function deserializeEnum(/** @scrutinizer ignore-unused */ DeserializationVisitorInterface $visitor, $data, array $type): ?\UnitEnum

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
72
    {
73
        $enumType = $type['params'][0];
74
        if (isset($enumType['name'])) {
75
            $enumType = $enumType['name'];
76
        } else {
77
            trigger_deprecation('jms/serializer', '3.31', "Using enum<'Type'> or similar is deprecated, use enum<Type> instead.");
78
        }
79
80
        $caseValue = (string) $data;
81
82
        $ref = new \ReflectionEnum($enumType);
83
        if (isset($type['params'][1]) && 'value' === $type['params'][1] || (!isset($type['params'][1]) && is_a($enumType, \BackedEnum::class, true))) {
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (IssetNode && 'value' ==...ackedEnum::class, true), Probably Intended Meaning: IssetNode && ('value' ==...ckedEnum::class, true))
Loading history...
84
            if (!is_a($enumType, \BackedEnum::class, true)) {
85
                throw new InvalidMetadataException(sprintf('The type "%s" is not a backed enum, thus you can not use "value" as serialization mode for its value.', $enumType));
86
            }
87
88
            if ('int' === $ref->getBackingType()->getName()) {
0 ignored issues
show
Bug introduced by
The method getBackingType() 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

88
            if ('int' === $ref->/** @scrutinizer ignore-call */ getBackingType()->getName()) {

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...
89
                if (!is_numeric($caseValue)) {
90
                    throw new RuntimeException(sprintf('"%s" is not a valid backing value for enum "%s"', $caseValue, $enumType));
91
                }
92
93
                $caseValue = (int) $caseValue;
94
            }
95
96
            return $enumType::from($caseValue);
97
        } else {
98
            if (!$ref->hasCase($caseValue)) {
0 ignored issues
show
Bug introduced by
The method hasCase() 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

98
            if (!$ref->/** @scrutinizer ignore-call */ hasCase($caseValue)) {

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...
99
                throw new InvalidMetadataException(sprintf('The type "%s" does not have the case "%s"', $ref->getName(), $caseValue));
0 ignored issues
show
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

99
                throw new InvalidMetadataException(sprintf('The type "%s" does not have the case "%s"', $ref->/** @scrutinizer ignore-call */ getName(), $caseValue));

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...
100
            }
101
102
            return $ref->getCase($caseValue)->getValue();
0 ignored issues
show
Bug introduced by
The method getCase() 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

102
            return $ref->/** @scrutinizer ignore-call */ getCase($caseValue)->getValue();

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...
103
        }
104
    }
105
}
106