Passed
Push — master ( e4e2c9...124fdd )
by Gabriel
01:32
created

Arr::forgetValues()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4.0466

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
dl 0
loc 12
ccs 6
cts 7
cp 0.8571
rs 10
cc 4
nc 4
nop 2
crap 4.0466
1
<?php
2
3
namespace Nip\Utility;
4
5
use ArrayAccess;
6
7
/**
8
 * Class Arr
9
 * @package Nip\Utility
10
 */
11
class Arr
12
{
13
14
    /**
15
     * Determine whether the given value is array accessible.
16
     *
17
     * @param mixed $value
18
     * @return bool
19
     */
20 1
    public static function accessible($value)
21
    {
22 1
        return is_array($value) || $value instanceof ArrayAccess;
23
    }
24
25
    /**
26
     * Collapse an array of arrays into a single array.
27
     *
28
     * @param array $array
29
     * @return array
30
     */
31
    public static function collapse($array)
32
    {
33
        $results = [];
34
        foreach ($array as $values) {
35
            if (is_object($values) && method_exists($values, 'all')) {
36
                $values = $values->all();
37
            } elseif (!is_array($values)) {
38
                continue;
39
            }
40
            $results[] = $values;
41
        }
42
        return array_merge([], ...$results);
43
    }
44
45
    /**
46
     * Determine if the given key exists in the provided array.
47
     *
48
     * @param \ArrayAccess|array $array
49
     * @param string|int $key
50
     * @return bool
51
     */
52 1
    public static function exists($array, $key)
53
    {
54 1
        if ($array instanceof ArrayAccess) {
55
            return $array->offsetExists($key);
56
        }
57 1
        return array_key_exists($key, $array);
58
    }
59
60
    /**
61
     * Return the first element in an array passing a given truth test.
62
     *
63
     * @param  iterable  $array
64
     * @param  callable|null  $callback
65
     * @param  mixed  $default
66
     * @return mixed
67
     */
68
    public static function first($array, callable $callback = null, $default = null)
69
    {
70
        if (is_null($callback)) {
71
            if (empty($array)) {
72
                return Util::value($default);
73
            }
74
75
            foreach ($array as $item) {
76
                return $item;
77
            }
78
        }
79
80
        foreach ($array as $key => $value) {
81
            if ($callback($value, $key)) {
82
                return $value;
83
            }
84
        }
85
86
        return Util::value($default);
87
    }
88
89
    /**
90
     * Return the last element in an array passing a given truth test.
91
     *
92
     * @param  array  $array
93
     * @param  callable|null  $callback
94
     * @param  mixed  $default
95
     * @return mixed
96
     */
97
    public static function last($array, callable $callback = null, $default = null)
98
    {
99
        if (is_null($callback)) {
100
            return empty($array) ? Util::value($default) : end($array);
101
        }
102
103
        return static::first(array_reverse($array, true), $callback, $default);
104
    }
105
106
    /**
107
     * Remove one or many array items from a given array using "dot" notation.
108
     *
109
     * @param array $array
110
     * @param array|string $keys
111
     * @return void
112
     */
113
    public static function forget(&$array, $keys)
114
    {
115
        $original = &$array;
116
117
        $keys = (array)$keys;
118
119
        if (count($keys) === 0) {
120
            return;
121
        }
122
123
        foreach ($keys as $key) {
124
            // if the exact key exists in the top-level, remove it
125
            if (static::exists($array, $key)) {
126
                unset($array[$key]);
127
128
                continue;
129
            }
130
131
            $parts = explode('.', $key);
132
133
            // clean up before each pass
134
            $array = &$original;
135
136
            while (count($parts) > 1) {
137
                $part = array_shift($parts);
138
139
                if (isset($array[$part]) && is_array($array[$part])) {
140
                    $array = &$array[$part];
141
                } else {
142
                    continue 2;
143
                }
144
            }
145
146
            unset($array[array_shift($parts)]);
147
        }
148
    }
149
150
    /**
151
     * @param $array
152
     * @param mixed ...$values
153
     * @return mixed
154
     */
155 1
    public static function forgetValues(&$array, ...$values)
156
    {
157 1
        if (is_array($values[0])) {
158
            $values = $values[0];
159
        }
160 1
        if ($values) {
161 1
            foreach ($values as $value) {
162 1
                unset($array[array_search($value, $array)]);
163
            }
164
        }
165
166 1
        return $array;
167
    }
168
169
    /**
170
     * Get an item from an array using "dot" notation.
171
     *
172
     * @param \ArrayAccess|array $array
173
     * @param string|int|null $key
174
     * @param mixed $default
175
     * @return mixed
176
     */
177
    public static function get($array, $key, $default = null)
178
    {
179
        if (!static::accessible($array)) {
180
            return value($default);
181
        }
182
183
        if (is_null($key)) {
184
            return $array;
185
        }
186
187
        if (static::exists($array, $key)) {
188
            return $array[$key];
189
        }
190
191
        if (strpos($key, '.') === false) {
192
            return $array[$key] ?? value($default);
193
        }
194
195
        foreach (explode('.', $key) as $segment) {
196
            if (static::accessible($array) && static::exists($array, $segment)) {
197
                $array = $array[$segment];
198
            } else {
199
                return value($default);
200
            }
201
        }
202
203
        return $array;
204
    }
205
206
207
    /**
208
     * Check if an item or items exist in an array using "dot" notation.
209
     *
210
     * @param \ArrayAccess|array $array
211
     * @param string|array $keys
212
     * @return bool
213
     */
214
    public static function has($array, $keys)
215
    {
216
        $keys = (array)$keys;
217
218
        if (!$array || $keys === []) {
219
            return false;
220
        }
221
222
        foreach ($keys as $key) {
223
            $subKeyArray = $array;
224
225
            if (static::exists($array, $key)) {
226
                continue;
227
            }
228
229
            foreach (explode('.', $key) as $segment) {
230
                if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) {
231
                    $subKeyArray = $subKeyArray[$segment];
232
                } else {
233
                    return false;
234
                }
235
            }
236
        }
237
238
        return true;
239
    }
