PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.4
Booking for Appointments and Events Calendar – Amelia v2.4.4
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / vendor / dasprid / enum / src / AbstractEnum.php
ameliabooking / vendor / dasprid / enum / src Last commit date
Exception 8 months ago AbstractEnum.php 8 months ago EnumMap.php 8 months ago NullValue.php 8 months ago
AbstractEnum.php
262 lines
1 <?php
2 declare(strict_types = 1);
3
4 namespace DASPRiD\Enum;
5
6 use DASPRiD\Enum\Exception\CloneNotSupportedException;
7 use DASPRiD\Enum\Exception\IllegalArgumentException;
8 use DASPRiD\Enum\Exception\MismatchException;
9 use DASPRiD\Enum\Exception\SerializeNotSupportedException;
10 use DASPRiD\Enum\Exception\UnserializeNotSupportedException;
11 use ReflectionClass;
12
13 abstract class AbstractEnum
14 {
15 /**
16 * @var string
17 */
18 private $name;
19
20 /**
21 * @var int
22 */
23 private $ordinal;
24
25 /**
26 * @var array<string, array<string, static>>
27 */
28 private static $values = [];
29
30 /**
31 * @var array<string, bool>
32 */
33 private static $allValuesLoaded = [];
34
35 /**
36 * @var array<string, array>
37 */
38 private static $constants = [];
39
40 /**
41 * The constructor is private by default to avoid arbitrary enum creation.
42 *
43 * When creating your own constructor for a parameterized enum, make sure to declare it as protected, so that
44 * the static methods are able to construct it. Avoid making it public, as that would allow creation of
45 * non-singleton enum instances.
46 */
47 private function __construct()
48 {
49 }
50
51 /**
52 * Magic getter which forwards all calls to {@see self::valueOf()}.
53 *
54 * @return static
55 */
56 final public static function __callStatic(string $name, array $arguments) : self
57 {
58 return static::valueOf($name);
59 }
60
61 /**
62 * Returns an enum with the specified name.
63 *
64 * The name must match exactly an identifier used to declare an enum in this type (extraneous whitespace characters
65 * are not permitted).
66 *
67 * @return static
68 * @throws IllegalArgumentException if the enum has no constant with the specified name
69 */
70 final public static function valueOf(string $name) : self
71 {
72 if (isset(self::$values[static::class][$name])) {
73 return self::$values[static::class][$name];
74 }
75
76 $constants = self::constants();
77
78 if (array_key_exists($name, $constants)) {
79 return self::createValue($name, $constants[$name][0], $constants[$name][1]);
80 }
81
82 throw new IllegalArgumentException(sprintf('No enum constant %s::%s', static::class, $name));
83 }
84
85 /**
86 * @return static
87 */
88 private static function createValue(string $name, int $ordinal, array $arguments) : self
89 {
90 $instance = new static(...$arguments);
91 $instance->name = $name;
92 $instance->ordinal = $ordinal;
93 self::$values[static::class][$name] = $instance;
94 return $instance;
95 }
96
97 /**
98 * Obtains all possible types defined by this enum.
99 *
100 * @return static[]
101 */
102 final public static function values() : array
103 {
104 if (isset(self::$allValuesLoaded[static::class])) {
105 return self::$values[static::class];
106 }
107
108 if (! isset(self::$values[static::class])) {
109 self::$values[static::class] = [];
110 }
111
112 foreach (self::constants() as $name => $constant) {
113 if (array_key_exists($name, self::$values[static::class])) {
114 continue;
115 }
116
117 static::createValue($name, $constant[0], $constant[1]);
118 }
119
120 uasort(self::$values[static::class], function (self $a, self $b) {
121 return $a->ordinal() <=> $b->ordinal();
122 });
123
124 self::$allValuesLoaded[static::class] = true;
125 return self::$values[static::class];
126 }
127
128 private static function constants() : array
129 {
130 if (isset(self::$constants[static::class])) {
131 return self::$constants[static::class];
132 }
133
134 self::$constants[static::class] = [];
135 $reflectionClass = new ReflectionClass(static::class);
136 $ordinal = -1;
137
138 foreach ($reflectionClass->getReflectionConstants() as $reflectionConstant) {
139 if (! $reflectionConstant->isProtected()) {
140 continue;
141 }
142
143 $value = $reflectionConstant->getValue();
144
145 self::$constants[static::class][$reflectionConstant->name] = [
146 ++$ordinal,
147 is_array($value) ? $value : []
148 ];
149 }
150
151 return self::$constants[static::class];
152 }
153
154 /**
155 * Returns the name of this enum constant, exactly as declared in its enum declaration.
156 *
157 * Most programmers should use the {@see self::__toString()} method in preference to this one, as the toString
158 * method may return a more user-friendly name. This method is designed primarily for use in specialized situations
159 * where correctness depends on getting the exact name, which will not vary from release to release.
160 */
161 final public function name() : string
162 {
163 return $this->name;
164 }
165
166 /**
167 * Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial
168 * constant is assigned an ordinal of zero).
169 *
170 * Most programmers will have no use for this method. It is designed for use by sophisticated enum-based data
171 * structures.
172 */
173 final public function ordinal() : int
174 {
175 return $this->ordinal;
176 }
177
178 /**
179 * Compares this enum with the specified object for order.
180 *
181 * Returns negative integer, zero or positive integer as this object is less than, equal to or greater than the
182 * specified object.
183 *
184 * Enums are only comparable to other enums of the same type. The natural order implemented by this method is the
185 * order in which the constants are declared.
186 *
187 * @throws MismatchException if the passed enum is not of the same type
188 */
189 final public function compareTo(self $other) : int
190 {
191 if (! $other instanceof static) {
192 throw new MismatchException(sprintf(
193 'The passed enum %s is not of the same type as %s',
194 get_class($other),
195 static::class
196 ));
197 }
198
199 return $this->ordinal - $other->ordinal;
200 }
201
202 /**
203 * Forbid cloning enums.
204 *
205 * @throws CloneNotSupportedException
206 */
207 final public function __clone()
208 {
209 throw new CloneNotSupportedException();
210 }
211
212 /**
213 * Forbid serializing enums.
214 *
215 * @throws SerializeNotSupportedException
216 */
217 final public function __sleep() : array
218 {
219 throw new SerializeNotSupportedException();
220 }
221
222 /**
223 * Forbid serializing enums.
224 *
225 * @throws SerializeNotSupportedException
226 */
227 final public function __serialize() : array
228 {
229 throw new SerializeNotSupportedException();
230 }
231
232 /**
233 * Forbid unserializing enums.
234 *
235 * @throws UnserializeNotSupportedException
236 */
237 final public function __wakeup() : void
238 {
239 throw new UnserializeNotSupportedException();
240 }
241
242 /**
243 * Forbid unserializing enums.
244 *
245 * @throws UnserializeNotSupportedException
246 */
247 final public function __unserialize($arg) : void
248 {
249 throw new UnserializeNotSupportedException();
250 }
251
252 /**
253 * Turns the enum into a string representation.
254 *
255 * You may override this method to give a more user-friendly version.
256 */
257 public function __toString() : string
258 {
259 return $this->name;
260 }
261 }
262