Completed
Push — master ( 7da3fd...970dd0 )
by Julián
02:33
created

AbstractEnum::__unserialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/*
4
 * enum (https://github.com/phpgears/enum).
5
 * Enum object for PHP.
6
 *
7
 * @license MIT
8
 * @link https://github.com/phpgears/enum
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
declare(strict_types=1);
13
14
namespace Gears\Enum;
15
16
use Gears\Enum\Exception\EnumException;
17
use Gears\Enum\Exception\InvalidEnumNameException;
18
use Gears\Enum\Exception\InvalidEnumValueException;
19
use Gears\Immutability\ImmutabilityBehaviour;
20
21
/**
22
 * Base immutable enum class.
23
 */
24
abstract class AbstractEnum implements Enum
25
{
26
    use ImmutabilityBehaviour;
27
28
    /**
29
     * Enum class constants map.
30
     *
31
     * @var array
32
     */
33
    protected static $enumCacheMap = [];
34
35
    /**
36
     * Enum value.
37
     *
38
     * @var mixed
39
     */
40
    private $value;
41
42
    /**
43
     * AbstractEnum constructor.
44
     *
45
     * @param mixed $value
46
     *
47
     * @throws InvalidEnumValueException
48
     */
49
    final public function __construct($value)
50
    {
51
        $this->assertImmutable();
52
53
        $this->checkValue($value);
54
55
        $this->value = $value;
56
    }
57
58
    /**
59
     * Value based static constructor.
60
     *
61
     * @param string  $name
62
     * @param mixed[] $params
63
     *
64
     * @return self
65
     */
66
    final public static function __callStatic(string $name, array $params)
67
    {
68
        if (\count($params) !== 0) {
69
            throw new EnumException('Enum static constructor must be called with no parameters');
70
        }
71
72
        $enumerator = static::normalizeName($name);
73
        $enumerators = static::getEnumerators();
74
75
        if (!\array_key_exists($enumerator, $enumerators)) {
76
            throw new InvalidEnumNameException(\sprintf(
77
                '"%s" is not a valid enumerator for enum "%s"',
78
                $name,
79
                static::class
80
            ));
81
        }
82
83
        return new static($enumerators[$enumerator]);
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    final public function isEqualTo(Enum $enum): bool
90
    {
91
        return \get_class($enum) === static::class && $enum->getValue() === $this->value;
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    final public function isAnyOf(array $enums): bool
98
    {
99
        foreach ($enums as $enum) {
100
            if ($this->isEqualTo($enum)) {
101
                return true;
102
            }
103
        }
104
105
        return false;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111
    final public function getValue()
112
    {
113
        return $this->value;
114
    }
115
116
    /**
117
     * @return mixed[]
118
     */
119
    final public function __sleep(): array
120
    {
121
        throw new EnumException(\sprintf('Enum "%s" cannot be serialized', static::class));
122
    }
123
124
    final public function __wakeup(): void
125
    {
126
        throw new EnumException(\sprintf('Enum "%s" cannot be unserialized', static::class));
127
    }
128
129
    /**
130
     * @return mixed[]
131
     *
132
     * @SuppressWarnings(PHPMD.CamelCaseMethodName)
133
     */
134
    final public function __serialize(): array
135
    {
136
        throw new EnumException(\sprintf('Enum "%s" cannot be serialized', static::class));
137
    }
138
139
    /**
140
     * @SuppressWarnings(PHPMD.CamelCaseMethodName)
141
     */
142
    final public function __unserialize(): void
143
    {
144
        throw new EnumException(\sprintf('Enum "%s" cannot be unserialized', static::class));
145
    }
146
147
    /**
148
     * Check enum value validity.
149
     *
150
     * @param mixed $value
151
     *
152
     * @throws InvalidEnumValueException
153
     */
154
    private function checkValue($value): void
155
    {
156
        if (!\in_array($value, static::getEnumerators(), true)) {
157
            throw new InvalidEnumValueException(\sprintf(
158
                '"%s" is not a valid value for enum "%s"',
159
                $value,
160
                static::class
161
            ));
162
        }
163
    }
164
165
    /**
166
     * Get list of enumerators.
167
     *
168
     * @return array<string, mixed>
169
     */
170
    private static function getEnumerators(): array
171
    {
172
        $class = static::class;
173
174
        if (!isset(static::$enumCacheMap[$class])) {
175
            $constants = [];
176
            foreach ((new \ReflectionClass($class))->getReflectionConstants() as $reflectionConstant) {
177
                if ($reflectionConstant->isPublic()) {
178
                    $constants[static::normalizeName($reflectionConstant->getName())] = $reflectionConstant->getValue();
179
                }
180
            }
181
182
            static::$enumCacheMap[$class] = $constants;
183
        }
184
185
        return static::$enumCacheMap[$class];
186
    }
187
188
    /**
189
     * Normalize name.
190
     *
191
     * @param string $name
192
     *
193
     * @return string
194
     */
195
    private static function normalizeName(string $name): string
196
    {
197
        return \strtoupper($name);
198
    }
199
200
    /**
201
     * {@inheritdoc}
202
     *
203
     * @return string[]
204
     */
205
    final protected function getAllowedInterfaces(): array
206
    {
207
        return [Enum::class];
208
    }
209
}
210