|
3 | 3 | namespace MabeEnum;
|
4 | 4 |
|
5 | 5 | use SplObjectStorage;
|
| 6 | +use InvalidArgumentException; |
6 | 7 |
|
7 | 8 | class EnumMap extends SplObjectStorage
|
8 | 9 | {
|
9 | 10 |
|
10 | 11 | public function __construct($enumClass)
|
11 | 12 | {
|
| 13 | + if (!is_subclass_of($enumClass, 'MabeEnum\Enum')) { |
| 14 | + throw new InvalidArgumentException( |
| 15 | + "This EnumMap can only handle subclasses of 'MabeEnum\Enum'" |
| 16 | + ); |
| 17 | + } |
12 | 18 | $this->enumClass = $enumClass;
|
13 | 19 | }
|
14 | 20 |
|
15 | 21 | public function attach($enum, $data = null)
|
16 | 22 | {
|
17 |
| - if (!($enum instanceof $this->enumClass)) { |
18 |
| - $enum = call_user_func(array($this->enumClass, 'get'), $enum); |
19 |
| - } |
20 |
| - |
| 23 | + $this->initEnum($enum); |
21 | 24 | parent::attach($enum, $data);
|
22 | 25 | }
|
23 | 26 |
|
24 | 27 | public function contains($enum)
|
25 | 28 | {
|
26 |
| - if (!($enum instanceof $this->enumClass)) { |
27 |
| - $enum = call_user_func(array($this->enumClass, 'get'), $enum); |
28 |
| - } |
29 |
| - |
| 29 | + $this->initEnum($enum); |
30 | 30 | return parent::contains($enum);
|
31 | 31 | }
|
32 | 32 |
|
33 | 33 | public function detach($enum)
|
34 | 34 | {
|
35 |
| - if (!($enum instanceof $this->enumClass)) { |
36 |
| - $enum = call_user_func(array($this->enumClass, 'get'), $enum); |
37 |
| - } |
38 |
| - |
| 35 | + $this->initEnum($enum); |
39 | 36 | parent::detach($enum);
|
40 | 37 | }
|
41 | 38 |
|
42 | 39 | public function getHash($enum)
|
43 | 40 | {
|
44 |
| - if (!($enum instanceof $this->enumClass)) { |
45 |
| - $enum = call_user_func(array($this->enumClass, 'get'), $enum); |
46 |
| - } |
47 |
| - |
| 41 | + $this->initEnum($enum); |
48 | 42 | return parent::getHash($enum);
|
49 | 43 | }
|
50 | 44 |
|
51 | 45 | public function offsetExists($enum)
|
52 | 46 | {
|
53 |
| - if (!($enum instanceof $this->enumClass)) { |
54 |
| - $enum = call_user_func(array($this->enumClass, 'get'), $enum); |
55 |
| - } |
56 |
| - |
| 47 | + $this->initEnum($enum); |
57 | 48 | return parent::offsetExists($enum);
|
58 | 49 | }
|
59 | 50 |
|
60 | 51 | public function offsetGet($enum)
|
61 | 52 | {
|
62 |
| - if (!($enum instanceof $this->enumClass)) { |
63 |
| - $enum = call_user_func(array($this->enumClass, 'get'), $enum); |
64 |
| - } |
65 |
| - |
| 53 | + $this->initEnum($enum); |
66 | 54 | return parent::offsetGet($enum);
|
67 | 55 | }
|
68 | 56 |
|
69 | 57 | public function offsetSet($enum, $data = null)
|
70 | 58 | {
|
71 |
| - if (!($enum instanceof $this->enumClass)) { |
72 |
| - $enum = call_user_func(array($this->enumClass, 'get'), $enum); |
73 |
| - } |
74 |
| - |
| 59 | + $this->initEnum($enum); |
75 | 60 | parent::offsetSet($enum, $data);
|
76 | 61 | }
|
77 | 62 |
|
78 | 63 | public function offsetUnset($enum)
|
79 | 64 | {
|
80 |
| - if (!($enum instanceof $this->enumClass)) { |
81 |
| - $enum = call_user_func(array($this->enumClass, 'get'), $enum); |
| 65 | + $this->initEnum($enum); |
| 66 | + parent::offsetUnset($enum, $data); |
| 67 | + } |
| 68 | + |
| 69 | + private function initEnum(&$enum) |
| 70 | + { |
| 71 | + // auto instantiate |
| 72 | + if (is_scalar($enum)) { |
| 73 | + $enumClass = $this->enumClass; |
| 74 | + $enum = $enumClass::get($enum); |
| 75 | + return; |
82 | 76 | }
|
83 | 77 |
|
84 |
| - parent::offsetUnset($enum, $data); |
| 78 | + // allow only enums of the same type |
| 79 | + // (don't allow instance of) |
| 80 | + $enumClass = get_class($enum); |
| 81 | + if ($enumClass && strcasecmp($enumClass, $this->enumClass) === 0) { |
| 82 | + return; |
| 83 | + } |
| 84 | + |
| 85 | + throw new InvalidArgumentException(sprintf( |
| 86 | + "The given enum of type '%s' isn't same as the required type '%s'", |
| 87 | + get_class($enum) ?: gettype($enum), |
| 88 | + $this->enumClass |
| 89 | + )); |
85 | 90 | }
|
86 | 91 | }
|
0 commit comments