Completed
Push — master ( 44cd2c...638a5b )
by Daniel
05:15
created

Access::pull()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4286
cc 1
eloc 4
nc 1
nop 3
1
<?php
2
namespace Narrowspark\Arr;
3
4
use Narrowspark\Arr\Traits\SplitPathTrait;
5
use Narrowspark\Arr\Traits\ValueTrait;
6
7
class Access
8
{
9
    use SplitPathTrait;
10
    use ValueTrait;
11
12
    /**
13
     * Set an array item to a given value using "dot" notation.
14
     *
15
     * If no key is given to the method, the entire array will be replaced.
16
     *
17
     * @param array  $array
18
     * @param string $key
19
     * @param mixed  $value
20
     *
21
     * @return array
22
     */
23
    public function set(array &$array, $key, $value)
24
    {
25
        var_dump($array);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($array); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
26
27
        if ($key === null) {
28
            return $array = $value;
29
        }
30
31
        $keys = $this->splitPath($key);
32
33
        while (count($keys) > 1) {
34
            $key = array_shift($keys);
35
36
            // If the key doesn't exist at this depth, we will just create an empty array
37
            // to hold the next value, allowing us to create the arrays to hold final
38
            // values at the correct depth. Then we'll keep digging into the array.
39
            if (!isset($array[$key]) || !is_array($array[$key])) {
40
                $array[$key] = [];
41
            }
42
43
            $array = &$array[$key];
44
        }
45
46
        $array[array_shift($keys)] = $value;
47
48
        return $array;
49
    }
50
51
    /**
52
     * Get an item from an array using "dot" notation.
53
     *
54
     * @param array           $array
55
     * @param string|callable $key
0 ignored issues
show
Documentation introduced by
Should the type for parameter $key not be callable|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
56
     * @param mixed           $default
57
     *
58
     * @return mixed
59
     */
60
    public function get(array $array, $key = null, $default = null)
61
    {
62
        if ($key === null) {
63
            return $array;
64
        }
65
66
        if (isset($array[$key])) {
67
            return $array[$key];
68
        }
69
70 View Code Duplication
        foreach ($this->splitPath($key) as $segment) {
0 ignored issues
show
Documentation introduced by
$key is of type callable, but the function expects a array|string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
71
            if (!array_key_exists($segment, $array)) {
72
                return $this->value($default);
73
            }
74
75
            $array = $array[$segment];
76
        }
77
78
        return $array;
79
    }
80
81
    /**
82
     * Add an element to the array at a specific location
83
     * using the "dot" notation.
84
     *
85
     * @param array $array
86
     * @param $key
87
     * @param $value
88
     *
89
     * @return array
90
     */
91
    public function add(array &$array, $key, $value)
92
    {
93
        $target = $this->get($array, $key, []);
94
95
        if (!is_array($target)) {
96
            $target = [$target];
97
        }
98
99
        $target[] = $value;
100
        $this->set($array, $key, $target);
101
102
        return $array;
103
    }
104
105
    /**
106
     * Get a value from the array, and remove it.
107
     *
108
     * @param array       $array
109
     * @param string      $key
110
     * @param string|null $default
111
     *
112
     * @return mixed
113
     */
114
    public function pull(array &$array, $key, $default = null)
115
    {
116
        $value = $this->get($array, $key, $default);
117
118
        $this->forget($array, $key);
119
120
        return $value;
121
    }
122
123
    /**
124
     * Check if an item exists in an array using "dot" notation.
125
     *
126
     * @param array  $array
127
     * @param string $key
128
     *
129
     * @return bool
130
     */
131
    public function has(array $array, $key)
132
    {
133
        if (empty($array) || is_null($key)) {
134
            return false;
135
        }
136
137
        if (array_key_exists($key, $array)) {
138
            return true;
139
        }
140
141 View Code Duplication
        foreach ($this->splitPath($key) as $segment) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
142
            if (!array_key_exists($segment, $array)) {
143
                return false;
144
            }
145
146
            $array = $array[$segment];
147
        }
148
149
        return true;
150
    }
151
152
    /**
153
     * Updates data at the given path.
154
     *
155
     * @param array        $array
156
     * @param array|string $key
157
     * @param callable     $cb    Callback to update the value.
158
     *
159
     * @return mixed Updated data.
160
     */
161
    public function update(array $array, $key, callable $cb)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $cb. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
162
    {
163
        $keys    = $this->splitPath($key);
164
        $current = & $array;
165
166
        foreach ($keys as $key) {
167
            if (!isset($current[$key])) {
168
                return $array;
169
            }
170
171
            $current = & $current[$key];
172
        }
173
174
        $current = call_user_func($cb, $current);
175
176
        return $array;
177
    }
178
179
    /**
180
     * Remove one or many array items from a given array using "dot" notation.
181
     *
182
     * @param array        $array
183
     * @param array|string $keys
184
     */
185
    public function forget(array &$array, $keys)
186
    {
187
        $original = &$array;
188
        $keys     = (array) $keys;
189
190
        if (count($keys) === 0) {
191
            return;
192
        }
193
194
        foreach ($keys as $key) {
195
            $parts = $this->splitPath($key);
196
197
            // clean up before each pass
198
            $array = &$original;
199
200
            while (count($parts) > 1) {
201
                $part = array_shift($parts);
202
203
                if (isset($array[$part]) && is_array($array[$part])) {
204
                    $array = &$array[$part];
205
                } else {
206
                    continue 2;
207
                }
208
            }
209
210
            unset($array[array_shift($parts)]);
211
        }
212
    }
213
214
    /**
215
     * Reset all numerical indexes of an array (start from zero).
216
     * Non-numerical indexes will stay untouched. Returns a new array.
217
     *
218
     * @param array      $array
219
     * @param bool|false $deep
220
     *
221
     * @return array
222
     */
223
    public function reset(array $array, $deep = false)
224
    {
225
        $target = [];
226
227
        foreach ($array as $key => $value) {
228
            if ($deep && is_array($value)) {
229
                $value = $this->reset($value);
230
            }
231
232
            if (is_numeric($key)) {
233
                $target[] = $value;
234
            } else {
235
                $target[$key] = $value;
236
            }
237
        }
238
239
        return $target;
240
    }
241
242
    /**
243
     * Get all of the given array except for a specified array of items.
244
     *
245
     * @param array    $array
246
     * @param string[] $keys
247
     *
248
     * @return array
249
     */
250
    public function except(array $array, $keys)
251
    {
252
        $this->forget($array, $keys);
253
254
        return $array;
255
    }
256
}
257