Test Failed
Push — develop ( 33b521...cdbd76 )
by Paul
10:16 queued 21s
created

Arr::restrictKeys()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
ccs 1
cts 1
cp 1
cc 1
nc 1
nop 2
crap 1
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 47
    public static function compare(array $arr1, array $arr2): bool
11
    {
12 47
        sort($arr1);
13 47
        sort($arr2);
14 47
        return $arr1 == $arr2;
15
    }
16
17
    /**
18
     * @param mixed $value
19
     */
20 224
    public static function consolidate($value, array $fallback = []): array
21
    {
22 224
        if ($value instanceof Arguments) {
23 8
            return $value->getArrayCopy(); // This ensures we don't convert array values.
24
        }
25 224
        if (is_object($value)) {
26 17
            $values = get_object_vars($value);
27 17
            $value = Helper::ifEmpty($values, (array) $value, $strict = true);
28
        }
29 224
        return is_array($value) ? $value : $fallback;
30
    }
31
32
    /**
33
     * @param mixed $value
34
     * @param mixed $callback
35
     */
36 130
    public static function convertFromString($value, $callback = null): array
37
    {
38 130
        if (is_scalar($value)) {
39 129
            $value = array_map('trim', explode(',', Cast::toString($value)));
40
        }
41 130
        $callback = Helper::ifEmpty(Cast::toString($callback), Helper::class.'::isNotEmpty');
42 130
        return static::reindex(array_filter((array) $value, $callback));
43
    }
44
45 143
    public static function flatten(array $array, bool $flattenValue = false, string $prefix = ''): array
46
    {
47 143
        $result = [];
48 143
        foreach ($array as $key => $value) {
49 143
            $newKey = ltrim("{$prefix}.{$key}", '.');
50 143
            if (static::isIndexedAndFlat($value)) {
51 45
                $value = Helper::ifTrue(!$flattenValue, $value,
52 45
                    fn () => '['.implode(', ', $value).']'
53 45
                );
54 143
            } elseif (is_array($value)) {
55 45
                $result = array_merge($result, static::flatten($value, $flattenValue, $newKey));
56 45
                continue;
57
            }
58 143
            $result[$newKey] = $value;
59
        }
60 143
        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 221
    public static function get($data, $path = '', $fallback = '')
73
    {
74 221
        $data = static::consolidate($data);
75 221
        $keys = explode('.', (string) $path);
76 221
        $result = $fallback;
77 221
        foreach ($keys as $key) {
78 221
            if (!isset($data[$key])) {
79 208
                return $fallback;
80
            }
81 220
            if (is_object($data[$key])) {
82 9
                $result = $data[$key];
83 9
                $data = static::consolidate($result);
84 9
                continue;
85
            }
86 220
            $result = $data[$key];
87 220
            $data = $result;
88
        }
89 220
        return $result;
90
    }
91
92
    /**
93
     * @param mixed      $data
94
     * @param string|int $path
95
     * @param mixed      $fallback
96
     *
97
     * @return mixed
98
     */
99 50
    public static function getAs(string $cast, $data, $path = '', $fallback = '')
100
    {
101 50
        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 215
    public static function isIndexedAndFlat($array): bool
142
    {
143 215
        if (!is_array($array) || array_filter($array, 'is_array')) {
144 167
            return false;
145
        }
146 214
        return wp_is_numeric_array($array);
147
    }
148
149 26
    public static function prefixKeys(array $values, string $prefix = '_'): array
150
    {
151 26
        $result = [];
152 26
        foreach ($values as $key => $value) {
153 26
            $key = trim($key);
154 2
            if (!str_starts_with($key, $prefix)) {
155 2
                $key = $prefix.$key;
156 2
            }
157
            $result[$key] = $value;
158 2
        }
159
        return $result;
160 26
    }
161
162
    /**
163
     * @param mixed $value
164
     * @param mixed $key
165
     */
166
    public static function prepend(array $array, $value, $key = null): array
167 50
    {
168
        if (!is_null($key)) {
169 50
            return [$key => $value] + $array;
170 13
        }
171
        array_unshift($array, $value);
172 46
        return $array;
173 46
    }
174
175
    public static function reindex(array $array): array
176 131
    {
177
        return static::isIndexedAndFlat($array) ? array_values($array) : $array;
178 131
    }
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
    public static function remove($data, string $path = ''): array
186 1
    {
187
        $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 1
            }
195
        }
196
        unset($pointer[$last]);
197 1
        return $data;
198 1
    }
