These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace Narrowspark\Arr; |
||
3 | |||
4 | use Narrowspark\Arr\Traits\ValueTrait; |
||
5 | |||
6 | class Access |
||
7 | { |
||
8 | use ValueTrait; |
||
9 | |||
10 | /** |
||
11 | * Set an array item to a given value using "dot" notation. |
||
12 | * |
||
13 | * If no key is given to the method, the entire array will be replaced. |
||
14 | * |
||
15 | * @param array $array |
||
16 | * @param string $key |
||
17 | * @param mixed $value |
||
18 | * |
||
19 | * @return array |
||
20 | */ |
||
21 | public function set(array $array, $key, $value) |
||
22 | { |
||
23 | if ($key === null) { |
||
24 | return $value; |
||
25 | } |
||
26 | |||
27 | $keys = explode('.', $key); |
||
28 | $current = &$array; |
||
29 | |||
30 | while (count($keys) > 1) { |
||
31 | $key = array_shift($keys); |
||
32 | |||
33 | // If the key doesn't exist at this depth, we will just create an empty array |
||
34 | // to hold the next value, allowing us to create the arrays to hold final |
||
35 | // values at the correct depth. Then we'll keep digging into the array. |
||
36 | if (!isset($current[$key]) || !is_array($current[$key])) { |
||
37 | $current[$key] = []; |
||
38 | } |
||
39 | |||
40 | $current = &$current[$key]; |
||
41 | } |
||
42 | |||
43 | $current[array_shift($keys)] = $value; |
||
44 | |||
45 | return $array; |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * Get an item from an array using "dot" notation. |
||
50 | * |
||
51 | * @param array $array |
||
52 | * @param string[]|callable|null $key |
||
53 | * @param mixed $default |
||
54 | * |
||
55 | * @return mixed |
||
56 | */ |
||
57 | public function get(array $array, $key = null, $default = null) |
||
58 | { |
||
59 | if ($key === null) { |
||
60 | return $array; |
||
61 | } |
||
62 | |||
63 | if (isset($array[$key])) { |
||
64 | return $this->value($array[$key]); |
||
65 | } |
||
66 | |||
67 | foreach (explode('.', $key) as $segment) { |
||
68 | if (!array_key_exists($segment, $array)) { |
||
69 | return $this->value($default); |
||
70 | } |
||
71 | |||
72 | $array = $array[$segment]; |
||
73 | } |
||
74 | |||
75 | return $array; |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * Add an element to the array at a specific location |
||
80 | * using the "dot" notation. |
||
81 | * |
||
82 | * @param array $array |
||
83 | * @param $key |
||
84 | * @param $value |
||
85 | * |
||
86 | * @return array |
||
87 | */ |
||
88 | public function add(array $array, $key, $value) |
||
89 | { |
||
90 | $target = $this->get($array, $key, []); |
||
91 | |||
92 | if (!is_array($target)) { |
||
93 | $target = [$target]; |
||
94 | } |
||
95 | |||
96 | $target[] = $value; |
||
97 | $array = $this->set($array, $key, $target); |
||
98 | |||
99 | return $array; |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * Check if an item exists in an array using "dot" notation. |
||
104 | * |
||
105 | * @param array $array |
||
106 | * @param string $key |
||
107 | * |
||
108 | * @return bool |
||
109 | */ |
||
110 | public function has(array $array, $key) |
||
111 | { |
||
112 | if (empty($array) || is_null($key)) { |
||
113 | return false; |
||
114 | } |
||
115 | |||
116 | if (array_key_exists($key, $array)) { |
||
117 | return true; |
||
118 | } |
||
119 | |||
120 | foreach (explode('.', $key) as $segment) { |
||
121 | if (!is_array($array) || !array_key_exists($segment, $array)) { |
||
122 | return false; |
||
123 | } |
||
124 | |||
125 | $array = $array[$segment]; |
||
126 | } |
||
127 | |||
128 | return true; |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * Updates data at the given path. |
||
133 | * |
||
134 | * @param array $array |
||
135 | * @param array|string[] $key |
||
136 | * @param callable $callback Callback to update the value. |
||
137 | * |
||
138 | * @return mixed Updated data. |
||
139 | */ |
||
140 | public function update(array $array, $key, callable $callback) |
||
141 | { |
||
142 | $keys = explode('.', $key); |
||
143 | $current = &$array; |
||
144 | |||
145 | View Code Duplication | foreach ($keys as $key) { |
|
0 ignored issues
–
show
|
|||
146 | if (!isset($current[$key])) { |
||
147 | return $array; |
||
148 | } |
||
149 | |||
150 | $current = &$current[$key]; |
||
151 | } |
||
152 | |||
153 | $current = call_user_func($callback, $current); |
||
154 | |||
155 | return $array; |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * Remove one or many array items from a given array using "dot" or "wildcards" notation. |
||
160 | * |
||
161 | * @param array $array |
||
162 | * @param array|string $keys |
||
163 | */ |
||
164 | public function forget(array $array, $keys) |
||
165 | { |
||
166 | $original = &$array; |
||
167 | $keys = (array) $keys; |
||
168 | |||
169 | if (count($keys) === 0) { |
||
170 | return $original; |
||
171 | } |
||
172 | |||
173 | foreach ($keys as $key) { |
||
174 | $parts = explode('.', $key); |
||
175 | // clean up before each pass |
||
176 | $arr = &$original; |
||
177 | |||
178 | while (count($parts) > 1) { |
||
179 | $part = array_shift($parts); |
||
180 | |||
181 | if (isset($arr[$part]) && is_array($arr[$part])) { |
||
182 | $arr = &$arr[$part]; |
||
183 | } else { |
||
184 | continue 2; |
||
185 | } |
||
186 | } |
||
187 | |||
188 | unset($arr[array_shift($parts)]); |
||
189 | } |
||
190 | |||
191 | return $array; |
||
192 | } |
||
193 | } |
||
194 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.