AbstractEnum::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Arp\Enum;
6
7
/**
8
 * @author  Alex Patterson <[email protected]>
9
 * @package Arp\Enum
10
 */
11
abstract class AbstractEnum implements EnumInterface
12
{
13
    /**
14
     * @var mixed
15
     */
16
    private $value;
17
18
    /**
19
     * @var array<mixed>
20
     */
21
    private static array $constants = [];
22
23
    /**
24
     * @param mixed $value
25
     *
26
     * @throws \InvalidArgumentException
27
     */
28
    public function __construct($value = null)
29
    {
30
        if ($value instanceof EnumInterface) {
31
            $value = $value->getValue();
32
        }
33
34
        $this->setValue($value);
35
    }
36
37
    /**
38
     * @return string|null
39
     */
40
    public function getKey(): ?string
41
    {
42
        return self::getKeyByValue($this->value);
43
    }
44
45
    /**
46
     * Return the current value
47
     *
48
     * @return mixed
49
     */
50
    public function getValue()
51
    {
52
        return $this->value;
53
    }
54
55
    /**
56
     * @param mixed $value
57
     *
58
     * @throws \InvalidArgumentException
59
     */
60
    private function setValue($value): void
61
    {
62
        if (null !== $value && !static::hasValue($value)) {
63
            throw new \InvalidArgumentException(
64
                sprintf(
65
                    'The value \'%s\' for enum class \'%s\' could not be mapped to a valid constant value',
66
                    $value,
67
                    static::class
68
                )
69
            );
70
        }
71
72
        $this->value = $value;
73
    }
74
75
    /**
76
     * Check if a constant key exists
77
     *
78
     * @param string $name
79
     *
80
     * @return bool
81
     */
82
    public static function hasKey(string $name): bool
83
    {
84
        return array_key_exists($name, static::toArray());
85
    }
86
87
    /**
88
     * Check if a constant value exists
89
     *
90
     * @param mixed $value
91
     *
92
     * @return bool
93
     */
94
    public static function hasValue($value): bool
95
    {
96
        return in_array($value, static::toArray(), true);
97
    }
98
99
    /**
100
     * Return a numerically indexed array of the constants names
101
     *
102
     * @return array<int, string>
103
     */
104
    public static function getKeys(): array
105
    {
106
        return array_keys(static::toArray());
107
    }
108
109
    /**
110
     * Return an numerically indexed array of the constants values
111
     *
112
     * @return array<int, string>
113
     */
114
    public static function getValues(): array
115
    {
116
        return array_values(static::toArray());
117
    }
118
119
    /**
120
     * Return a constant key matching the provided $value
121
     *
122
     * @param mixed $value
123
     *
124
     * @return string|null
125
     */
126
    public static function getKeyByValue($value): ?string
127
    {
128
        $key = array_search($value, static::toArray(), true);
129
130
        return (false === $key) ? null : $key;
131
    }
132
133
    /**
134
     * Return a constant value matching $key
135
     *
136
     * @param string $key
137
     *
138
     * @return mixed
139
     */
140
    public static function getValueByKey(string $key)
141
    {
142
        return static::toArray()[$key] ?? null;
143
    }
144
145
    /**
146
     * Return a key value map, with the array keys being the constant names with their associated constant values
147
     *
148
     * @return array<string, mixed>
149
     * @throws \ReflectionException
150
     */
151
    public static function toArray(): array
152
    {
153
        $className = static::class;
154
155
        if (!isset(self::$constants[$className])) {
156
            self::$constants[$className] = (new \ReflectionClass($className))->getConstants();
157
        }
158
159
        return self::$constants[$className];
160
    }
161
}
162