199
200
    public static function removeEmptyValues(array $array): array
201 136
    {
202
        $result = [];
203 136
        foreach ($array as $key => $value) {
204 136
            if (Helper::isEmpty($value)) {
205 136
                continue;
206 128
            }
207
            $result[$key] = Helper::ifTrue(!is_array($value), $value,
208 136
                fn () => static::removeEmptyValues($value)
209 136
            );
210 136
        }
211
        return $result;
212 136
    }
213
214
    public static function restrictKeys(array $array, array $allowedKeys): array
215 160
    {
216
        return array_intersect_key($array, array_fill_keys($allowedKeys, ''));
217 160
    }
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|iterable|false
227
     */
228
    public static function searchByKey($needle, $haystack, $key)
229 45
    {
230
        if (!is_array($haystack) || array_diff_key($haystack, array_filter($haystack, 'is_iterable'))) {
231 45
            return false;
232
        }
233
        $index = array_search($needle, wp_list_pluck($haystack, $key));
234 45
        if (false !== $index) {
235 45
            return $haystack[$index];
236 44
        }
237
        return false;
238 45
    }
239
240
    /**
241
     * Set a value to an array of values using a dot-notation path as reference.
242
     *
243
     * @param mixed $value
244
     */
245
    public static function set(array $data, string $path, $value): array
246
    {
247 125
        $token = strtok($path, '.');
248
        if (false === $token) {
249 125
            return $data; // abort since no path was given
250 125
        }
251 125
        $ref = &$data;
252 125
        while (false !== $token) {
253
            if (is_object($ref)) {
254
                $ref = &$ref->$token;
255 125
            } else {
256 125
                $ref = static::consolidate($ref);
257
                $ref = &$ref[$token];
258 125
            }
259
            $token = strtok('.');
260 125
        }
261 125
        $ref = $value;
262
        return $data;
263
    }
264 124
265
    public static function unflatten(array $array): array
266 124
    {
267 124
        $results = [];
268 124
        foreach ($array as $path => $value) {
269
            $results = static::set($results, $path, $value);
270 124
        }
271
        return $results;
272
    }
273 154
274
    public static function unique(array $values): array
275 154
    {
276 154
        return Helper::ifTrue(!static::isIndexedAndFlat($values), $values,
277 154
            fn () => array_filter(array_unique($values)) // we do not want to reindex the array!
278
        );
279
    }
280
281
    /**
282
     * This reindexes the array!
283
     *
284
     * @param array|string $values
285 51
     */
286
    public static function uniqueInt($values, bool $absint = true): array
287 51
    {
288 51
        $values = array_filter(static::convertFromString($values), 'is_numeric');
289 51
        $values = array_map('intval', $values);
290 51
        if ($absint) {
291
            $values = array_filter($values, fn ($value) => $value > 0);
292 51
        }
293
        return array_values(array_unique($values));
294
    }
295 25
296
    public static function unprefixKeys(array $values, string $prefix = '_'): array
297 25
    {
298
        $results = [];
299
        foreach ($values as $key => $value) {
300
            $key = trim($key);
301
            if ($key !== $prefix && str_starts_with($key, $prefix)) {
302
                $key = substr($key, strlen($prefix));
303
            }
304
            $results[$key] = $value;
305
        }
306
        return $results;
307
    }
308
}
309