Test Failed
Push — develop ( 425fc0...4f2be8 )
by Paul
13:11
created

Arr::consolidate()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
dl 0
loc 10
ccs 7
cts 7
cp 1
rs 10
cc 4
nc 5
nop 2
crap 4
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Helpers;
4
5
use GeminiLabs\SiteReviews\Arguments;
6
use GeminiLabs\SiteReviews\Helper;
7
8
class Arr
9
{
10 40
    public static function compare(array $arr1, array $arr2): bool
11
    {
12 40
        sort($arr1);
13 40
        sort($arr2);
14 40
        return $arr1 == $arr2;
15
    }
16
17
    /**
18
     * @param mixed $value
19
     */
20 231
    public static function consolidate($value, array $fallback = []): array
21
    {
22 231
        if ($value instanceof Arguments) {
23 1
            return $value->getArrayCopy(); // This ensures we don't convert array values.
24
        }
25 231
        if (is_object($value)) {
26 12
            $values = get_object_vars($value);
27 12
            $value = Helper::ifEmpty($values, (array) $value, $strict = true);
28
        }
29 231
        return is_array($value) ? $value : $fallback;
30
    }
31
32
    /**
33
     * @param mixed $value
34
     * @param mixed $callback
35
     */
36 131
    public static function convertFromString($value, $callback = null): array
37
    {
38 131
        if (is_scalar($value)) {
39 130
            $value = array_map('trim', explode(',', Cast::toString($value)));
40
        }
41 131
        $callback = Helper::ifEmpty(Cast::toString($callback), Helper::class.'::isNotEmpty');
42 131
        return static::reindex(array_filter((array) $value, $callback));
43
    }
44
45 142
    public static function flatten(array $array, bool $flattenValue = false, string $prefix = ''): array
46
    {
47 142
        $result = [];
48 142
        foreach ($array as $key => $value) {
49 142
            $newKey = ltrim("{$prefix}.{$key}", '.');
50 142
            if (static::isIndexedAndFlat($value)) {
51 38
                $value = Helper::ifTrue(!$flattenValue, $value,
52 38
                    fn () => '['.implode(', ', $value).']'
53 38
                );
54 142
            } elseif (is_array($value)) {
55 38
                $result = array_merge($result, static::flatten($value, $flattenValue, $newKey));
56 38
                continue;
57
            }
58 142
            $result[$newKey] = $value;
59
        }
60 142
        return $result;
61
    }
62
63
    /**
64
     * Get a value from an array of values using a dot-notation path as reference.
65
     *
66
     * @param mixed      $data
67
     * @param string|int $path
68
     * @param mixed      $fallback
69
     *
70
     * @return mixed
71
     */
72 228
    public static function get($data, $path = '', $fallback = '')
73
    {
74 228
        $data = static::consolidate($data);
75 228
        $keys = explode('.', (string) $path);
76 228
        $result = $fallback;
77 228
        foreach ($keys as $key) {
78 228
            if (!isset($data[$key])) {
79 212
                return $fallback;
80
            }
81 227
            if (is_object($data[$key])) {
82 2
                $result = $data[$key];
83 2
                $data = static::consolidate($result);
84 2
                continue;
85
            }
86 227
            $result = $data[$key];
87 227
            $data = $result;
88
        }
89 227
        return $result;
90
    }
91
92
    /**
93
     * @param mixed      $data
94
     * @param string|int $path
95
     * @param mixed      $fallback
96
     *
97
     * @return mixed
98
     */
99 70
    public static function getAs(string $cast, $data, $path = '', $fallback = '')
100
    {
101 70
        return Cast::to($cast, static::get($data, $path, $fallback));
102
    }
103
104
    /**
105
     * @param string|int $key
106
     */
107 1
    public static function insertAfter($key, array $array, array $insert): array
108
    {
109 1
        return static::insert($array, $insert, $key, 'after');
110
    }
111
112
    /**
113
     * @param string|int $key
114
     */
115 1
    public static function insertBefore($key, array $array, array $insert): array
116
    {
117 1
        return static::insert($array, $insert, $key, 'before');
118
    }
119
120
    /**
121
     * @param string|int $key
122
     */
123 2
    public static function insert(array $array, array $insert, $key, string $position = 'before'): array
124
    {
125 2
        $keyPosition = array_search($key, array_keys($array));
126 2
        if (false !== $keyPosition) {
127 2
            $keyPosition = Cast::toInt($keyPosition);
128 2
            if ('after' === $position) {
129 1
                ++$keyPosition;
130
            }
131 2
            $result = array_slice($array, 0, $keyPosition);
132 2
            $result = array_merge($result, $insert);
133 2
            return array_merge($result, array_slice($array, $keyPosition));
134
        }
135 2
        return array_merge($array, $insert);
136
    }
137
138
    /**
139
     * @param mixed $array
140
     */
141 218
    public static function isIndexedAndFlat($array): bool
142
    {
143 218
        if (!is_array($array) || array_filter($array, 'is_array')) {
144 166
            return false;
145
        }
146 218
        return wp_is_numeric_array($array);
147
    }
148
149 1
    public static function prefixKeys(array $values, string $prefix = '_'): array
150
    {
151 1
        $result = [];
152 1
        foreach ($values as $key => $value) {
153 1
            $key = trim($key);
154 1
            if (!str_starts_with($key, $prefix)) {
155 1
                $key = $prefix.$key;
156
            }
157 1
            $result[$key] = $value;
158
        }
159 1
        return $result;
160
    }
161
162
    /**
163
     * @param mixed $value
164
     * @param mixed $key
165
     */
166 46
    public static function prepend(array $array, $value, $key = null): array
167
    {
168 46
        if (!is_null($key)) {
169 6
            return [$key => $value] + $array;
170
        }
171 42
        array_unshift($array, $value);
172 42
        return $array;
173
    }
174
175 132
    public static function reindex(array $array): array
176
    {
177 132
        return static::isIndexedAndFlat($array) ? array_values($array) : $array;
178
    }
179
180
    /**
181
     * Unset a value from an array of values using a dot-notation path as reference.
182
     *
183
     * @param mixed $data
184
     */
185 1
    public static function remove($data, string $path = ''): array
186
    {
187 1
        $data = static::consolidate($data);
188 1
        $keys = explode('.', $path);
189 1
        $last = array_pop($keys);
190 1
        $pointer = &$data;
191 1
        foreach ($keys as $key) {
192 1
            if (is_array(static::get($pointer, $key))) {
193 1
                $pointer = &$pointer[$key];
194
            }
195
        }
196 1
        unset($pointer[$last]);
197 1
        return $data;
198
    }
199
200 136
    public static function removeEmptyValues(array $array): array
201
    {
202 136
        $result = [];
203 136
        foreach ($array as $key => $value) {
204 136
            if (Helper::isEmpty($value)) {
205 134
                continue;
206
            }
207 136
            $result[$key] = Helper::ifTrue(!is_array($value), $value,
208 136
                fn () => static::removeEmptyValues($value)
209 136
            );
210
        }
211 136
        return $result;
212
    }
213
214 160
    public static function restrictKeys(array $array, array $allowedKeys): array
215
    {
216 160
        return array_intersect_key($array, array_fill_keys($allowedKeys, ''));
217
    }
218
219
    /**
220
     * Search a multidimensional array by key value.
221
     *
222
     * @param mixed      $needle
223
     * @param array      $haystack
224
     * @param int|string $key
225
     *
226
     * @return array|false
227
     */
228 42
    public static function searchByKey($needle, $haystack, $key)
229
    {
230 42
        if (!is_array($haystack) || empty($haystack)) {
231 1
            return false;
232
        }
233 42
        $keys = array_keys($haystack);
234 42
        $values = array_column($haystack, $key);
235 42
        if (count($keys) !== count($values)) {
236 1
            return false; // Avoid array_combine failure
237
        }
238 42
        $column = array_combine($keys, $values);
239 42
        $index = array_search($needle, $column, true);
240 42
        return false !== $index ? $haystack[$index] ?? false : false;
241
    }
242
243
    /**
244
     * Set a value to an array of values using a dot-notation path as reference.
245
     *
246
     * @param mixed $value
247
     */
248 121
    public static function set(array $data, string $path, $value): array
249
    {
250 121
        $token = strtok($path, '.');
251 121
        if (false === $token) {
252 1
            return $data; // abort since no path was given
253
        }
254 121
        $ref = &$data;
255 121
        while (false !== $token) {
256 121
            if (is_object($ref)) {
257
                $ref = &$ref->$token;
258
            } else {
259 121
                $ref = static::consolidate($ref);
260 121
                $ref = &$ref[$token];
261
            }
262 121
            $token = strtok('.');
263
        }
264 121
        $ref = $value;
265 121
        return $data;
266
    }
267
268 120
    public static function unflatten(array $array): array
269
    {
270 120
        $results = [];
271 120
        foreach ($array as $path => $value) {
272 120
            $results = static::set($results, $path, $value);
273
        }
274 120
        return $results;
275
    }
276
277 153
    public static function unique(array $values): array
278
    {
279 153
        return Helper::ifTrue(!static::isIndexedAndFlat($values), $values,
280 153
            fn () => array_filter(array_unique($values)) // we do not want to reindex the array!
281 153
        );
282
    }
283
284
    /**
285
     * This reindexes the array!
286
     *
287
     * @param array|string $values
288
     */
289 48
    public static function uniqueInt($values, bool $absint = true): array
290
    {
291 48
        $values = array_filter(static::convertFromString($values), 'is_numeric');
292 48
        $values = array_map('intval', $values);
293 48
        if ($absint) {
294 48
            $values = array_filter($values, fn ($value) => $value > 0);
295
        }
296 48
        return array_values(array_unique($values));
297
    }
298
299 18
    public static function unprefixKeys(array $values, string $prefix = '_'): array
300
    {
301 18
        $results = [];
302 18
        foreach ($values as $key => $value) {
303 1
            $key = trim($key);
304 1
            if ($key !== $prefix && str_starts_with($key, $prefix)) {
305 1
                $key = substr($key, strlen($prefix));
306
            }
307 1
            $results[$key] = $value;
308
        }
309 18
        return $results;
310
    }
311
}
312