Passed
Pull Request — master (#1013)
by lee
07:38
created

Collection::getPosition()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.351

Importance

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