1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace MabeEnum; |
||
6 | |||
7 | use RuntimeException; |
||
8 | use LogicException; |
||
9 | |||
10 | /** |
||
11 | * Trait to make enumerations serializable |
||
12 | * |
||
13 | * This trait is a workaround to make enumerations serializable. |
||
14 | * |
||
15 | * Please note that this feature breaks singleton behaviour of your enumerations |
||
16 | * if an enumeration will be unserialized after it was instantiated already. |
||
17 | * |
||
18 | * @copyright 2020, Marc Bennewitz |
||
19 | * @license http://github.com/marc-mabe/php-enum/blob/master/LICENSE.txt New BSD License |
||
20 | * @link http://github.com/marc-mabe/php-enum for the canonical source repository |
||
21 | * @link https://github.com/marc-mabe/php-enum/issues/52 for further information about this feature |
||
22 | */ |
||
23 | trait EnumSerializableTrait |
||
24 | { |
||
25 | /** |
||
26 | * The method will be defined by MabeEnum\Enum |
||
27 | * @return null|bool|int|float|string|array<mixed> |
||
28 | */ |
||
29 | abstract public function getValue(); |
||
30 | |||
31 | /** |
||
32 | * Returns an array of data to be serialized. |
||
33 | * This magic method will be called by serialize() in PHP >= 7.4 |
||
34 | * |
||
35 | * @return array<string, null|bool|int|float|string|array<mixed>> |
||
36 | */ |
||
37 | 1 | public function __serialize(): array |
|
38 | { |
||
39 | 1 | return ['value' => $this->getValue()]; |
|
40 | } |
||
41 | |||
42 | /** |
||
43 | * Receives an array of data to be unserialized on a new instance without constructor. |
||
44 | * This magic method will be called in PHP >= 7.4 is the data where serialized with PHP >= 7.4. |
||
45 | * |
||
46 | * @throws RuntimeException On missing, unknown or invalid value |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
47 | * @throws LogicException On calling this method on an already initialized enumerator |
||
0 ignored issues
–
show
|
|||
48 | * |
||
49 | * @param array<string, null|bool|int|float|string|array<mixed>> $data |
||
50 | * @return void |
||
51 | */ |
||
52 | 8 | public function __unserialize(array $data): void |
|
53 | { |
||
54 | 8 | if (!\array_key_exists('value', $data)) { |
|
55 | throw new RuntimeException('Missing array key "value"'); |
||
56 | } |
||
57 | |||
58 | /** @var mixed $value */ |
||
59 | 8 | $value = $data['value']; |
|
60 | 8 | $constants = self::getConstants(); |
|
61 | 8 | $name = \array_search($value, $constants, true); |
|
62 | 8 | if ($name === false) { |
|
63 | 2 | $message = \is_scalar($value) |
|
64 | 1 | ? 'Unknown value ' . \var_export($value, true) |
|
65 | 2 | : 'Invalid value of type ' . (\is_object($value) ? \get_class($value) : \gettype($value)); |
|
66 | 2 | throw new RuntimeException($message); |
|
67 | } |
||
68 | |||
69 | 6 | $class = static::class; |
|
70 | 6 | $enumerator = $this; |
|
71 | 6 | $closure = function () use ($class, $name, $value, $enumerator) { |
|
72 | 6 | if ($value !== null && $this->value !== null) { |
|
73 | 1 | throw new LogicException('Do not call this directly - please use unserialize($enum) instead'); |
|
74 | } |
||
75 | |||
76 | 5 | $this->value = $value; |
|
77 | |||
78 | 5 | if (!isset(self::$instances[$class][$name])) { |
|
79 | 2 | self::$instances[$class][$name] = $enumerator; |
|
80 | } |
||
81 | 6 | }; |
|
82 | 6 | $closure->bindTo($this, Enum::class)(); |
|
83 | 5 | } |
|
84 | |||
85 | /** |
||
86 | * Serialize the value of the enumeration |
||
87 | * This will be called automatically on `serialize()` if the enumeration implements the `Serializable` interface |
||
88 | * |
||
89 | * @return string |
||
90 | * @deprecated Since PHP 7.4 |
||
91 | */ |
||
92 | 4 | public function serialize(): string |
|
93 | { |
||
94 | 4 | return \serialize($this->getValue()); |
|
95 | } |
||
96 | |||
97 | /** |
||
98 | * Unserializes a given serialized value and push it into the current instance |
||
99 | * This will be called automatically on `unserialize()` if the enumeration implements the `Serializable` interface |
||
100 | * @param string $serialized |
||
101 | * @return void |
||
102 | * @throws RuntimeException On an unknown or invalid value |
||
0 ignored issues
–
show
|
|||
103 | * @throws LogicException On calling this method on an already initialized enumerator |
||
0 ignored issues
–
show
|
|||
104 | * @deprecated Since PHP 7.4 |
||
105 | */ |
||
106 | 7 | public function unserialize($serialized): void |
|
107 | { |
||
108 | 7 | $this->__unserialize(['value' => \unserialize($serialized)]); |
|
109 | 5 | } |
|
110 | } |
||
111 |