240
    
241
    /**
242
     * Filter the array using the given callback.
243
     *
244
     * @param array $array
245
     * @param callable $callback
246
     * @return array
247
     */
248
    public static function where($array, callable $callback)
249
    {
250
        return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH);
251
    }
252
253
    /**
254
     * If the given value is not an array, wrap it in one.
255
     *
256
     * @param mixed $value
257
     * @return array
258
     */
259
    public static function wrap($value)
260
    {
261
        return !is_array($value) ? [$value] : $value;
262
    }
263
264
    /**
265
     * Get a subset of the items from the given array.
266
     *
267
     * @param array $array
268
     * @param array|string $keys
269
     * @return array
270
     */
271
    public static function only($array, $keys)
272
    {
273
        return array_intersect_key($array, array_flip((array)$keys));
274
    }
275
276
    /**
277
     * Pluck an array of values from an array.
278
     *
279
     * @param array $array
280
     * @param string|array $value
281
     * @param string|array|null $key
282
     * @return array
283
     */
284 1
    public static function pluck($array, $value, $key = null)
285
    {
286 1
        $results = [];
287 1
        [$value, $key] = static::explodePluckParameters($value, $key);
288 1
        foreach ($array as $item) {
289 1
            $itemValue = data_get($item, $value);
290
291
            // If the key is "null", we will just append the value to the array and keep
292
            // looping. Otherwise we will key the array using the value of the key we
293
            // received from the developer. Then we'll return the final array form.
294 1
            if (is_null($key)) {
295 1
                $results[] = $itemValue;
296
            } else {
297
                $itemKey = data_get($item, $key);
298
                if (is_object($itemKey) && method_exists($itemKey, '__toString')) {
299
                    $itemKey = (string)$itemKey;
300
                }
301
                $results[$itemKey] = $itemValue;
302
            }
303
        }
304 1
        return $results;
305
    }
