Passed
Push — master ( 84bf0f...c60b29 )
by Marc
43s queued 16s
created

EnumSerializableTrait::__unserialize()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 8.0069

Importance

Changes 0
Metric Value
cc 8
eloc 19
nc 6
nop 1
dl 0
loc 30
ccs 20
cts 21
cp 0.9524
crap 8.0069
rs 8.4444
c 0
b 0
f 0
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 2019 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
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
36
     */
37 1
    public function __serialize(): array
0 ignored issues
show
Coding Style introduced by
Method name "EnumSerializableTrait::__serialize" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
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
@throws tag comment must end with a full stop
Loading history...
47
     * @throws LogicException   On calling this method on an already initialized enumerator
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
48
     *
49
     * @param array $data
0 ignored issues
show
Documentation introduced by
Missing parameter comment
Loading history...
50
     * @return void
51
     */
52 8
    public function __unserialize(array $data): void
0 ignored issues
show
Coding Style introduced by
Method name "EnumSerializableTrait::__unserialize" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
53
    {
54 8
        if (!\array_key_exists('value', $data)) {
55
            throw new RuntimeException('Missing array key "value"');
56
        }
57
58 8
        $value     = $data['value'];
59 8
        $constants = self::getConstants();
60 8
        $name      = \array_search($value, $constants, true);
61 8
        if ($name === false) {
62 2
            $message = \is_scalar($value)
63 1
                ? 'Unknown value ' . \var_export($value, true)
64 2
                : 'Invalid value of type ' . (\is_object($value) ? \get_class($value) : \gettype($value));
65 2
            throw new RuntimeException($message);
66
        }
67
68 6
        $class      = static::class;
69 6
        $enumerator = $this;
70 6
        $closure    = function () use ($class, $name, $value, $enumerator) {
71 6
            if ($value !== null && $this->value !== null) {
72 1
                throw new LogicException('Do not call this directly - please use unserialize($enum) instead');
73
            }
74
75 5
            $this->value = $value;
0 ignored issues
show
Bug Best Practice introduced by
The property value does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
76
77 5
            if (!isset(self::$instances[$class][$name])) {
78 2
                self::$instances[$class][$name] = $enumerator;
0 ignored issues
show
Bug Best Practice introduced by
The property instances does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
79
            }
80 6
        };
81 6
        $closure->bindTo($this, Enum::class)();
82 5
    }
83
84
    /**
85
     * Serialize the value of the enumeration
86
     * This will be called automatically on `serialize()` if the enumeration implements the `Serializable` interface
87
     *
88
     * @return string
89
     * @deprecated Since PHP 7.4
90
     */
91 4
    public function serialize(): string
92
    {
93 4
        return \serialize($this->getValue());
94
    }
95
96
    /**
97
     * Unserializes a given serialized value and push it into the current instance
98
     * This will be called automatically on `unserialize()` if the enumeration implements the `Serializable` interface
99
     * @param string $serialized
0 ignored issues
show
Documentation introduced by
Missing parameter comment
Loading history...
100
     * @return void
101
     * @throws RuntimeException On an unknown or invalid value
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
102
     * @throws LogicException   On calling this method on an already initialized enumerator
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
103
     * @deprecated Since PHP 7.4
104
     */
105 7
    public function unserialize($serialized): void
0 ignored issues
show
Coding Style introduced by
Type hint "string" missing for $serialized
Loading history...
106
    {
107 7
        $this->__unserialize(['value' => \unserialize($serialized)]);
108 5
    }
109
}
110