Completed
Push — EnumMap-IteratorAggregate-Gene... ( aa8b87 )
by Marc
03:33
created

EnumMap::getIterator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MabeEnum;
6
7
use ArrayAccess;
8
use Countable;
9
use InvalidArgumentException;
10
use Iterator;
11
use IteratorAggregate;
12
use OutOfBoundsException;
13
use SeekableIterator;
14
use TypeError;
15
use UnexpectedValueException;
16
17
/**
18
 * A map of enumerators (EnumMap<T>) and mixed values.
19
 *
20
 * @copyright 2019 Marc Bennewitz
21
 * @license http://github.com/marc-mabe/php-enum/blob/master/LICENSE.txt New BSD License
22
 * @link http://github.com/marc-mabe/php-enum for the canonical source repository
23
 */
3 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
24
class EnumMap implements ArrayAccess, Countable, IteratorAggregate
25
{
26
    /**
27
     * The classname of the enumeration type
28
     * @var string
29
     */
30
    private $enumeration;
1 ignored issue
show
Coding Style introduced by
Expected 1 blank line before member var; 0 found
Loading history...
Coding Style introduced by
Private member variable "enumeration" must contain a leading underscore
Loading history...
31
32
    /**
33
     * Internal map of ordinal number and value
34
     * @var array
35
     */
36
    private $map = [];
1 ignored issue
show
Coding Style introduced by
Private member variable "map" must contain a leading underscore
Loading history...
37
38
    /**
39
     * Constructor
40
     * @param string $enumeration The classname of the enumeration type
1 ignored issue
show
introduced by
Parameter comment must end with a full stop
Loading history...
41
     * @throws InvalidArgumentException
0 ignored issues
show
introduced by
Comment missing for @throws tag in function comment
Loading history...
42
     */
43 14
    public function __construct(string $enumeration)
44
    {
45 14
        if (!\is_subclass_of($enumeration, Enum::class)) {
46 1
            throw new InvalidArgumentException(\sprintf(
47 1
                '%s can handle subclasses of %s only',
48 1
                 __CLASS__,
49 1
                Enum::class
50
            ));
51
        }
52 13
        $this->enumeration = $enumeration;
53 13
    }
54
55
    /**
56
     * Get the classname of the enumeration
57
     * @return string
58
     */
59 1
    public function getEnumeration(): string
60
    {
61 1
        return $this->enumeration;
62
    }
63
64
    /**
65
     * Get a list of map keys
66
     * @return Enum[]
67
     */
68 3
    public function getKeys(): array
69
    {
70 3
        return \array_map([$this->enumeration, 'byOrdinal'], \array_keys($this->map));
71
    }
72
73
    /**
74
     * Get a list of map values
75
     * @return mixed[]
76
     */
77 3
    public function getValues(): array
78
    {
79 3
        return \array_values($this->map);
80
    }
81
82
    /**
83
     * Search for the given value
84
     * @param mixed $value
0 ignored issues
show
Documentation introduced by
Missing parameter comment
Loading history...
85
     * @param bool $strict Use strict type comparison
2 ignored issues
show
Coding Style introduced by
Expected "boolean" but found "bool" for parameter type
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
introduced by
Parameter comment must end with a full stop
Loading history...
86
     * @return Enum|null The found key or NULL
87
     */
88 2
    public function search($value, bool $strict = false)
2 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$strict" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$strict"; expected 0 but found 1
Loading history...
89
    {
90 2
        $ord = \array_search($value, $this->map, $strict);
91 2
        if ($ord !== false) {
92 2
            return ($this->enumeration)::byOrdinal($ord);
93
        }
94
95 2
        return null;
96
    }
97
98
    /**
99
     * Test if the given enumerator exists
100
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
101
     * @return bool
1 ignored issue
show
Coding Style introduced by
Expected "boolean" but found "bool" for function return type
Loading history...
102
     * @see offsetExists
103
     */
104 4
    public function contains($enumerator): bool
105
    {
106
        try {
107 4
            $ord = ($this->enumeration)::get($enumerator)->getOrdinal();
108 3
            return \array_key_exists($ord, $this->map);
109 1
        } catch (InvalidArgumentException $e) {
110
            // An invalid enumerator can't be contained in this map
111 1
            return false;
112
        }
113
    }
114
115
    /**
116
     * Test if the given enumerator key exists and is not NULL
117
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
118
     * @return bool
1 ignored issue
show
Coding Style introduced by
Expected "boolean" but found "bool" for function return type
Loading history...
119
     * @see contains
120
     */
121 5
    public function offsetExists($enumerator): bool
122
    {
123
        try {
124 5
            return isset($this->map[($this->enumeration)::get($enumerator)->getOrdinal()]);
125 1
        } catch (InvalidArgumentException $e) {
126
            // An invalid enumerator can't be an offset of this map
127 1
            return false;
128
        }
129
    }
130
131
    /**
132
     * Get mapped data for the given enumerator
133
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
134
     * @return mixed
135
     * @throws InvalidArgumentException On an invalid given enumerator
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
136
     * @throws UnexpectedValueException If the given enumerator does not exist in this map
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
137
     */
138 7
    public function offsetGet($enumerator)
139
    {
140 7
        $enumerator = ($this->enumeration)::get($enumerator);
141 7
        $ord = $enumerator->getOrdinal();
142 7
        if (!isset($this->map[$ord]) && !\array_key_exists($ord, $this->map)) {
143 2
            throw new UnexpectedValueException(sprintf(
144 2
                'Enumerator %s could not be found',
145 2
                \var_export($enumerator->getValue(), true)
146
            ));
147
        }
148
149 5
        return $this->map[$ord];
150
    }
151
152
    /**
153
     * Attach a new enumerator or overwrite an existing one
154
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
155
     * @param mixed                                 $value
0 ignored issues
show
Documentation introduced by
Missing parameter comment
Loading history...
156
     * @return void
157
     * @throws InvalidArgumentException On an invalid given enumerator
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
158
     * @see attach()
159
     */
160 10
    public function offsetSet($enumerator, $value = null): void
2 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$value"; expected 0 but found 1
Loading history...
161
    {
162 10
        $ord = ($this->enumeration)::get($enumerator)->getOrdinal();
163 9
        $this->map[$ord] = $value;
164 9
    }
165
166
    /**
167
     * Detach an existing enumerator
168
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
169
     * @return void
170
     * @throws InvalidArgumentException On an invalid given enumerator
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
171
     * @see detach()
172
     */
173 4
    public function offsetUnset($enumerator): void
174
    {
175 4
        $ord = ($this->enumeration)::get($enumerator)->getOrdinal();
176 4
        unset($this->map[$ord]);
177 4
    }
178
179
    /**
180
     * Get a new Iterator.
181
     *
182
     * @return Iterator
183
     */
184 2
    public function getIterator(): Iterator
185
    {
186 2
        $map = $this->map;
187 2
        foreach ($map as $ordinal => $value) {
188 2
            yield ($this->enumeration)::byOrdinal($ordinal) => $value;
189
        }
190 2
    }
191
192
    /**
193
     * Count the number of elements
194
     *
195
     * @return int
1 ignored issue
show
Coding Style introduced by
Expected "integer" but found "int" for function return type
Loading history...
196
     */
197 2
    public function count(): int
198
    {
199 2
        return \count($this->map);
200
    }
201
}
202