306
307
    /**
308
     * Explode the "value" and "key" arguments passed to "pluck".
309
     *
310
     * @param string|array $value
311
     * @param string|array|null $key
312
     * @return array
313
     */
314 1
    protected static function explodePluckParameters($value, $key)
315
    {
316 1
        $value = is_string($value) ? explode('.', $value) : $value;
317 1
        $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
318 1
        return [$value, $key];
319
    }
320
321
    /**
322
     * Push an item onto the beginning of an array.
323
     *
324
     * @param array $array
325
     * @param mixed $value
326
     * @param mixed $key
327
     * @return array
328
     */
329
    public static function prepend($array, $value, $key = null)
330
    {
331
        if (is_null($key)) {
332
            array_unshift($array, $value);
333
        } else {
334
            $array = [$key => $value] + $array;
335
        }
336
337
        return $array;
338
    }
339
340
    /**
341
     * Get a value from the array, and remove it.
342
     *
343
     * @param array $array
344
     * @param string $key
345
     * @param mixed $default
346
     * @return mixed
347
     */
348
    public static function pull(&$array, $key, $default = null)
349
    {
350
        $value = static::get($array, $key, $default);
351
352
        static::forget($array, $key);
353
354
        return $value;
355
    }
356
357
358
    /**
359
     * Get one or a specified number of random values from an array.
360
     *
361
     * @param array $array
362
     * @param int|null $number
363
     * @return mixed
364
     *
365
     * @throws \InvalidArgumentException
366
     */
367
    public static function random($array, $number = null)
368
    {
369
        $requested = is_null($number) ? 1 : $number;
370
371
        $count = count($array);
372
373
        if ($requested > $count) {
374
            throw new InvalidArgumentException(
0 ignored issues
show
Bug introduced by
The type Nip\Utility\InvalidArgumentException was not found. Did you mean InvalidArgumentException? If so, make sure to prefix the type with \.
Loading history...
375
                "You requested {$requested} items, but there are only {$count} items available."
376
            );
377
        }
378
379
        if (is_null($number)) {
380
            return $array[array_rand($array)];
381
        }
382
383
        if ((int)$number === 0) {
384
            return [];
385
        }
386
387
        $keys = array_rand($array, $number);
388
389
        $results = [];
390
391
        foreach ((array)$keys as $key) {
392
            $results[] = $array[$key];
393
        }
394
395
        return $results;
396
    }
397
398
    /**
399
     * Set an array item to a given value using "dot" notation.
400
     *
401
     * If no key is given to the method, the entire array will be replaced.
402
     *
403
     * @param array $array
404
     * @param string|null $key
405
     * @param mixed $value
406
     * @return array
407
     */
408
    public static function set(&$array, $key, $value)
409
    {
410
        if (is_null($key)) {
411
            return $array = $value;
412
        }
413
414
        $keys = explode('.', $key);
415
416
        foreach ($keys as $i => $key) {
0 ignored issues
show
introduced by
$key is overwriting one of the parameters of this function.
Loading history...
417
            if (count($keys) === 1) {
418
                break;
419
            }
420
421
            unset($keys[$i]);
422
423
            // If the key doesn't exist at this depth, we will just create an empty array
424
            // to hold the next value, allowing us to create the arrays to hold final
425
            // values at the correct depth. Then we'll keep digging into the array.
426
            if (!isset($array[$key]) || !is_array($array[$key])) {
427
                $array[$key] = [];
428
            }
429
430
            $array = &$array[$key];
431
        }
432
433
        $array[array_shift($keys)] = $value;
434
435
        return $array;
436
    }
437
438
    /**
439
     * Shuffle the given array and return the result.
440
     *
441
     * @param array $array
442
     * @param int|null $seed
443
     * @return array
444
     */
445
    public static function shuffle($array, $seed = null)
446
    {
447
        if (is_null($seed)) {
448
            shuffle($array);
449
        } else {
450
            mt_srand($seed);
451
            shuffle($array);
452
            mt_srand();
453
        }
454
455
        return $array;
456
    }
457
}
458