Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
/**
3
 * @link    http://github.com/myclabs/php-enum
4
 * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
5
 */
6
 
7
namespace MyCLabs\Enum;
8
 
9
/**
10
 * Base Enum class
11
 *
12
 * Create an enum by implementing this class and adding class constants.
13
 *
14
 * @author Matthieu Napoli <matthieu@mnapoli.fr>
15
 * @author Daniel Costa <danielcosta@gmail.com>
16
 * @author Mirosław Filip <mirfilip@gmail.com>
17
 *
18
 * @psalm-template T
19
 * @psalm-immutable
20
 * @psalm-consistent-constructor
21
 */
22
abstract class Enum implements \JsonSerializable, \Stringable
23
{
24
    /**
25
     * Enum value
26
     *
27
     * @var mixed
28
     * @psalm-var T
29
     */
30
    protected $value;
31
 
32
    /**
33
     * Enum key, the constant name
34
     *
35
     * @var string
36
     */
37
    private $key;
38
 
39
    /**
40
     * Store existing constants in a static cache per object.
41
     *
42
     *
43
     * @var array
44
     * @psalm-var array<class-string, array<string, mixed>>
45
     */
46
    protected static $cache = [];
47
 
48
    /**
49
     * Cache of instances of the Enum class
50
     *
51
     * @var array
52
     * @psalm-var array<class-string, array<string, static>>
53
     */
54
    protected static $instances = [];
55
 
56
    /**
57
     * Creates a new value of some type
58
     *
59
     * @psalm-pure
60
     * @param mixed $value
61
     *
62
     * @psalm-param T $value
63
     * @throws \UnexpectedValueException if incompatible type is given.
64
     */
65
    public function __construct($value)
66
    {
67
        if ($value instanceof static) {
68
           /** @psalm-var T */
69
            $value = $value->getValue();
70
        }
71
 
72
        /** @psalm-suppress ImplicitToStringCast assertValidValueReturningKey returns always a string but psalm has currently an issue here */
73
        $this->key = static::assertValidValueReturningKey($value);
74
 
75
        /** @psalm-var T */
76
        $this->value = $value;
77
    }
78
 
79
    /**
80
     * This method exists only for the compatibility reason when deserializing a previously serialized version
81
     * that didn't had the key property
82
     */
83
    public function __wakeup()
84
    {
85
        /** @psalm-suppress DocblockTypeContradiction key can be null when deserializing an enum without the key */
86
        if ($this->key === null) {
87
            /**
88
             * @psalm-suppress InaccessibleProperty key is not readonly as marked by psalm
89
             * @psalm-suppress PossiblyFalsePropertyAssignmentValue deserializing a case that was removed
90
             */
91
            $this->key = static::search($this->value);
92
        }
93
    }
94
 
95
    /**
96
     * @param mixed $value
97
     * @return static
98
     */
99
    public static function from($value): self
100
    {
101
        $key = static::assertValidValueReturningKey($value);
102
 
103
        return self::__callStatic($key, []);
104
    }
105
 
106
    /**
107
     * @psalm-pure
108
     * @return mixed
109
     * @psalm-return T
110
     */
111
    public function getValue()
112
    {
113
        return $this->value;
114
    }
115
 
116
    /**
117
     * Returns the enum key (i.e. the constant name).
118
     *
119
     * @psalm-pure
120
     * @return string
121
     */
122
    public function getKey()
123
    {
124
        return $this->key;
125
    }
126
 
127
    /**
128
     * @psalm-pure
129
     * @psalm-suppress InvalidCast
130
     * @return string
131
     */
132
    public function __toString()
133
    {
134
        return (string)$this->value;
135
    }
136
 
137
    /**
138
     * Determines if Enum should be considered equal with the variable passed as a parameter.
139
     * Returns false if an argument is an object of different class or not an object.
140
     *
141
     * This method is final, for more information read https://github.com/myclabs/php-enum/issues/4
142
     *
143
     * @psalm-pure
144
     * @psalm-param mixed $variable
145
     * @return bool
146
     */
147
    final public function equals($variable = null): bool
148
    {
149
        return $variable instanceof self
150
            && $this->getValue() === $variable->getValue()
151
            && static::class === \get_class($variable);
152
    }
153
 
154
    /**
155
     * Returns the names (keys) of all constants in the Enum class
156
     *
157
     * @psalm-pure
158
     * @psalm-return list<string>
159
     * @return array
160
     */
161
    public static function keys()
162
    {
163
        return \array_keys(static::toArray());
164
    }
165
 
166
    /**
167
     * Returns instances of the Enum class of all Enum constants
168
     *
169
     * @psalm-pure
170
     * @psalm-return array<string, static>
171
     * @return static[] Constant name in key, Enum instance in value
172
     */
173
    public static function values()
174
    {
175
        $values = array();
176
 
177
        /** @psalm-var T $value */
178
        foreach (static::toArray() as $key => $value) {
179
            $values[$key] = new static($value);
180
        }
181
 
182
        return $values;
183
    }
184
 
185
    /**
186
     * Returns all possible values as an array
187
     *
188
     * @psalm-pure
189
     * @psalm-suppress ImpureStaticProperty
190
     *
191
     * @psalm-return array<string, mixed>
192
     * @return array Constant name in key, constant value in value
193
     */
194
    public static function toArray()
195
    {
196
        $class = static::class;
197
 
198
        if (!isset(static::$cache[$class])) {
199
            /** @psalm-suppress ImpureMethodCall this reflection API usage has no side-effects here */
200
            $reflection            = new \ReflectionClass($class);
201
            /** @psalm-suppress ImpureMethodCall this reflection API usage has no side-effects here */
202
            static::$cache[$class] = $reflection->getConstants();
203
        }
204
 
205
        return static::$cache[$class];
206
    }
207
 
208
    /**
209
     * Check if is valid enum value
210
     *
211
     * @param $value
212
     * @psalm-param mixed $value
213
     * @psalm-pure
214
     * @psalm-assert-if-true T $value
215
     * @return bool
216
     */
217
    public static function isValid($value)
218
    {
219
        return \in_array($value, static::toArray(), true);
220
    }
221
 
222
    /**
223
     * Asserts valid enum value
224
     *
225
     * @psalm-pure
226
     * @psalm-assert T $value
227
     * @param mixed $value
228
     */
229
    public static function assertValidValue($value): void
230
    {
231
        self::assertValidValueReturningKey($value);
232
    }
233
 
234
    /**
235
     * Asserts valid enum value
236
     *
237
     * @psalm-pure
238
     * @psalm-assert T $value
239
     * @param mixed $value
240
     * @return string
241
     */
242
    private static function assertValidValueReturningKey($value): string
243
    {
244
        if (false === ($key = static::search($value))) {
245
            throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class);
246
        }
247
 
248
        return $key;
249
    }
