marc-mabe /
php-enum
| 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 |
||
| 47 | * @throws LogicException On calling this method on an already initialized enumerator |
||
| 48 | * |
||
| 49 | * @param array<string, null|bool|int|float|string|array<mixed>> $data |
||
|
0 ignored issues
–
show
Documentation
introduced
by
Loading history...
|
|||
| 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 |
||
|
0 ignored issues
–
show
|
|||
| 101 | * @return void |
||
| 102 | * @throws RuntimeException On an unknown or invalid value |
||
| 103 | * @throws LogicException On calling this method on an already initialized enumerator |
||
| 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 |