Completed
Push — master ( c29848...6d2813 )
by Gabriel
02:24
created

Arr::set()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 28
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 12
c 1
b 0
f 1
dl 0
loc 28
ccs 0
cts 13
cp 0
rs 9.2222
cc 6
nc 3
nop 3
crap 42
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
     * Get an item from an array using "dot" notation.
152
     *
153
     * @param \ArrayAccess|array $array
154
     * @param string|int|null $key
155
     * @param mixed $default
156
     * @return mixed
157
     */
158
    public static function get($array, $key, $default = null)
159
    {
160
        if (!static::accessible($array)) {
161
            return value($default);
162
        }
163
164
        if (is_null($key)) {
165
            return $array;
166
        }
167
168
        if (static::exists($array, $key)) {
169
            return $array[$key];
170
        }
171
172
        if (strpos($key, '.') === false) {
173
            return $array[$key] ?? value($default);
174
        }
175
176
        foreach (explode('.', $key) as $segment) {
177
            if (static::accessible($array) && static::exists($array, $segment)) {
178
                $array = $array[$segment];
179
            } else {
180
                return value($default);
181
            }
182
        }
183
184
        return $array;
185
    }
186
187
188
    /**
189
     * Check if an item or items exist in an array using "dot" notation.
190
     *
191
     * @param \ArrayAccess|array $array
192
     * @param string|array $keys
193
     * @return bool
194
     */
195
    public static function has($array, $keys)
196
    {
197
        $keys = (array)$keys;
198
199
        if (!$array || $keys === []) {
200
            return false;
201
        }
202
203
        foreach ($keys as $key) {
204
            $subKeyArray = $array;
205
206
            if (static::exists($array, $key)) {
207
                continue;
208
            }
209
210
            foreach (explode('.', $key) as $segment) {
211
                if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) {
212
                    $subKeyArray = $subKeyArray[$segment];
213
                } else {
214
                    return false;
215
                }
216
            }
217
        }
218
219
        return true;
220
    }
221
    
222
    /**
223
     * Filter the array using the given callback.
224
     *
225
     * @param array $array
226
     * @param callable $callback
227
     * @return array
228
     */
229
    public static function where($array, callable $callback)
230
    {
231
        return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH);
232
    }
233
234
    /**
235
     * If the given value is not an array, wrap it in one.
236
     *
237
     * @param mixed $value
238
     * @return array
239
     */
240
    public static function wrap($value)
241
    {
242
        return !is_array($value) ? [$value] : $value;
243
    }
244
245
    /**
246
     * Get a subset of the items from the given array.
247
     *
248
     * @param array $array
249
     * @param array|string $keys
250
     * @return array
251
     */
252
    public static function only($array, $keys)
253
    {
254
        return array_intersect_key($array, array_flip((array)$keys));
255
    }
256
257
    /**
258
     * Pluck an array of values from an array.
259
     *
260
     * @param array $array
261
     * @param string|array $value
262
     * @param string|array|null $key
263
     * @return array
264
     */
265 1
    public static function pluck($array, $value, $key = null)
266
    {
267 1
        $results = [];
268 1
        [$value, $key] = static::explodePluckParameters($value, $key);
269 1
        foreach ($array as $item) {
270 1
            $itemValue = data_get($item, $value);
271
272
            // If the key is "null", we will just append the value to the array and keep
273
            // looping. Otherwise we will key the array using the value of the key we
274
            // received from the developer. Then we'll return the final array form.
275 1
            if (is_null($key)) {
276 1
                $results[] = $itemValue;
277
            } else {
278
                $itemKey = data_get($item, $key);
279
                if (is_object($itemKey) && method_exists($itemKey, '__toString')) {
280
                    $itemKey = (string)$itemKey;
281
                }
282
                $results[$itemKey] = $itemValue;
283
            }
284
        }
285 1
        return $results;
286
    }
287
288
    /**
289
     * Explode the "value" and "key" arguments passed to "pluck".
290
     *
291
     * @param string|array $value
292
     * @param string|array|null $key
293
     * @return array
294
     */
295 1
    protected static function explodePluckParameters($value, $key)
296
    {
297 1
        $value = is_string($value) ? explode('.', $value) : $value;
298 1
        $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
299 1
        return [$value, $key];
300
    }
301
302
    /**
303
     * Push an item onto the beginning of an array.
304
     *
305
     * @param array $array
306
     * @param mixed $value
307
     * @param mixed $key
308
     * @return array
309
     */
310
    public static function prepend($array, $value, $key = null)
311
    {
312
        if (is_null($key)) {
313
            array_unshift($array, $value);
314
        } else {
315
            $array = [$key => $value] + $array;
316
        }
317
318
        return $array;
319
    }
320
321
    /**
322
     * Get a value from the array, and remove it.
323
     *
324
     * @param array $array
325
     * @param string $key
326
     * @param mixed $default
327
     * @return mixed
328
     */
329
    public static function pull(&$array, $key, $default = null)
330
    {
331
        $value = static::get($array, $key, $default);
332
333
        static::forget($array, $key);
334
335
        return $value;
336
    }
337
338
339
    /**
340
     * Get one or a specified number of random values from an array.
341
     *
342
     * @param array $array
343
     * @param int|null $number
344
     * @return mixed
345
     *
346
     * @throws \InvalidArgumentException
347
     */
348
    public static function random($array, $number = null)
349
    {
350
        $requested = is_null($number) ? 1 : $number;
351
352
        $count = count($array);
353
354
        if ($requested > $count) {
355
            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...
356
                "You requested {$requested} items, but there are only {$count} items available."
357
            );
358
        }
359
360
        if (is_null($number)) {
361
            return $array[array_rand($array)];
362
        }
363
364
        if ((int)$number === 0) {
365
            return [];
366
        }
367
368
        $keys = array_rand($array, $number);
369
370
        $results = [];
371
372
        foreach ((array)$keys as $key) {
373
            $results[] = $array[$key];
374
        }
375
376
        return $results;
377
    }
378
379
    /**
380
     * Set an array item to a given value using "dot" notation.
381
     *
382
     * If no key is given to the method, the entire array will be replaced.
383
     *
384
     * @param array $array
385
     * @param string|null $key
386
     * @param mixed $value
387
     * @return array
388
     */
389
    public static function set(&$array, $key, $value)
390
    {
391
        if (is_null($key)) {
392
            return $array = $value;
393
        }
394
395
        $keys = explode('.', $key);
396
397
        foreach ($keys as $i => $key) {
0 ignored issues
show
introduced by
$key is overwriting one of the parameters of this function.
Loading history...
398
            if (count($keys) === 1) {
399
                break;
400
            }
401
402
            unset($keys[$i]);
403
404
            // If the key doesn't exist at this depth, we will just create an empty array
405
            // to hold the next value, allowing us to create the arrays to hold final
406
            // values at the correct depth. Then we'll keep digging into the array.
407
            if (!isset($array[$key]) || !is_array($array[$key])) {
408
                $array[$key] = [];
409
            }
410
411
            $array = &$array[$key];
412
        }
413
414
        $array[array_shift($keys)] = $value;
415
416
        return $array;
417
    }
418
419
    /**
420
     * Shuffle the given array and return the result.
421
     *
422
     * @param array $array
423
     * @param int|null $seed
424
     * @return array
425
     */
426
    public static function shuffle($array, $seed = null)
427
    {
428
        if (is_null($seed)) {
429
            shuffle($array);
430
        } else {
431
            mt_srand($seed);
432
            shuffle($array);
433
            mt_srand();
434
        }
435
436
        return $array;
437
    }
438
}
439