CommandCollection::offsetUnset()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
/*
4
 * This file is part of the webmozart/console package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webmozart\Console\Api\Command;
13
14
use ArrayAccess;
15
use ArrayIterator;
16
use Countable;
17
use IteratorAggregate;
18
use LogicException;
19
20
/**
21
 * A collection of named commands.
22
 *
23
 * @since  1.0
24
 *
25
 * @author Bernhard Schussek <[email protected]>
26
 */
27
class CommandCollection implements ArrayAccess, IteratorAggregate, Countable
28
{
29
    /**
30
     * @var Command[]
31
     */
32
    private $commands = array();
33
34
    /**
35
     * @var string[]
36
     */
37
    private $shortNameIndex = array();
38
39
    /**
40
     * @var string[]
41
     */
42
    private $aliasIndex = array();
43
44
    /**
45
     * Creates a new command collection.
46
     *
47
     * @param Command[] $commands The commands to initially add to the
48
     *                            collection.
49
     */
50 246
    public function __construct(array $commands = array())
51
    {
52 246
        $this->merge($commands);
53 246
    }
54
55
    /**
56
     * Adds a command to the collection.
57
     *
58
     * If a command exists with the same name in the collection, that command
59
     * is overwritten.
60
     *
61
     * @param Command $command The command to add.
62
     *
63
     * @see merge(), replace()
64
     */
65 177
    public function add(Command $command)
66
    {
67 177
        $name = $command->getName();
68
69 177
        $this->commands[$name] = $command;
70
71 177
        if ($shortName = $command->getShortName()) {
72 14
            $this->shortNameIndex[$shortName] = $name;
73
        }
74
75 177
        foreach ($command->getAliases() as $alias) {
76 27
            $this->aliasIndex[$alias] = $name;
77
        }
78
79 177
        ksort($this->aliasIndex);
80 177
    }
81
82
    /**
83
     * Adds multiple commands to the collection.
84
     *
85
     * Existing commands are preserved. Commands with the same names as the
86
     * passed commands are overwritten.
87
     *
88
     * @param Command[] $commands The commands to add.
89
     *
90
     * @see add(), replace()
91
     */
92 246
    public function merge(array $commands)
93
    {
94 246
        foreach ($commands as $command) {
95 28
            $this->add($command);
96
        }
97 246
    }
98
99
    /**
100
     * Sets the commands in the collection.
101
     *
102
     * Existing commands are replaced.
103
     *
104
     * @param Command[] $commands The commands to set.
105
     *
106
     * @see add(), merge()
107
     */
108 1
    public function replace(array $commands)
109
    {
110 1
        $this->clear();
111 1
        $this->merge($commands);
112 1
    }
113
114
    /**
115
     * Returns a command by its name.
116
     *
117
     * @param string $name The name of the command.
118
     *
119
     * @return Command The command.
120
     *
121
     * @throws NoSuchCommandException If no command with that name exists in the
122
     *                                collection.
123
     */
124 295
    public function get($name)
125
    {
126 295
        if (isset($this->commands[$name])) {
127 274
            return $this->commands[$name];
128
        }
129
130 66
        if (isset($this->shortNameIndex[$name])) {
131 20
            return $this->commands[$this->shortNameIndex[$name]];
132
        }
133
134 46
        if (isset($this->aliasIndex[$name])) {
135 43
            return $this->commands[$this->aliasIndex[$name]];
136
        }
137
138 3
        throw NoSuchCommandException::forCommandName($name);
139
    }
140
141
    /**
142
     * Removes the command with the given name from the collection.
143
     *
144
     * If no such command can be found, the method does nothing.
145
     *
146
     * @param string $name The name of the command.
147
     */
148 9
    public function remove($name)
149
    {
150 9
        if (isset($this->aliasIndex[$name])) {
151 1
            $this->remove($this->aliasIndex[$name]);
152
153 1
            return;
154
        }
155
156 9
        if (isset($this->shortNameIndex[$name])) {
157 1
            $this->remove($this->shortNameIndex[$name]);
158
159 1
            return;
160
        }
161
162 9
        unset($this->commands[$name]);
163
164 9
        foreach ($this->shortNameIndex as $shortName => $targetName) {
165 2
            if ($name === $targetName) {
166 2
                unset($this->shortNameIndex[$shortName]);
167
            }
168
        }
169
170 9
        foreach ($this->aliasIndex as $alias => $targetName) {
171 3
            if ($name === $targetName) {
172 3
                unset($this->aliasIndex[$alias]);
173
            }
174
        }
175 9
    }
176
177
    /**
178
     * Returns whether the collection contains a command with the given name.
179
     *
180
     * @param string $name The name of the command.
181
     *
182
     * @return bool Returns `true` if the collection contains a command with
183
     *              that name and `false` otherwise.
184
     */
185 320
    public function contains($name)
186
    {
187 320
        return isset($this->commands[$name]) || isset($this->shortNameIndex[$name]) || isset($this->aliasIndex[$name]);
188
    }
189
190
    /**
191
     * Removes all commands from the collection.
192
     */
193 3
    public function clear()
194
    {
195 3
        $this->commands = array();
196 3
        $this->shortNameIndex = array();
197 3
        $this->aliasIndex = array();
198 3
    }
199
200
    /**
201
     * Returns whether the collection is empty.
202
     *
203
     * @return bool Returns `true` if the collection is empty and `false`
204
     *              otherwise.
205
     */
206 50
    public function isEmpty()
207
    {
208 50
        return !$this->commands;
209
    }
210
211
    /**
212
     * Returns the contents of the collection as array.
213
     *
214
     * The commands in the collection are returned indexed by their names. The
215
     * result is sorted in the order in which the commands were added to the
216
     * collection.
217
     *
218
     * @return Command[] The commands indexed by their names.
219
     */
220 25
    public function toArray()
221
    {
222 25
        return $this->commands;
223
    }
224
225
    public function filterDefault()
226
    {
227
    }
228
229
    public function filterNonDefault()
230
    {
231
    }
232
233
    public function filterAnonymous()
234
    {
235
    }
236
237
    public function filterNonAnonymous()
238
    {
239
    }
240
241
    /**
242
     * Returns the names of all commands in the collection.
243
     *
244
     * The names are sorted alphabetically in ascending order. If you set
245
     * `$includeAliases` to `true`, the alias names are included in the result.
246
     *
247
     * @param bool $includeAliases Whether to include alias names in the result.
248
     *
249
     * @return string[] The sorted command names.
250
     */
251 20
    public function getNames($includeAliases = false)
252
    {
253 20
        $names = array_keys($this->commands);
254
255 20
        if ($includeAliases) {
256 19
            $names = array_merge($names, array_keys($this->aliasIndex));
257
        }
258
259 20
        sort($names);
260
261 20
        return $names;
262
    }
263
264
    /**
265
     * Returns the aliases of all commands in the collection.
266
     *
267
     * The aliases are sorted alphabetically in ascending order.
268
     *
269
     * @return string[] The command names indexed and sorted by their aliases.
270
     */
271 1
    public function getAliases()
272
    {
273 1
        return $this->aliasIndex;
274
    }
275
276
    /**
277
     * {@inheritdoc}
278
     */
279 1
    public function offsetExists($name)
280
    {
281 1
        return $this->contains($name);
282
    }
283
284
    /**
285
     * {@inheritdoc}
286
     */
287 1
    public function offsetGet($name)
288
    {
289 1
        return $this->get($name);
290
    }
291
292
    /**
293
     * {@inheritdoc}
294
     */
295 2
    public function offsetSet($offset, $command)
296
    {
297 2
        if ($offset) {
298 1
            throw new LogicException('Passing of offsets is not supported');
299
        }
300
301 1
        $this->add($command);
302 1
    }
303
304
    /**
305
     * {@inheritdoc}
306
     */
307 1
    public function offsetUnset($name)
308
    {
309 1
        $this->remove($name);
310 1
    }
311
312
    /**
313
     * {@inheritdoc}
314
     */
315 258
    public function getIterator()
316
    {
317 258
        return new ArrayIterator($this->commands);
318
    }
319
320
    /**
321
     * {@inheritdoc}
322
     */
323 36
    public function count()
324
    {
325 36
        return count($this->commands);
326
    }
327
}
328