Passed
Pull Request — master (#28)
by Mathieu
21:16 queued 14:19
created

Collection::sort()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 2
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Suricate;
6
7
class Collection implements
8
    \Iterator,
9
    \Countable,
10
    \ArrayAccess,
11
    Interfaces\ICollection
12
{
13
    protected $iteratorPosition = 0;
14
15
    protected $items = [];
16
    public $pagination = [
17
        'nbPages' => 0,
18
        'page' => 1,
19
        'nbItems' => 0
20
    ];
21
22 36
    public function __construct($items = [])
23
    {
24 36
        $this->items = $items;
25 36
    }
26
27 1
    public function paginate($nbItemPerPage, $currentPage = 1)
28
    {
29 1
        $this->pagination['page'] = $currentPage;
30 1
        $this->pagination['nbItems'] = count($this->items);
31 1
        $this->pagination['nbPages'] = (int) ceil(
32 1
            $this->pagination['nbItems'] / $nbItemPerPage
33
        );
34
35 1
        $this->items = array_slice(
36 1
            $this->items,
37 1
            ($currentPage - 1) * $nbItemPerPage,
38
            $nbItemPerPage
39
        );
40
41 1
        return $this;
42
    }
43
44 1
    /**
45
     * Get current page number
46 1
     *
47
     * @return integer
48 1
     */
49 1
    public function getPaginationCurrentPage(): int
50
    {
51
        return $this->pagination['page'];
52
    }
53 1
54 1
    /**
55 1
     * Get total number of pages
56 1
     *
57 1
     * @return integer
58
     */
59
    public function getPaginationNbPages(): int
60 1
    {
61 1
        return $this->pagination['nbPages'];
62 1
    }
63
64 1
    public function getPossibleValuesFor($args, $key = null)
65
    {
66
        if (!is_array($args)) {
67
            $args = [
68 1
                'format' => '%s',
69
                'data' => [$args]
70
            ];
71 1
        }
72
73 1
        $values = [];
74 1
        foreach ($this->items as $item) {
75 1
            $itemValues = [];
76
            foreach ($args['data'] as $arg) {
77
                $itemValues[] = dataGet($item, $arg);
78 1
            }
79
80
            $arrayKey = $key !== null ? dataGet($item, $key) : null;
81 14
            if (is_null($arrayKey)) {
82
                $values[] = vsprintf($args['format'], $itemValues);
83 14
            } else {
84
                $values[$arrayKey] = vsprintf($args['format'], $itemValues);
85
            }
86
        }
87
88
        return $values;
89
    }
90
91 4
    public function getValuesFor($name)
92
    {
93 4
        $values = [];
94
        foreach ($this->items as $item) {
95
            $values[] = dataGet($item, $name);
96
        }
97
98
        return $values;
99
    }
100
101
    public function getItems()
102
    {
103
        return $this->items;
104
    }
105
106
    /**
107
     * Implementation of countable interface
108
     *
109
     * @return int
110
     */
111
    public function count(): int
112
    {
113
        return count($this->items);
114
    }
115
116
    public function key()
117
    {
118
        return $this->iteratorPosition;
119
    }
120
121
    public function next()
122
    {
123 2
        ++$this->iteratorPosition;
124
    }
125 2
    public function current()
126
    {
127
        return $this->offsetGet($this->iteratorPosition);
128
    }
129
    public function rewind()
130
    {
131
        $this->iteratorPosition = 0;
132
    }
133
    public function valid()
134 3
    {
135
        return isset($this->items[$this->iteratorPosition]);
136 3
    }
137 3
    /**
138
     * Implementation of ArrayAccess interface
139 1
     *
140
     * @param  mixed $offset Offset to verify
141
     * @return bool
142
     */
143
    public function offsetExists($offset): bool
144
    {
145
        return \array_key_exists($offset, $this->items);
146
    }
147
148 1
    /**
149
     * Implementation of ArrayAccess Interface
150 1
     *
151 1
     * @param  mixed $offset Offset to get
152
     * @return mixed
153 1
     */
154
    public function offsetGet($offset)
155 1
    {
156
        if (array_key_exists($offset, $this->items)) {
157
            return $this->items[$offset];
158
        }
159
        return null;
160
    }
161
162 1
    /**
163
     * Implementation of ArrayAccess Interface
164 1
     *
165 1
     * @param mixed $offset Offset to set
166
     * @param mixed $value  Value to set
167
     */
168
    public function offsetSet($offset, $value)
169
    {
170
        if (is_null($offset)) {
171
            $this->items[] = $value;
172
        } else {
173
            $this->items[$offset] = $value;
174 1
        }
175
    }
176 1
177 1
    /**
178
     * Implementation of ArrayAccess Interface
179 1
     *
180
     * @param mixed $offset Offset to unset
181
     */
182
    public function offsetUnset($offset)
183
    {
184
        unset($this->items[$offset]);
185
    }
186 1
187
    // Helpers
188 1
189 1
    /**
190
     * Get first item of the collection
191
     *
192 1
     * @return mixed
193
     */
194
    public function first()
195
    {
196
        foreach ($this->items as $currentItem) {
197
            return $currentItem;
198
        }
199
    }
200 1
201
    /**
202 1
     * Get last item of the collection
203
     *
204
     * @return mixed
205
     */
206
    public function last()
207
    {
208
        if (count($this->items)) {
209
            return end($this->items);
210
        }
211 1
212
        return null;
213 1
    }
214 1
215
    /**
216 1
     * Check if collection is empty
217 1
     *
218 1
     * @return bool
219
     */
220 1
    public function isEmpty(): bool
221
    {
222
        return empty($this->items);
223
    }
224
225
    /**
226
     * Return the sum of the collection
227
     *
228
     * @param mixed $field Field to use for sum
229
     * @return double|integer
230
     */
231
    public function sum($field = null)
232
    {
233
        if ($field === null) {
234
            return array_sum($this->items);
235
        }
236
        $result = 0;
237
        foreach ($this->items as $item) {
238
            $result += dataGet($item, $field);
239
        }
240
        return $result;
241
    }
242
243
    public function random($nbItems = 1)
244
    {
245 1
        if ($this->isEmpty()) {
246
            return null;
247 1
        }
248
249
        $keys = array_rand($this->items, $nbItems);
250
251
        if (is_array($keys)) {
252
            return array_intersect_key($this->items, array_flip($keys));
253
        }
254
255
        return $this->items[$keys];
256
    }
257
258
    public function shuffle()
259
    {
260
        shuffle($this->items);
261
262
        return $this;
263
    }
264
265
    public function unique()
266
    {
267
        return new static(array_unique($this->items));
268
    }
269
270
    /**
271
     * Apply a closure to each element of the collection
272
     *
273
     * @param \Closure $callback Closure to apply
274
     * @return Collection
275
     */
276
    public function each(\Closure $callback): Collection
277
    {
278
        array_map($callback, $this->items);
279
        return $this;
280
    }
281
282
    /**
283
     * Sort a collection using a closure
284
     *
285
     * @param \Closure $closure Closure to apply for sorting, similar to uasort() closure
286
     * @return Collection
287
     */
288
    public function sort(\Closure $closure): Collection
289
    {
290
        uasort($this->items, $closure);
291
292
        return $this;
293
    }
294
295
    public function sortBy($field, $reverse = false)
296
    {
297
        if ($reverse) {
298
            $sortFunction = function ($a, $b) use ($field) {
299
                $first = dataGet($a, $field);
300
                $second = dataGet($b, $field);
301
                if ($first == $second) {
302 1
                    return 0;
303
                }
304 1
                return $first > $second ? -1 : 1;
305
            };
306
        } else {
307 1
            $sortFunction = function ($a, $b) use ($field) {
308
                $first = dataGet($a, $field);
309 1
                $second = dataGet($b, $field);
310
                if ($first == $second) {
311
                    return 0;
312 1
                }
313
                return $first < $second ? -1 : 1;
314 1
            };
315
        }
316
317 1
        usort($this->items, $sortFunction);
318
319 1
        return $this;
320
    }
321
322 1
    public function filter(\Closure $closure)
323
    {
324 1
        return new static(array_filter($this->items, $closure));
325
    }
326 1
327
    public function search($value, $strict = false)
328
    {
329 1
        return array_search($value, $this->items, $strict);
330
    }
331 1
332
    public function has($key)
333 1
    {
334
        return $this->offsetExists($key);
335
    }
336 1
337
    public function keys()
338 1
    {
339
        return array_keys($this->items);
340 1
    }
341
342 1
    public function prepend($item)
343
    {
344 1
        array_unshift($this->items, $item);
345
346
        return $this;
347 1
    }
348
349 1
    public function push($item)
350
    {
351
        $this->items[] = $item;
352 1
353
        return $this;
354 1
    }
355
356
    public function put($key, $val)
357 1
    {
358
        $this->items[$key] = $val;
359 1
360
        return $this;
361
    }
362 2
    public function shift()
363
    {
364 2
        return array_shift($this->items);
365 2
    }
366
367
    public function pop()
368
    {
369 1
        return array_pop($this->items);
370
    }
371 1
372
    public function reverse()
373
    {
374
        return new static(array_reverse($this->items));
375 1
    }
376
377
    public function reduce(callable $callback, $initial = null)
378
    {
379
        return array_reduce($this->items, $callback, $initial);
380
    }
381
382
    public function slice($offset, $length = null, $preserveKeys = false)
383
    {
384
        return new static(
385
            array_slice($this->items, $offset, $length, $preserveKeys)
386
        );
387
    }
388
389
    public function take($limit = null)
390
    {
391
        if ($limit < 0) {
392
            return $this->slice(abs($limit), $limit);
393
        }
394
395
        return $this->slice(0, $limit);
396
    }
397
398
    public function splice($offset, $length = null, $replacement = [])
399
    {
400
        return new static(
401
            array_splice($this->items, $offset, $length, $replacement)
402
        );
403
    }
404
405
    public function chunk($size, $preserveKeys = false)
406
    {
407
        $result = new static();
408
        foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) {
409
            $result->push(new static($chunk));
410
        }
411
        return $result;
412
    }
413
}
414