1 | <?php declare(strict_types = 1); |
||
2 | |||
3 | namespace Apicart\Utils\Arrays; |
||
4 | |||
5 | use InvalidArgumentException; |
||
6 | |||
7 | final class Arrays |
||
8 | { |
||
9 | |||
10 | /** |
||
11 | * @param mixed $default |
||
12 | * @return mixed |
||
13 | */ |
||
14 | 1 | public static function get(array $array, string $path, $default = null) |
|
15 | { |
||
16 | 1 | $return = $default; |
|
17 | 1 | $keyParts = explode('.', $path); |
|
18 | 1 | $rootKey = (string) array_shift($keyParts); |
|
19 | 1 | if (strpos($rootKey, ':') !== false) { // parse sub-structure search |
|
20 | 1 | $parts = explode(':', $rootKey); |
|
21 | 1 | $rootKey = $parts[0]; |
|
22 | 1 | $rootValue = $parts[1]; |
|
23 | } |
||
24 | 1 | foreach ($array as $mainIndex => $mainValue) { |
|
25 | 1 | if (isset($rootValue)) { |
|
26 | 1 | if (is_array($mainValue)) { |
|
27 | 1 | foreach ($mainValue as $key => $value) { |
|
28 | 1 | if ($key === $rootKey && $value === $rootValue) { |
|
29 | 1 | if (count($keyParts) > 0) { |
|
30 | 1 | $return = self::get($mainValue, implode('.', $keyParts), $default); |
|
31 | } else { |
||
32 | $return = $mainValue; |
||
33 | } |
||
34 | 1 | break 2; |
|
35 | } |
||
36 | } |
||
37 | } |
||
38 | 1 | continue; |
|
39 | } |
||
40 | |||
41 | 1 | if ($mainIndex === $rootKey || (is_int($mainIndex) && $mainIndex === (int) $rootKey)) { |
|
42 | 1 | if (is_array($mainValue) && $keyParts !== []) { |
|
43 | 1 | $return = self::get($mainValue, implode('.', $keyParts), $default); |
|
44 | 1 | } elseif ($keyParts !== []) { |
|
45 | $return = $default; |
||
46 | } else { |
||
47 | 1 | $return = $mainValue; |
|
48 | } |
||
49 | |||
50 | 1 | break; |
|
51 | } |
||
52 | } |
||
53 | |||
54 | 1 | return $return; |
|
55 | } |
||
56 | |||
57 | |||
58 | /** |
||
59 | * @param string|int|array $key one or more keys |
||
60 | * @return mixed |
||
61 | * @throws InvalidArgumentException |
||
62 | */ |
||
63 | 2 | public static function &getReference(array &$array, $key, string $keySeparator = '.') |
|
64 | { |
||
65 | 2 | if (is_string($key)) { |
|
66 | 1 | $key = (array) explode($keySeparator, $key); |
|
67 | 2 | } elseif (! is_array($key)) { |
|
68 | $key = [$key]; |
||
69 | } |
||
70 | |||
71 | 2 | foreach ($key as $index) { |
|
72 | 2 | if (is_array($array) || $array === null) { |
|
73 | 2 | $array = &$array[$index]; |
|
74 | } else { |
||
75 | throw new InvalidArgumentException('Traversed item is not an array.'); |
||
76 | } |
||
77 | } |
||
78 | |||
79 | 2 | return $array; |
|
80 | } |
||
81 | |||
82 | |||
83 | /** |
||
84 | * @param string|array $key |
||
85 | * @param mixed $value |
||
86 | */ |
||
87 | 1 | public static function set(array $haystack, $key, $value, string $keySeparator = '.'): array |
|
88 | { |
||
89 | 1 | if (is_string($key)) { |
|
90 | 1 | $key = explode($keySeparator, $key); |
|
91 | } |
||
92 | 1 | if (! is_array($key)) { |
|
0 ignored issues
–
show
introduced
by
![]() |
|||
93 | $key = [$key]; |
||
94 | } |
||
95 | |||
96 | 1 | $clone = $haystack; |
|
97 | 1 | $valueRef = & self::getReference($clone, $key); |
|
98 | 1 | $valueRef = $value; |
|
99 | |||
100 | 1 | return $clone; |
|
101 | } |
||
102 | |||
103 | |||
104 | /** |
||
105 | * @param array|string|null $left |
||
106 | * @param array|string|null $right |
||
107 | * @return array |
||
108 | */ |
||
109 | 1 | public static function merge($left, $right) |
|
110 | { |
||
111 | 1 | if (is_array($left) && is_array($right)) { |
|
112 | 1 | foreach ($left as $key => $val) { |
|
113 | 1 | if (is_int($key)) { |
|
114 | $right[] = $val; |
||
115 | } else { |
||
116 | 1 | if (isset($right[$key])) { |
|
117 | 1 | $val = static::merge($val, $right[$key]); |
|
118 | } |
||
119 | 1 | $right[$key] = $val; |
|
120 | } |
||
121 | } |
||
122 | 1 | return $right; |
|
0 ignored issues
–
show
|
|||
123 | 1 | } elseif ($left === null && is_array($right)) { |
|
124 | return $right; |
||
125 | } |
||
126 | |||
127 | 1 | return $left; |
|
0 ignored issues
–
show
|
|||
128 | } |
||
129 | |||
130 | } |
||
131 |