PluginProbe
PostNL for WooCommerce / 4.0.1
PostNL for WooCommerce v4.0.1
5.9.12 5.9.11 5.9.10 5.9.9 5.9.8 5.9.7 5.9.6 trunk 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.1.4 3.1.5 3.1.6 3.1.7 4.0.0 4.0.1 4.0.2 4.3.2 4.3.3 4.4.0 4.4.1 All 72 releases
woo-postnl / includes / vendor / myparcelnl / sdk / src / Support / Arr.php

Arr.php in PostNL for WooCommerce 4.0.1, at includes/vendor/myparcelnl/sdk/src/Support/Arr.php

704 lines 17.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php declare(strict_types=1); /** @noinspection PhpUndefinedClassInspection */
2
3 namespace MyParcelNL\Sdk\src\Support;
4
5 use ArrayAccess;
6 use InvalidArgumentException;
7
8 class Arr
9 {
10 /**
11 * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
12 * keys to arrays rather than overwriting the value in the first array with the duplicate
13 * value in the second array, as array_merge does. I.e., with array_merge_recursive,
14 * this happens (documented behavior):
15 *
16 * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
17 * => array('key' => array('org value', 'new value'));
18 *
19 * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
20 * Matching keys' values in the second array overwrite those in the first array, as is the
21 * case with array_merge, i.e.:
22 *
23 * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
24 * => array('key' => array('new value'));
25 *
26 * Parameters are passed by reference, though only for performance reasons. They're not
27 * altered by this function.
28 *
29 * @param array $array1
30 * @param array $array2
31 *
32 * @return array
33 * @author Daniel <daniel (at) danielsmedegaardbuus (dot) dk>
34 * @author Gabriel Sobrinho <gabriel (dot) sobrinho (at) gmail (dot) com>
35 * @link https://www.php.net/manual/en/function.array-merge-recursive.php#92195
36 */
37 public static function arrayMergeRecursiveDistinct(array &$array1, array &$array2)
38 {
39 $merged = $array1;
40
41 foreach ($array2 as $key => &$value) {
42 if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
43 $merged[$key] = self::arrayMergeRecursiveDistinct($merged[$key], $value);
44 } else {
45 $merged[$key] = $value;
46 }
47 }
48
49 return $merged;
50 }
51
52 /**
53 * @param mixed $array1
54 * @param mixed $array2
55 *
56 * @return array
57 */
58 public static function mergeAfterEachOther($array1, $array2): array
59 {
60 $result = [];
61 $array1 = array_values($array1);
62 $array2 = array_values($array2);
63
64 foreach ($array1 as $index => $value1) {
65 $result[] = $value1;
66 $result[] = $array2[$index];
67 }
68
69 return $result;
70 }
71
72 /**
73 * Determine whether the given value is array accessible.
74 *
75 * @param mixed $value
76 * @return bool
77 */
78 public static function accessible($value)
79 {
80 return is_array($value) || $value instanceof ArrayAccess;
81 }
82
83 /**
84 * Add an element to an array using "dot" notation if it doesn't exist.
85 *
86 * @param array $array
87 * @param string $key
88 * @param mixed $value
89 * @return array
90 */
91 public static function add($array, $key, $value)
92 {
93 if (is_null(static::get($array, $key))) {
94 static::set($array, $key, $value);
95 }
96
97 return $array;
98 }
99
100 /**
101 * Collapse an array of arrays into a single array.
102 *
103 * @param array $array
104 * @return array
105 */
106 public static function collapse($array)
107 {
108 $results = [];
109
110 foreach ($array as $values) {
111 if ($values instanceof CollectionProxy) {
112 $values = $values->all();
113 } elseif (! is_array($values)) {
114 continue;
115 }
116
117 $results = array_merge($results, $values);
118 }
119
120 return $results;
121 }
122
123 /**
124 * Cross join the given arrays, returning all possible permutations.
125 *
126 * @param array ...$arrays
127 * @return array
128 */
129 public static function crossJoin(...$arrays)
130 {
131 $results = [[]];
132
133 foreach ($arrays as $index => $array) {
134 $append = [];
135
136 foreach ($results as $product) {
137 foreach ($array as $item) {
138 $product[$index] = $item;
139
140 $append[] = $product;
141 }
142 }
143
144 $results = $append;
145 }
146
147 return $results;
148 }
149
150 /**
151 * Divide an array into two arrays. One with keys and the other with values.
152 *
153 * @param array $array
154 * @return array
155 */
156 public static function divide($array)
157 {
158 return [array_keys($array), array_values($array)];
159 }
160
161 /**
162 * Flatten a multi-dimensional associative array with dots.
163 *
164 * @param array $array
165 * @param string $prepend
166 * @return array
167 */
168 public static function dot($array, $prepend = '')
169 {
170 $results = [];
171
172 foreach ($array as $key => $value) {
173 if (is_array($value) && ! empty($value)) {
174 $results = array_merge($results, static::dot($value, $prepend . $key . '.'));
175 } else {
176 $results[$prepend . $key] = $value;
177 }
178 }
179
180 return $results;
181 }
182
183 /**
184 * Get all of the given array except for a specified array of keys.
185 *
186 * @param array $array
187 * @param array|string $keys
188 * @return array
189 */
190 public static function except($array, $keys)
191 {
192 static::forget($array, $keys);
193
194 return $array;
195 }
196
197 /**
198 * Determine if the given key exists in the provided array.
199 *
200 * @param \ArrayAccess|array $array
201 * @param string|int $key
202 * @return bool
203 */
204 public static function exists($array, $key)
205 {
206 if ($array instanceof ArrayAccess) {
207 return $array->offsetExists($key);
208 }
209
210 return array_key_exists($key, $array);
211 }
212
213 /**
214 * Return the first element in an array passing a given truth test.
215 *
216 * @param array $array
217 * @param callable|null $callback
218 * @param mixed $default
219 * @return mixed
220 */
221 public static function first($array, callable $callback = null, $default = null)
222 {
223 if (is_null($callback)) {
224 if (empty($array)) {
225 return (new Helpers())->value($default);
226 }
227
228 foreach ($array as $item) {
229 return $item;
230 }
231 }
232
233 foreach ($array as $key => $value) {
234 if (call_user_func($callback, $value, $key)) {
235 return $value;
236 }
237 }
238
239 return (new Helpers())->value($default);
240 }
241
242 /**
243 * Return the last element in an array passing a given truth test.
244 *
245 * @param array $array
246 * @param callable|null $callback
247 * @param mixed $default
248 * @return mixed
249 */
250 public static function last($array, callable $callback = null, $default = null)
251 {
252 if (is_null($callback)) {
253 return empty($array) ? (new Helpers())->value($default) : end($array);
254 }
255
256 return static::first(array_reverse($array, true), $callback, $default);
257 }
258
259 /**
260 * Flatten a multi-dimensional array into a single level.
261 *
262 * @param array $array
263 * @param int $depth
264 * @return array
265 */
266 public static function flatten($array, $depth = INF)
267 {
268 $result = [];
269
270 foreach ($array as $item) {
271 $item = $item instanceof CollectionProxy ? $item->all() : $item;
272
273 if (! is_array($item)) {
274 $result[] = $item;
275 } elseif ($depth === 1) {
276 $result = array_merge($result, array_values($item));
277 } else {
278 $result = array_merge($result, static::flatten($item, $depth - 1));
279 }
280 }
281
282 return $result;
283 }
284
285 /**
286 * Remove one or many array items from a given array using "dot" notation.
287 *
288 * @param array $array
289 * @param array|string $keys
290 * @return void
291 */
292 public static function forget(&$array, $keys)
293 {
294 $original = &$array;
295
296 $keys = (array) $keys;
297
298 if (count($keys) === 0) {
299 return;
300 }
301
302 foreach ($keys as $key) {
303 // if the exact key exists in the top-level, remove it
304 if (static::exists($array, $key)) {
305 unset($array[$key]);
306
307 continue;
308 }
309
310 $parts = explode('.', $key);
311
312 // clean up before each pass
313 $array = &$original;
314
315 while (count($parts) > 1) {
316 $part = array_shift($parts);
317
318 if (isset($array[$part]) && is_array($array[$part])) {
319 $array = &$array[$part];
320 } else {
321 continue 2;
322 }
323 }
324
325 unset($array[array_shift($parts)]);
326 }
327 }
328
329 /**
330 * Get an item from an array using "dot" notation.
331 *
332 * @param \ArrayAccess|array $array
333 * @param string $key
334 * @param mixed $default
335 * @return mixed
336 */
337 public static function get($array, $key, $default = null)
338 {
339 if (! static::accessible($array)) {
340 return (new Helpers())->value($default);
341 }
342
343 if (is_null($key) || empty($key)) {
344 return $array;
345 }
346
347 if (static::exists($array, $key)) {
348 return $array[$key];
349 }
350
351 if (strpos($key, '.') === false) {
352 if (isset($array[$key])) {
353 return $array[$key];
354 } else {
355 return (new Helpers())->value($default);
356 }
357 }
358
359 foreach (explode('.', $key) as $segment) {
360 if (static::accessible($array) && static::exists($array, $segment)) {
361 $array = $array[$segment];
362 } else {
363 return (new Helpers())->value($default);
364 }
365 }
366
367 return $array;
368 }
369
370 /**
371 * Check if an item or items exist in an array using "dot" notation.
372 *
373 * @param \ArrayAccess|array $array
374 * @param string|array $keys
375 * @return bool
376 */
377 public static function has($array, $keys)
378 {
379 if (is_null($keys)) {
380 return false;
381 }
382
383 $keys = (array) $keys;
384
385 if (! $array) {
386 return false;
387 }
388
389 if ($keys === []) {
390 return false;
391 }
392
393 foreach ($keys as $key) {
394 $subKeyArray = $array;
395
396 if (static::exists($array, $key)) {
397 continue;
398 }
399
400 foreach (explode('.', $key) as $segment) {
401 if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) {
402 $subKeyArray = $subKeyArray[$segment];
403 } else {
404 return false;
405 }
406 }
407 }
408
409 return true;
410 }
411
412 /**
413 * Determines if an array is associative.
414 *
415 * An array is "associative" if it doesn't have sequential numerical keys beginning with zero.
416 *
417 * @param array $array
418 * @return bool
419 */
420 public static function isAssoc(array $array)
421 {
422 $keys = array_keys($array);
423
424 return array_keys($keys) !== $keys;
425 }
426
427 /**
428 * Get a subset of the items from the given array.
429 *
430 * @param array $array
431 * @param array|string $keys
432 * @return array
433 */
434 public static function only($array, $keys)
435 {
436 return array_intersect_key($array, array_flip((array) $keys));
437 }
438
439 /**
440 * Pluck an array of values from an array.
441 *
442 * @param array $array
443 * @param string|array $value
444 * @param string|array|null $key
445 * @return array
446 */
447 public static function pluck($array, $value, $key = null)
448 {
449 $results = [];
450
451 list($value, $key) = static::explodePluckParameters($value, $key);
452
453 foreach ($array as $item) {
454 $itemValue = (new Helpers())->data_get($item, $value);
455
456 // If the key is "null", we will just append the value to the array and keep
457 // looping. Otherwise we will key the array using the value of the key we
458 // received from the developer. Then we'll return the final array form.
459 if (is_null($key)) {
460 $results[] = $itemValue;
461 } else {
462 $itemKey = (new Helpers())->data_get($item, $key);
463
464 if (is_object($itemKey) && method_exists($itemKey, '__toString')) {
465 $itemKey = (string) $itemKey;
466 }
467
468 $results[$itemKey] = $itemValue;
469 }
470 }
471
472 return $results;
473 }
474
475 /**
476 * Explode the "value" and "key" arguments passed to "pluck".
477 *
478 * @param string|array $value
479 * @param string|array|null $key
480 * @return array
481 */
482 protected static function explodePluckParameters($value, $key)
483 {
484 $value = is_string($value) ? explode('.', $value) : $value;
485
486 $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
487
488 return [$value, $key];
489 }
490
491 /**
492 * Push an item onto the beginning of an array.
493 *
494 * @param array $array
495 * @param mixed $value
496 * @param mixed $key
497 * @return array
498 */
499 public static function prepend($array, $value, $key = null)
500 {
501 if (is_null($key)) {
502 array_unshift($array, $value);
503 } else {
504 $array = [$key => $value] + $array;
505 }
506
507 return $array;
508 }
509
510 /**
511 * Get a value from the array, and remove it.
512 *
513 * @param array $array
514 * @param string $key
515 * @param mixed $default
516 * @return mixed
517 */
518 public static function pull(&$array, $key, $default = null)
519 {
520 $value = static::get($array, $key, $default);
521
522 static::forget($array, $key);
523
524 return $value;
525 }
526
527 /**
528 * Get one or a specified number of random values from an array.
529 *
530 * @param array $array
531 * @param int|null $number
532 * @return mixed
533 *
534 * @throws \InvalidArgumentException
535 */
536 public static function random($array, $number = null)
537 {
538 $requested = is_null($number) ? 1 : $number;
539
540 $count = count($array);
541
542 if ($requested > $count) {
543 throw new InvalidArgumentException(
544 "You requested {$requested} items, but there are only {$count} items available."
545 );
546 }
547
548 if (is_null($number)) {
549 return $array[array_rand($array)];
550 }
551
552 if ((int) $number === 0) {
553 return [];
554 }
555
556 $keys = array_rand($array, $number);
557
558 $results = [];
559
560 foreach ((array) $keys as $key) {
561 $results[] = $array[$key];
562 }
563
564 return $results;
565 }
566
567 /**
568 * Set an array item to a given value using "dot" notation.
569 *
570 * If no key is given to the method, the entire array will be replaced.
571 *
572 * @param array $array
573 * @param string $key
574 * @param mixed $value
575 * @return array
576 */
577 public static function set(&$array, $key, $value)
578 {
579 if (is_null($key)) {
580 return $array = $value;
581 }
582
583 $keys = explode('.', $key);
584
585 while (count($keys) > 1) {
586 $key = array_shift($keys);
587
588 // If the key doesn't exist at this depth, we will just create an empty array
589 // to hold the next value, allowing us to create the arrays to hold final
590 // values at the correct depth. Then we'll keep digging into the array.
591 if (! isset($array[$key]) || ! is_array($array[$key])) {
592 $array[$key] = [];
593 }
594
595 $array = &$array[$key];
596 }
597
598 $array[array_shift($keys)] = $value;
599
600 return $array;
601 }
602
603 /**
604 * Shuffle the given array and return the result.
605 *
606 * @param array $array
607 * @param int|null $seed
608 * @return array
609 */
610 public static function shuffle($array, $seed = null)
611 {
612 if (is_null($seed)) {
613 shuffle($array);
614 } else {
615 srand($seed);
616
617 usort($array, function () {
618 return rand(-1, 1);
619 });
620 }
621
622 return $array;
623 }
624
625 /**
626 * Sort the array using the given callback or "dot" notation.
627 *
628 * @param array $array
629 * @param callable|string|null $callback
630 * @return array
631 */
632 public static function sort($array, $callback = null)
633 {
634 return Collection::make($array)->sortBy($callback)->all();
635 }
636
637 /**
638 * Recursively sort an array by keys and values.
639 *
640 * @param array $array
641 * @return array
642 */
643 public static function sortRecursive($array)
644 {
645 foreach ($array as &$value) {
646 if (is_array($value)) {
647 $value = static::sortRecursive($value);
648 }
649 }
650
651 if (static::isAssoc($array)) {
652 ksort($array);
653 } else {
654 sort($array);
655 }
656
657 return $array;
658 }
659
660 /**
661 * Filter the array using the given callback.
662 *
663 * @param array $array
664 * @param callable $callback
665 * @return array
666 */
667 public static function where($array, callable $callback)
668 {
669 return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH);
670 }
671
672 /**
673 * If the given value is not an array and not null, wrap it in one.
674 *
675 * @param mixed $value
676 * @return array
677 */
678 public static function wrap($value)
679 {
680 if (is_null($value)) {
681 return [];
682 }
683
684 return ! is_array($value) ? [$value] : $value;
685 }
686
687 /**
688 * @param array|object $object
689 *
690 * @return array
691 */
692 public static function fromObject($object): array
693 {
694 $array = (array) $object;
695 foreach ($array as &$var) {
696 if (is_object($var)) {
697 $var = self::fromObject($var);
698 }
699 }
700
701 return $array;
702 }
703 }
704