Completed
Push — develop ( ca634b...64da83 )
by Mathieu
02:06
created

Collection::random()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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