Completed
Push — collection-position ( 9f47c3...636ee4 )
by Arnaud
02:03
created

Collection::toJson()   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 0
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
        $result = $this->searchItem($id);
80
        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...
81
            return true;
82
        }
83
84
        return false;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function add(ItemInterface $item): CollectionInterface
91
    {
92
        if ($this->has($item->getId())) {
93
            throw new \DomainException(sprintf(
94
                'Failed adding "%s" in "%s" collection: item already exists.',
95
                $item->getId(),
96
                $this->getId()
97
            ));
98
        }
99
        $this->items[] = $item;
100
101
        return $this;
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function replace(string $id, ItemInterface $item): CollectionInterface
108
    {
109
        if (!$this->has($id)) {
110
            throw new \DomainException(sprintf(
111
                'Failed replacing "%s" in "%s" collection: item does not exist.',
112
                $item->getId(),
113
                $this->getId()
114
            ));
115
        }
116
        $this->items[$this->getPosition($id)] = $item;
117
118
        return $this;
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124
    public function remove(string $id): CollectionInterface
125
    {
126
        if (!$this->has($id)) {
127
            throw new \DomainException(sprintf(
128
                'Failed removing "%s" in "%s" collection: item does not exist.',
129
                $id,
130
                $this->getId()
131
            ));
132
        }
133
        unset($this->items[$this->getPosition($id)]);
134
135
        return $this;
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141
    public function get(string $id): ItemInterface
142
    {
143
        if (!$this->has($id)) {
144
            throw new \DomainException(sprintf(
145
                'Failed getting "%s" in "%s" collection: item does not exist.',
146
                $id,
147
                $this->getId()
148
            ));
149
        }
150
151
        return $this->items[$this->getPosition($id)];
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157
    public function getPosition(string $id): int
158
    {
159
        $result = $this->searchItem($id);
160
        $position = key($result);
161
        if (!is_int($position)) {
162
            throw new \DomainException(sprintf(
163
                'Failed getting position of "%s" in "%s" collection: item does not exist.',
164
                $id,
165
                $this->getId()
166
            ));
167
        }
168
169
        return $position;
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175
    public function keys(): array
176
    {
177
        return array_keys($this->items);
178
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183
    public function first(): ?ItemInterface
184
    {
185
        if (count($this->items) < 1) {
186
            return null;
187
        }
188
        $items = $this->items;
189
190
        return array_shift($items);
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196
    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...
197
    {
198
        if (count($this->items) < 1) {
199
            return null;
200
        }
201
        $items = $this->items;
202
203
        return array_pop($items);
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     */
209
    public function count(): int
210
    {
211
        return count($this->items);
212
    }
213
214
    /**
215
     * {@inheritdoc}
216
     */
217
    public function toArray(): array
218
    {
219
        return $this->items;
220
    }
221
222
    /**
223
     * {@inheritdoc}
224
     */
225
    public function toJson(): string
226
    {
227
        return sprintf("%s\n", json_encode($this->items));
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     */
233
    public function getIterator(): \ArrayIterator
234
    {
235
        return new \ArrayIterator($this->items);
236
    }
237
238
    /**
239
     * {@inheritdoc}
240
     */
241
    public function usort(\Closure $callback = null): CollectionInterface
242
    {
243
        $callback ? usort($this->items, $callback) : usort($this->items, function ($a, $b) {
244
            if ($a == $b) {
245
                return 0;
246
            }
247
248
            return ($a < $b) ? -1 : 1;
249
        });
250
251
        return new static(self::getId(), $this->items);
252
    }
253
254
    /**
255
     * {@inheritdoc}
256
     */
257
    public function filter(\Closure $callback): CollectionInterface
258
    {
259
        return new static(self::getId(), array_filter($this->items, $callback));
260
    }
261
262
    /**
263
     * {@inheritdoc}
264
     */
265
    public function map(\Closure $callback): CollectionInterface
266
    {
267
        return new static(self::getId(), array_map($callback, $this->items));
268
    }
269
270
    /**
271
     * Implement ArrayAccess.
272
     *
273
     * @param string $offset
274
     *
275
     * @return bool
276
     */
277
    public function offsetExists($offset)
278
    {
279
        return $this->has($offset);
280
    }
281
282
    /**
283
     * Implement ArrayAccess.
284
     *
285
     * @param string $offset
286
     *
287
     * @return CollectionInterface|ItemInterface|null
288
     */
289
    public function offsetGet($offset)
290
    {
291
        return $this->get($offset);
292
    }
293
294
    /**
295
     * Implement ArrayAccess.
296
     *
297
     * @param mixed         $offset
298
     * @param ItemInterface $value
299
     *
300
     * @return CollectionInterface|ItemInterface|null
301
     */
302
    public function offsetSet($offset, $value)
303
    {
304
        return $this->add($value);
305
    }
306
307
    /**
308
     * Implement ArrayAccess.
309
     *
310
     * @param string $offset
311
     *
312
     * @return CollectionInterface|null
313
     */
314
    public function offsetUnset($offset)
315
    {
316
        return $this->remove($offset);
317
    }
318
319
    /**
320
     * Return collection ID.
321
     *
322
     * @return string
323
     */
324
    public function __toString()
325
    {
326
        return $this->getId();
327
    }
328
}
329