Completed
Push — feature-output-formats ( 2db023...b177b1 )
by Arnaud
01:49
created

Collection::last()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
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|null $id
34
     * @param array       $items
35
     */
36
    public function __construct($id = null, $items = [])
37
    {
38
        $this->setId($id);
39
        $this->items = $items;
40
        /*
41
        if ($items) {
42
            foreach ($items as $item) {
43
                $this->add($item);
44
            }
45
        }*/
46
    }
47
48
    /**
49
     * If parameter is empty uses the object's hash.
50
     * {@inheritdoc}
51
     */
52
    public function setId(string $id = null)
53
    {
54
        $this->id = $id;
55
        if (empty($this->id)) {
56
            $this->id = spl_object_hash($this);
57
        }
58
59
        return $this;
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function getId(): string
66
    {
67
        return $this->id;
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73
    public function has(string $id): bool
74
    {
75
        return array_key_exists($id, $this->items);
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     */
81
    public function add(ItemInterface $item): ?CollectionInterface
82
    {
83
        if ($this->has($item->getId())) {
84
            throw new \DomainException(sprintf(
85
                'Failed adding "%s" in "%s" collection: item already exists.',
86
                $item->getId(),
87
                $this->getId()
88
            ));
89
        }
90
        $this->items[$item->getId()] = $item;
91
92
        return $this;
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function replace(string $id, ItemInterface $item): ?CollectionInterface
99
    {
100
        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
        $this->items[$id] = $item;
108
109
        return $this;
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function remove(string $id): ?CollectionInterface
116
    {
117
        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
        unset($this->items[$id]);
125
126
        return $this;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function get(string $id): ?ItemInterface
133
    {
134
        if (!$this->has($id)) {
135
            return false;
136
        }
137
138
        return $this->items[$id];
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     */
144
    public function keys(): array
145
    {
146
        return array_keys($this->items);
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    public function first(): ?ItemInterface
153
    {
154
        if (count($this->items) < 1) {
155
            return null;
156
        }
157
        $items = $this->items;
158
159
        return array_shift($items);
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165
    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...
166
    {
167
        if (count($this->items) < 1) {
168
            return null;
169
        }
170
        $items = $this->items;
171
172
        return array_pop($items);
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178
    public function count(): int
179
    {
180
        return count($this->items);
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186
    public function toArray(): array
187
    {
188
        return $this->items;
189
    }
190
191
    /**
192
     * {@inheritdoc}
193
     */
194
    public function getIterator(): \ArrayIterator
195
    {
196
        return new \ArrayIterator($this->items);
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202
    public function usort(\Closure $callback = null): CollectionInterface
203
    {
204
        $callback ? uasort($this->items, $callback) : uasort($this->items, function ($a, $b) {
205
            if ($a == $b) {
206
                return 0;
207
            }
208
209
            return ($a < $b) ? -1 : 1;
210
        });
211
212
        return new static(self::getId(), $this->items);
213
    }
214
215
    /**
216
     * {@inheritdoc}
217
     */
218
    public function filter(\Closure $callback): CollectionInterface
219
    {
220
        return new static(self::getId(), array_filter($this->items, $callback));
221
    }
222
223
    /**
224
     * {@inheritdoc}
225
     */
226
    public function map(\Closure $callback): CollectionInterface
227
    {
228
        return new static(self::getId(), array_map($callback, $this->items));
229
    }
230
231
    /**
232
     * Implement ArrayAccess.
233
     *
234
     * @param string $offset
235
     *
236
     * @return bool
237
     */
238
    public function offsetExists($offset)
239
    {
240
        return $this->has($offset);
241
    }
242
243
    /**
244
     * Implement ArrayAccess.
245
     *
246
     * @param string $offset
247
     *
248
     * @return CollectionInterface|bool
0 ignored issues
show
Documentation introduced by
Should the return type not be ItemInterface|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
249
     */
250
    public function offsetGet($offset)
251
    {
252
        return $this->get($offset);
253
    }
254
255
    /**
256
     * Implement ArrayAccess.
257
     *
258
     * @param mixed         $offset
259
     * @param ItemInterface $value
260
     *
261
     * @return CollectionInterface|null
262
     */
263
    public function offsetSet($offset, $value)
264
    {
265
        return $this->add($value);
266
    }
267
268
    /**
269
     * Implement ArrayAccess.
270
     *
271
     * @param string $offset
272
     *
273
     * @return CollectionInterface|null
274
     */
275
    public function offsetUnset($offset)
276
    {
277
        return $this->remove($offset);
278
    }
279
280
    /**
281
     * Returns a string representation of this object.
282
     *
283
     * @return string
284
     */
285
    public function __toString()
286
    {
287
        return sprintf("%s\n", json_encode($this->items));
288
    }
289
}
290