Completed
Push — master ( 3c2288...07648f )
by Matthew
01:30
created

Collection::sort()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PublishingKit\Utilities\Collections;
6
7
use Countable;
8
use ArrayAccess;
9
use IteratorAggregate;
10
use ArrayIterator;
11
use JsonSerializable;
12
use Serializable;
13
use PublishingKit\Utilities\Contracts\Collectable;
14
use PublishingKit\Utilities\Traits\Macroable;
15
use OutOfBoundsException;
16
17
/**
18
 * Collection class
19
 */
20
class Collection implements Countable, ArrayAccess, IteratorAggregate, JsonSerializable, Collectable, Serializable
21
{
22
    use Macroable;
0 ignored issues
show
Bug introduced by
The trait PublishingKit\Utilities\Traits\Macroable requires the property $name which is not provided by PublishingKit\Utilities\Collections\Collection.
Loading history...
23
24
    /**
25
     * Items
26
     *
27
     * @var array
28
     */
29
    protected $items;
30
31
    /**
32
     * Position
33
     *
34
     * @var integer
35
     */
36
    protected $position = 0;
37
38
    /**
39
     * Return count of items
40
     *
41
     * @return integer
42
     */
43 9
    public function count()
44
    {
45 9
        return count($this->items);
46
    }
47
48
    /**
49
     * Constructor
50
     *
51
     * @param array $items Items to collect.
52
     * @return void
53
     */
54 147
    public function __construct(array $items = [])
55
    {
56 147
        $this->items = $items;
57 147
    }
58
59
    /**
60
     * Create collection
61
     *
62
     * @param array $items Items to collect.
63
     * @return Collection
64
     */
65 6
    public static function make(array $items)
66
    {
67 6
        return new static($items);
68
    }
69
70
    /**
71
     * Does item exist?
72
     *
73
     * @param mixed $offset The offset.
74
     * @return boolean
75
     */
76 3
    public function offsetExists($offset)
77
    {
78 3
        return isset($this->items[$offset]);
79
    }
80
81
    /**
82
     * Get offset
83
     *
84
     * @param mixed $offset The offset.
85
     * @return mixed
86
     */
87 15
    public function offsetGet($offset)
88
    {
89 15
        return isset($this->items[$offset]) ? $this->items[$offset] : null;
90
    }
91
92
    /**
93
     * Set offset
94
     *
95
     * @param mixed $offset The offset.
96
     * @param mixed $value  The value to set.
97
     * @return void
98
     */
99 6
    public function offsetSet($offset, $value): void
100
    {
101 6
        if (is_null($offset)) {
102 3
            $this->items[] = $value;
103 3
            return;
104
        }
105 3
        $this->items[$offset] = $value;
106 3
    }
107
108
    /**
109
     * Unset offset
110
     *
111
     * @param mixed $offset The offset.
112
     * @return void
113
     */
114 3
    public function offsetUnset($offset)
115
    {
116 3
        unset($this->items[$offset]);
117 3
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122 3
    public function getIterator()
123
    {
124 3
        return new ArrayIterator($this->items);
125
    }
126
127
    /**
128
     * Serialize collection to JSON
129
     *
130
     * @return string|false
131
     */
132 6
    public function jsonSerialize()
133
    {
134 6
        return json_encode($this->items);
135
    }
136
137
    /**
138
     * Convert collection to JSON
139
     *
140
     * @return string|false
141
     */
142 3
    public function toJson()
143
    {
144 3
        return $this->jsonSerialize();
145
    }
146
147
    /**
148
     * Convert collection to array
149
     *
150
     * @return array
151
     */
152 72
    public function toArray()
153
    {
154 72
        return $this->items;
155
    }
156
157
    /**
158
     * Map operation
159
     *
160
     * @param callable $callback The callback to use.
161
     * @return Collection
162
     */
163 12
    public function map(callable $callback)
164
    {
165 12
        return new static(array_map($callback, $this->items));
166
    }
167
168
    /**
169
     * Filter operation
170
     *
171
     * @param callable $callback The callback to use.
172
     * @return Collection
173
     */
174 6
    public function filter(callable $callback)
175
    {
176 6
        return new static(array_filter($this->items, $callback));
177
    }
178
179
    /**
180
     * Reverse filter operation
181
     *
182
     * @param callable $callback The callback to use.
183
     * @return Collection
184
     */
185 3
    public function reject(callable $callback)
186
    {
187
        return $this->filter(function ($item) use ($callback) {
188 3
            return !$callback($item);
189 3
        });
190
    }
191
192
    /**
193
     * Reduce operation
194
     *
195
     * @param callable $callback The callback to use.
196
     * @param mixed   $initial  The initial value.
197
     * @return mixed
198
     */
199 3
    public function reduce(callable $callback, $initial = 0)
200
    {
201 3
        $accumulator = $initial;
202 3
        foreach ($this->items as $item) {
203 3
            $accumulator = $callback($accumulator, $item);
204
        }
205 3
        return $accumulator;
206
    }
207
208
    /**
209
     * Reduce operation that returns a collection
210
     *
211
     * @param callable $callback The callback to use.
212
     * @param mixed   $initial  The initial value.
213
     * @return Collection
214
     */
215 3
    public function reduceToCollection(callable $callback, $initial = 0): Collection
216
    {
217 3
        $accumulator = $initial;
218 3
        foreach ($this->items as $item) {
219 3
            $accumulator = $callback($accumulator, $item);
220
        }
221 3
        return new static($accumulator);
222
    }
223
224
    /**
225
     * Pluck a single field
226
     *
227
     * @param mixed $name Name of field to pluck.
228
     * @return mixed
229
     */
230 3
    public function pluck($name)
231
    {
232
        return $this->map(function (array $item) use ($name) {
233 3
            return $item[$name];
234 3
        });
235
    }
236
237
    /**
238
     * Apply callback to each item in the collection
239
     *
240
     * @param callable $callback The callback to use.
241
     * @return void
242
     */
243 3
    public function each(callable $callback)
244
    {
245 3
        foreach ($this->items as $item) {
246 3
            $callback($item);
247
        }
248 3
    }
249
250
    /**
251
     * Push item to end of collection
252
     *
253
     * @param mixed $item Item to push.
254
     * @return Collection
255
     */
256 3
    public function push($item)
257
    {
258 3
        array_push($this->items, $item);
259 3
        return new static($this->items);
260
    }
261
262
    /**
263
     * Pop item from end of collection
264
     *
265
     * @return mixed
266
     */
267 3
    public function pop()
268
    {
269 3
        return array_pop($this->items);
270
    }
271
272
    /**
273
     * Push item to start of collection
274
     *
275
     * @param mixed $item Item to push.
276
     * @return Collection
277
     */
278 3
    public function unshift($item)
279
    {
280 3
        array_unshift($this->items, $item);
281 3
        return new static($this->items);
282
    }
283
284
    /**
285
     * Pop item from start of collection
286
     *
287
     * @return mixed
288
     */
289 3
    public function shift()
290
    {
291 3
        return array_shift($this->items);
292
    }
293
294
    /**
295
     * Sort collection
296
     *
297
     * @param callable|null $callback The callback to use.
298
     * @return Collection
299
     */
300 6
    public function sort(callable $callback = null)
301
    {
302 6
        if ($callback) {
303 3
            usort($this->items, $callback);
304
        } else {
305 3
            sort($this->items);
306
        }
307 6
        return new static($this->items);
308
    }
309
310
    /**
311
     * Reverse collection
312
     *
313
     * @return Collection
314
     */
315 3
    public function reverse()
316
    {
317 3
        return new static(array_reverse($this->items));
318
    }
319
320
    /**
321
     * Return keys
322
     *
323
     * @return Collection
324
     */
325 3
    public function keys()
326
    {
327 3
        return new static(array_keys($this->items));
328
    }
329
330
    /**
331
     * Return values
332
     *
333
     * @return Collection
334
     */
335 3
    public function values(): Collection
336
    {
337 3
        return new static(array_values($this->items));
338
    }
339
340
    /**
341
     * Return chunked collection
342
     *
343
     * @param integer $size Chunk size.
344
     * @return Collection
345
     */
346 3
    public function chunk(int $size): Collection
347
    {
348 3
        return new static(array_chunk($this->items, $size));
349
    }
350
351
    /**
352
     * Merge another array into the collection
353
     *
354
     * @param mixed $merge Array to merge.
355
     * @return Collection
356
     */
357 3
    public function merge($merge): Collection
358
    {
359 3
        return new static(array_merge($this->items, $merge));
360
    }
361
362
    /**
363
     * Group by a given key
364
     *
365
     * @param string $key Key to group by.
366
     * @return Collection
367
     */
368 3
    public function groupBy(string $key): Collection
369
    {
370 3
        $items = [];
371 3
        foreach ($this->items as $item) {
372 3
            $items[$item[$key]][] = $item;
373
        }
374 3
        return new static($items);
375
    }
376
377
    /**
378
     * Flatten items
379
     *
380
     * @return Collection
381
     */
382 3
    public function flatten(): Collection
383
    {
384 3
        $return = [];
385
        array_walk_recursive($this->items, function ($a) use (&$return) {
386 3
            $return[] = $a;
387 3
        });
388 3
        return new static($return);
389
    }
390
391
    /**
392
     * Paginate items
393
     *
394
     * @return Collection
395
     */
396 3
    public function paginate(int $perPage, int $page): Collection
397
    {
398 3
        $offset = ($page - 1) * $perPage;
399 3
        return new static(array_slice($this->items, $offset, $perPage));
400
    }
401
402
    /**
403
     * {@inheritDoc}
404
     */
405 3
    public function serialize()
406
    {
407 3
        return serialize($this->items);
408
    }
409
410
    /**
411
     * {@inheritDoc}
412
     */
413 3
    public function unserialize($serialized)
414
    {
415 3
        $this->items = unserialize($serialized);
416 3
    }
417
418
    /**
419
     * @return mixed
420
     */
421 3
    public function pipe(callable $callback)
422
    {
423 3
        return $callback($this);
424
    }
425
}
426