Completed
Push — develop ( 8be0b9...37dfb0 )
by Mathieu
02:02
created

Collection::search()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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