Completed
Push — collection-position ( d51bab )
by Arnaud
02:27
created

Collection::filter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/*
3
 * Copyright (c) Arnaud Ligny <[email protected]>
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Cecil\Collection;
10
11
/**
12
 * Class Collection.
13
 */
14
class Collection implements CollectionInterface
15
{
16
    /**
17
     * Collection's identifier.
18
     *
19
     * @var string
20
     */
21
    protected $id;
22
23
    /**
24
     * Collection's items.
25
     *
26
     * @var array
27
     */
28
    protected $items = [];
29
30
    /**
31
     * Collection constructor.
32
     *
33
     * @param string $id
34
     * @param array  $items
35
     */
36
    public function __construct($id, $items = [])
37
    {
38
        $this->setId($id);
39
        $this->items = $items;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function setId(string $id): BaseInterface
46
    {
47
        $this->id = $id;
48
49
        return $this;
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function getId(): string
56
    {
57
        return $this->id;
58
    }
59
60
    /**
61
     * Search item by ID.
62
     *
63
     * @param string $id
64
     *
65
     * @return array|null
66
     */
67
    protected function searchItem(string $id): ?array
68
    {
69
        return array_filter($this->items, function ($item) use ($id) {
70
            return $item->getId() == $id;
71
        });
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function has(string $id): bool
78
    {
79
        //return array_key_exists($id, $this->items);
80
        $result = $this->searchItem($id);
81
        if (is_array($result) && !empty($result)) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return is_array($result) && !empty($result);.
Loading history...
82
            return true;
83
        }
84
85
        return false;
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91
    public function getPosition(string $id): int
92
    {
93
        $result = $this->searchItem($id);
94
        $position = key($result);
95
        if (!is_int($position)) {
96
            throw new \DomainException(sprintf(
97
                'Failed getting position of "%s" in "%s" collection: item does not exist.',
98
                $id,
99
                $this->getId()
100
            ));
101
        }
102
103
        return $position;
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function add(ItemInterface $item): CollectionInterface
110
    {
111
        if ($this->has($item->getId())) {
112
            throw new \DomainException(sprintf(
113
                'Failed adding "%s" in "%s" collection: item already exists.',
114
                $item->getId(),
115
                $this->getId()
116
            ));
117
        }
118
        //$this->items[$item->getId()] = $item;
119
        $this->items[] = $item;
120
121
        return $this;
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function replace(string $id, ItemInterface $item): CollectionInterface
128
    {
129
        if (!$this->has($id)) {
130
            throw new \DomainException(sprintf(
131
                'Failed replacing "%s" in "%s" collection: item does not exist.',
132
                $item->getId(),
133
                $this->getId()
134
            ));
135
        }
136
        //$this->items[$id] = $item;
137
        $this->items[$this->getPosition($id)] = $item;
138
139
        return $this;
140
    }
141
142
    /**
143
     * {@inheritdoc}
144
     */
145
    public function remove(string $id): CollectionInterface
146
    {
147
        if (!$this->has($id)) {
148
            throw new \DomainException(sprintf(
149
                'Failed removing "%s" in "%s" collection: item does not exist.',
150
                $id,
151
                $this->getId()
152
            ));
153
        }
154
        //unset($this->items[$id]);
155
        unset($this->items[$this->getPosition($id)]);
156
157
        return $this;
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163
    public function get(string $id): ItemInterface
164
    {
165
        if (!$this->has($id)) {
166
            throw new \DomainException(sprintf(
167
                'Failed getting "%s" in "%s" collection: item does not exist.',
168
                $id,
169
                $this->getId()
170
            ));
171
        }
172
173
        //return $this->items[$id];
174
        return $this->items[$this->getPosition($id)];
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180
    public function keys(): array
181
    {
182
        return array_keys($this->items);
183
    }
184
185
    /**
186
     * {@inheritdoc}
187
     */
188
    public function first(): ?ItemInterface
189
    {
190
        if (count($this->items) < 1) {
191
            return null;
192
        }
193
        $items = $this->items;
194
195
        return array_shift($items);
196
    }
197
198
    /**
199
     * {@inheritdoc}
200
     */
201
    public function last(): ?ItemInterface
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
202
    {
203
        if (count($this->items) < 1) {
204
            return null;
205
        }
206
        $items = $this->items;
207
208
        return array_pop($items);
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214
    public function count(): int
215
    {
216
        return count($this->items);
217
    }
218
219
    /**
220
     * {@inheritdoc}
221
     */
222
    public function toArray(): array
223
    {
224
        return $this->items;
225
    }
226
227
    /**
228
     * {@inheritdoc}
229
     */
230
    public function getIterator(): \ArrayIterator
231
    {
232
        return new \ArrayIterator($this->items);
233
    }
234
235
    /**
236
     * {@inheritdoc}
237
     */
238
    public function usort(\Closure $callback = null): CollectionInterface
239
    {
240
        //$callback ? uasort($this->items, $callback) : uasort($this->items, function ($a, $b) {
241
        $callback ? usort($this->items, $callback) : usort($this->items, function ($a, $b) {
242
            if ($a == $b) {
243
                return 0;
244
            }
245
246
            return ($a < $b) ? -1 : 1;
247
        });
248
249
        return new static(self::getId(), $this->items);
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     */
255
    public function filter(\Closure $callback): CollectionInterface
256
    {
257
        return new static(self::getId(), array_filter($this->items, $callback));
258
    }
259
260
    /**
261
     * {@inheritdoc}
262
     */
263
    public function map(\Closure $callback): CollectionInterface
264
    {
265
        return new static(self::getId(), array_map($callback, $this->items));
266
    }
267
268
    /**
269
     * Implement ArrayAccess.
270
     *
271
     * @param string $offset
272
     *
273
     * @return bool
274
     */
275
    public function offsetExists($offset)
276
    {
277
        return $this->has($offset);
278
    }
279
280
    /**
281
     * Implement ArrayAccess.
282
     *
283
     * @param string $offset
284
     *
285
     * @return CollectionInterface|ItemInterface|null
286
     */
287
    public function offsetGet($offset)
288
    {
289
        return $this->get($offset);
290
    }
291
292
    /**
293
     * Implement ArrayAccess.
294
     *
295
     * @param mixed         $offset
296
     * @param ItemInterface $value
297
     *
298
     * @return CollectionInterface|ItemInterface|null
299
     */
300
    public function offsetSet($offset, $value)
301
    {
302
        return $this->add($value);
303
    }
304
305
    /**
306
     * Implement ArrayAccess.
307
     *
308
     * @param string $offset
309
     *
310
     * @return CollectionInterface|null
311
     */
312
    public function offsetUnset($offset)
313
    {
314
        return $this->remove($offset);
315
    }
316
317
    /**
318
     * Returns a string representation of this object.
319
     *
320
     * @return string
321
     */
322
    public function __toString()
323
    {
324
        return sprintf("%s\n", json_encode($this->items));
325
    }
326
}
327