Passed
Push — master ( 800dec...fc1f17 )
by Xu
05:50
created

ArrayHelper::build()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @link http://www.tintsoft.com/
4
 * @copyright Copyright (c) 2012 TintSoft Technology Co. Ltd.
5
 * @license http://www.tintsoft.com/license/
6
 */
7
8
namespace yuncms\helpers;
9
10
use ArrayAccess;
11
use Closure;
12
13
/**
14
 * Class ArrayHelper
15
 * @package yuncms\helpers
16
 * @author Tongle Xu <[email protected]>
17
 */
18
class ArrayHelper extends \yii\helpers\ArrayHelper
19
{
20
21
    /**
22
     * Add an element to an array using "dot" notation if it doesn't exist.
23
     *
24
     * @param array $array
25
     * @param string $key
26
     * @param mixed $value
27
     * @return array
28
     */
29
    public static function add($array, $key, $value): array
30
    {
31
        if (is_null(static::get($array, $key))) {
32
            static::set($array, $key, $value);
33
        }
34
        return $array;
35
    }
36
37
    /**
38
     * Build a new array using a callback.
39
     *
40
     * @param array $array
41
     * @param Closure $callback
42
     * @return array
43
     */
44
    public static function build($array, Closure $callback): array
45
    {
46
        $results = [];
47
        foreach ($array as $key => $value) {
48
            list($innerKey, $innerValue) = call_user_func($callback, $key, $value);
49
            $results[$innerKey] = $innerValue;
50
        }
51
        return $results;
52
    }
53
54
    /**
55
     * Divide an array into two arrays. One with keys and the other with values.
56
     *
57
     * @param array $array
58
     * @return array
59
     */
60
    public static function divide($array): array
61
    {
62
        return [
63
            array_keys($array),
64
            array_values($array),
65
        ];
66
    }
67
68
    /**
69
     * Return the first element in an array passing a given truth test.
70
     *
71
     * @param array $array
72
     * @param \Closure $callback
73
     * @param mixed $default
74
     * @return mixed
75
     */
76
    public static function first($array, $callback, $default = null)
77
    {
78
        foreach ($array as $key => $value) {
79
            if (call_user_func($callback, $key, $value)) {
80
                return $value;
81
            }
82
        }
83
        return $default;
84
    }
85
86
    /**
87
     * Return the last element in an array passing a given truth test.
88
     *
89
     * @param array $array
90
     * @param Closure $callback
91
     * @param mixed $default
92
     * @return mixed
93
     */
94
    public static function last($array, $callback, $default = null)
95
    {
96
        return static::first(array_reverse($array), $callback, $default);
97
    }
98
99
    /**
100
     * Flatten a multi-dimensional array into a single level.
101
     *
102
     * @param array $array
103
     * @return array
104
     */
105
    public static function flatten($array): array
106
    {
107
        $return = [];
108
        array_walk_recursive($array, function ($x) use (&$return) {
109
            $return[] = $x;
110
        });
111
        return $return;
112
    }
113
114
    /**
115
     * Get all of the given array except for a specified array of items.
116
     *
117
     * @param array $array
118
     * @param array|string $keys
119
     * @return array
120
     */
121
    public static function except($array, $keys): array
122
    {
123
        return array_diff_key($array, array_flip((array)$keys));
124
    }
125
126
    /**
127
     * Fetch a flattened array of a nested array element.
128
     *
129
     * @param array $array
130
     * @param string $key
131
     * @return array
132
     */
133
    public static function fetch($array, $key): array
134
    {
135
        $results = [];
136
        foreach (explode('.', $key) as $segment) {
137
            $results = [];
138
            foreach ($array as $value) {
139
                $value = (array)$value;
140
                $results[] = $value[$segment];
141
            }
142
            $array = array_values($results);
143
        }
144
        return array_values($results);
145
    }
146
147
    /**
148
     * Get an item from an array using "dot" notation.
149
     *
150
     * @param array $array
151
     * @param string $key
152
     * @param mixed $default
153
     * @return mixed
154
     */
155
    public static function get($array, $key, $default = null)
156
    {
157
        if (is_null($key)) {
0 ignored issues
show
introduced by
The condition is_null($key) can never be true.
Loading history...
158
            return $array;
159
        }
160
        if (isset($array[$key])) {
161
            return $array[$key];
162
        }
163
        foreach (explode('.', $key) as $segment) {
164
            if (!is_array($array) || !array_key_exists($segment, $array)) {
165
                return $default;
166
            }
167
            $array = $array[$segment];
168
        }
169
        return $array;
170
    }
171
172
    /**
173
     * Get a subset of the items from the given array.
174
     *
175
     * @param array $array
176
     * @param array|string $keys
177
     * @return array
178
     */
179
    public static function only($array, $keys): array
180
    {
181
        return array_intersect_key($array, array_flip((array)$keys));
182
    }
183
184
    /**
185
     * Set an array item to a given value using "dot" notation.
186
     *
187
     * If no key is given to the method, the entire array will be replaced.
188
     *
189
     * @param array $array
190
     * @param string $key
191
     * @param mixed $value
192
     * @return array
193
     */
194
    public static function set(&$array, $key, $value): array
195
    {
196
        if (is_null($key)) {
0 ignored issues
show
introduced by
The condition is_null($key) can never be true.
Loading history...
197
            return $array = $value;
198
        }
199
        $keys = explode('.', $key);
200
        while (count($keys) > 1) {
201
            $key = array_shift($keys);
202
            // If the key doesn't exist at this depth, we will just create an empty array
203
            // to hold the next value, allowing us to create the arrays to hold final
204
            // values at the correct depth. Then we'll keep digging into the array.
205
            if (!isset($array[$key]) || !is_array($array[$key])) {
206
                $array[$key] = [];
207
            }
208
            $array = &$array[$key];
209
        }
210
        $array[array_shift($keys)] = $value;
211
        return $array;
212
    }
213
214
    /**
215
     * Pluck an array of values from an array.
216
     *
217
     * @param array $array
218
     * @param string $value
219
     * @param string $key
220
     * @return array
221
     */
222
    public static function pluck($array, $value, $key = null): array
223
    {
224
        $results = [];
225
        foreach ($array as $item) {
226
            $itemValue = is_object($item) ? $item->{$value} : $item[$value];
227
            // If the key is "null", we will just append the value to the array and keep
228
            // looping. Otherwise we will key the array using the value of the key we
229
            // received from the developer. Then we'll return the final array form.
230
            if (is_null($key)) {
231
                $results[] = $itemValue;
232
            } else {
233
                $itemKey = is_object($item) ? $item->{$key} : $item[$key];
234
                $results[$itemKey] = $itemValue;
235
            }
236
        }
237
        return $results;
238
    }
239
240
    /**
241
     * Get a value from the array, and remove it.
242
     *
243
     * @param array $array
244
     * @param string $key
245
     * @param mixed $default
246
     * @return mixed
247
     */
248
    public static function pull(&$array, $key, $default = null)
249
    {
250
        $value = static::get($array, $key, $default);
251
        static::forget($array, $key);
252
        return $value;
253
    }
254
255
    /**
256
     * Remove one or many array items from a given array using "dot" notation.
257
     *
258
     * @param array $array
259
     * @param array|string $keys
260
     */
261
    public static function forget(&$array, $keys)
262
    {
263
        $original = &$array;
264
        foreach ((array)$keys as $key) {
265
            $parts = explode('.', $key);
266
            while (count($parts) > 1) {
267
                $part = array_shift($parts);
268
                if (isset($array[$part]) && is_array($array[$part])) {
269
                    $array = &$array[$part];
270
                }
271
            }
272
            unset($array[array_shift($parts)]);
273
            // clean up after each pass
274
            $array = &$original;
275
        }
276
    }
277
278
    /**
279
     * Sort the array using the given Closure.
280
     *
281
     * @param array $array
282
     * @param Closure $callback
283
     *
284
     * @return array
285
     */
286
    public static function sort($array, Closure $callback):array
287
    {
288
        $results = [];
289
        foreach ($array as $key => $value) {
290
            $results[$key] = $callback($value);
291
        }
292
        return $results;
293
    }
294
295
    /**
296
     * Filter the array using the given Closure.
297
     *
298
     * @param array $array
299
     * @param Closure $callback
300
     * @return array
301
     */
302
    public static function where($array, Closure $callback):array
303
    {
304
        $filtered = [];
305
        foreach ($array as $key => $value) {
306
            if (call_user_func($callback, $key, $value)) {
307
                $filtered[$key] = $value;
308
            }
309
        }
310
        return $filtered;
311
    }
312
313
    /**
314
     * Prepends or appends a value to an array.
315
     *
316
     * @param array &$array the array to be prepended/appended to
317
     * @param mixed $value the value to prepend/append to the array
318
     * @param bool $prepend `true` will prepend the value; `false` will append it
319
     */
320
    public static function prependOrAppend(array &$array, $value, bool $prepend)
321
    {
322
        if ($prepend) {
323
            array_unshift($array, $value);
324
        } else {
325
            $array[] = $value;
326
        }
327
    }
328
329
    /**
330
     * Filters an array to only the values where a given key (the name of a
331
     * sub-array key or sub-object property) is set to a given value.
332
     *
333
     * Array keys are preserved.
334
     *
335
     * @param array|\Traversable $array the array that needs to be indexed or grouped
336
     * @param string|\Closure $key the column name or anonymous function which result will be used to index the array
337
     * @param mixed $value the value that $key should be compared with
338
     * @param bool $strict whether a strict type comparison should be used when checking array element values against $value
339
     *
340
     * @return array the filtered array
341
     */
342
    public static function filterByValue($array, $key, $value, bool $strict = false): array
343
    {
344
        $result = [];
345
346
        foreach ($array as $i => $element) {
347
            $elementValue = static::getValue($element, $key);
348
            /** @noinspection TypeUnsafeComparisonInspection */
349
            if (($strict && $elementValue === $value) || (!$strict && $elementValue == $value)) {
350
                $result[$i] = $element;
351
            }
352
        }
353
354
        return $result;
355
    }
356
357
    /**
358
     * Filters empty strings from an array.
359
     *
360
     * @param array $arr
361
     * @return array
362
     */
363
    public static function filterEmptyStringsFromArray(array $arr): array
364
    {
365
        return array_filter($arr, function ($value): bool {
366
            return $value !== '';
367
        });
368
    }
369
370
    /**
371
     * Returns the first key in a given array.
372
     *
373
     * @param array $arr
374
     *
375
     * @return string|int|null The first key, whether that is a number (if the array is numerically indexed) or a string, or null if $arr isn’t an array, or is empty.
376
     */
377
    public static function firstKey(array $arr)
378
    {
379
        /** @noinspection LoopWhichDoesNotLoopInspection */
380
        foreach ($arr as $key => $value) {
381
            return $key;
382
        }
383
384
        return null;
385
    }
386
387
    /**
388
     * Returns the first value in a given array.
389
     *
390
     * @param array $arr
391
     *
392
     * @return mixed The first value, or null if $arr isn’t an array, or is empty.
393
     */
394
    public static function firstValue(array $arr)
395
    {
396
        return !empty($arr) ? reset($arr) : null;
397
    }
398
399
    /**
400
     * Renames an item in an array. If the new key already exists in the array and the old key doesn’t,
401
     * the array will be left unchanged.
402
     *
403
     * @param array $array the array to extract value from
404
     * @param string $oldKey old key name of the array element
405
     * @param string $newKey new key name of the array element
406
     * @param mixed $default the default value to be set if the specified old key does not exist
407
     *
408
     * @return void
409
     */
410
    public static function rename(array &$array, string $oldKey, string $newKey, $default = null)
411
    {
412
        if (!array_key_exists($newKey, $array) || array_key_exists($oldKey, $array)) {
413
            $array[$newKey] = static::remove($array, $oldKey, $default);
414
        }
415
    }
416
}