250
 
251
    /**
252
     * Check if is valid enum key
253
     *
254
     * @param $key
255
     * @psalm-param string $key
256
     * @psalm-pure
257
     * @return bool
258
     */
259
    public static function isValidKey($key)
260
    {
261
        $array = static::toArray();
262
 
263
        return isset($array[$key]) || \array_key_exists($key, $array);
264
    }
265
 
266
    /**
267
     * Return key for value
268
     *
269
     * @param mixed $value
270
     *
271
     * @psalm-param mixed $value
272
     * @psalm-pure
273
     * @return string|false
274
     */
275
    public static function search($value)
276
    {
277
        return \array_search($value, static::toArray(), true);
278
    }
279
 
280
    /**
281
     * Returns a value when called statically like so: MyEnum::SOME_VALUE() given SOME_VALUE is a class constant
282
     *
283
     * @param string $name
284
     * @param array  $arguments
285
     *
286
     * @return static
287
     * @throws \BadMethodCallException
288
     *
289
     * @psalm-pure
290
     */
291
    public static function __callStatic($name, $arguments)
292
    {
293
        $class = static::class;
294
        if (!isset(self::$instances[$class][$name])) {
295
            $array = static::toArray();
296
            if (!isset($array[$name]) && !\array_key_exists($name, $array)) {
297
                $message = "No static method or enum constant '$name' in class " . static::class;
298
                throw new \BadMethodCallException($message);
299
            }
300
            return self::$instances[$class][$name] = new static($array[$name]);
301
        }
302
        return clone self::$instances[$class][$name];
303
    }
304
 
305
    /**
306
     * Specify data which should be serialized to JSON. This method returns data that can be serialized by json_encode()
307
     * natively.
308
     *
309
     * @return mixed
310
     * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
311
     * @psalm-pure
312
     */
313
    #[\ReturnTypeWillChange]
314
    public function jsonSerialize()
315
    {
316
        return $this->getValue();
317
    }
318
}