Passed
Pull Request — master (#1676)
by Arnaud
05:15 queued 14s
created

Collection::replace()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 7
ccs 3
cts 4
cp 0.75
crap 2.0625
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Cecil.
7
 *
8
 * Copyright (c) Arnaud Ligny <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Cecil\Collection;
15
16
/**
17
 * Class Collection.
18
 */
19
class Collection implements CollectionInterface
20
{
21
    /** @var string Collection's identifier. */
22
    protected $id;
23
24
    /** @var array Collection's items. */
25
    protected $items = [];
26
27 1
    public function __construct(string $id, array $items = [])
28
    {
29 1
        $this->setId($id);
30 1
        $this->items = $items;
31
    }
32
33
    /**
34
     * {@inheritdoc}
35
     */
36 1
    public function setId(string $id): BaseInterface
37
    {
38 1
        $this->id = $id;
39
40 1
        return $this;
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46 1
    public function getId(): string
47
    {
48 1
        return $this->id;
49
    }
50
51
    /**
52
     * Search an item by ID.
53
     */
54 1
    protected function searchItem(string $id): ?array
55
    {
56 1
        return array_filter($this->items, function (ItemInterface $item) use ($id) {
57 1
            return $item->getId() == $id;
58 1
        });
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64 1
    public function has(string $id): bool
65
    {
66 1
        $result = $this->searchItem($id);
67 1
        if (\is_array($result) && !empty($result)) {
68 1
            return true;
69
        }
70
71 1
        return false;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     *
77
     * @throws \DomainException
78
     */
79 1
    public function add(ItemInterface $item): CollectionInterface
80
    {
81 1
        if ($this->has($item->getId())) {
82 1
            throw new \DomainException(sprintf('Failed adding "%s" in "%s" collection: item already exists.', $item->getId(), $this->getId()));
83
        }
84 1
        $this->items[] = $item;
85
86 1
        return $this;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     *
92
     * @throws \DomainException
93
     */
94 1
    public function replace(string $id, ItemInterface $item): CollectionInterface
95
    {
96 1
        if (!$this->has($id)) {
97
            throw new \DomainException(sprintf('Failed replacing "%s" in "%s" collection: item does not exist.', $item->getId(), $this->getId()));
98
        }
99
100 1
        return $this;
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     *
106
     * @throws \DomainException
107
     */
108 1
    public function remove(string $id): CollectionInterface
109
    {
110 1
        if (!$this->has($id)) {
111
            throw new \DomainException(sprintf('Failed removing "%s" in "%s" collection: item does not exist.', $id, $this->getId()));
112
        }
113
114 1
        return $this;
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     *
120
     * @throws \DomainException
121
     */
122 1
    public function get(string $id): ItemInterface
123
    {
124 1
        if (!$this->has($id)) {
125
            throw new \DomainException(sprintf('Failed getting "%s" in "%s" collection: item does not exist.', $id, $this->getId()));
126
        }
127
128 1
        return $this->items[$this->getPosition($id)];
129
    }
130
131
    /**
132
     * {@inheritdoc}
133
     *
134
     * @throws \DomainException
135
     */
136 1
    public function getPosition(string $id): int
137
    {
138 1
        $result = $this->searchItem($id);
139 1
        $position = key($result);
140 1
        if (!\is_int($position)) {
141
            throw new \DomainException(sprintf('Failed getting position of "%s" in "%s" collection: item does not exist.', $id, $this->getId()));
142
        }
143
144 1
        return $position;
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150
    public function keys(): array
151
    {
152
        return array_keys($this->items);
153
    }
154
155
    /**
156
     * {@inheritdoc}
157
     */
158 1
    public function first(): ?ItemInterface
159
    {
160 1
        if (\count($this->items) < 1) {
161
            return null;
162
        }
163 1
        $items = $this->items;
164
165 1
        return array_shift($items);
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function last(): ?ItemInterface
172
    {
173
        if (\count($this->items) < 1) {
174
            return null;
175
        }
176
        $items = $this->items;
177
178
        return array_pop($items);
179
    }
180
181
    /**
182
     * {@inheritdoc}
183
     */
184 1
    public function count(): int
185
    {
186 1
        return \count($this->items);
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     */
192 1
    public function toArray(): array
193
    {
194 1
        return $this->items;
195
    }
196
197
    /**
198
     * {@inheritdoc}
199
     */
200
    public function toJson(): string
201
    {
202
        return sprintf("%s\n", json_encode($this->items));
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208 1
    public function getIterator(): \ArrayIterator
209
    {
210 1
        return new \ArrayIterator($this->items);
211
    }
212
213
    /**
214
     * {@inheritdoc}
215
     */
216 1
    public function usort(\Closure $callback = null): CollectionInterface
217
    {
218 1
        $callback ? usort($this->items, $callback) : usort($this->items, function ($a, $b) {
219
            if ($a == $b) {
220
                return 0;
221
            }
222
223
            return ($a < $b) ? -1 : 1;
224 1
        });
225
226 1
        return new static($this->getId(), $this->items); /** @phpstan-ignore-line */
227
    }
228
229
    /**
230
     * {@inheritdoc}
231
     */
232
    public function reverse(): CollectionInterface
233
    {
234
        return new static($this->getId(), array_reverse($this->items)); /** @phpstan-ignore-line */
235
    }
236
237
    /**
238
     * {@inheritdoc}
239
     */
240 1
    public function filter(\Closure $callback): CollectionInterface
241
    {
242 1
        return new static($this->getId(), array_filter($this->items, $callback)); /** @phpstan-ignore-line */
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248 1
    public function map(\Closure $callback): CollectionInterface
249
    {
250 1
        return new static($this->getId(), array_map($callback, $this->items)); /** @phpstan-ignore-line */
251
    }
252
253
    /**
254
     * Implements \ArrayAccess.
255
     *
256
     * @param string $offset
257
     *
258
     * @return bool
259
     */
260
    #[\ReturnTypeWillChange]
261 1
    public function offsetExists($offset): bool
262
    {
263 1
        return $this->has((string) $offset);
264
    }
265
266
    /**
267
     * Implements \ArrayAccess.
268
     *
269
     * @param string $offset
270
     *
271
     * @return CollectionInterface|ItemInterface|null
272
     */
273
    #[\ReturnTypeWillChange]
274 1
    public function offsetGet($offset)
275
    {
276 1
        return $this->get((string) $offset);
277
    }
278
279
    /**
280
     * Implements \ArrayAccess.
281
     *
282
     * @param mixed         $offset
283
     * @param ItemInterface $value
284
     *
285
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
286
     */
287
    #[\ReturnTypeWillChange]
288
    public function offsetSet($offset, $value): void
289
    {
290
        $this->add($value);
291
    }
292
293
    /**
294
     * Implements \ArrayAccess.
295
     *
296
     * @param string $offset
297
     *
298
     * @return void
299
     */
300
    #[\ReturnTypeWillChange]
301
    public function offsetUnset($offset): void
302
    {
303
        $this->remove($offset);
304
    }
305
306
    /**
307
     * Returns the collection ID.
308
     *
309
     * @return string
310
     */
311 1
    public function __toString()
312
    {
313 1
        return $this->getId();
314
    }
315
}
316