Completed
Push — master ( e70327...8e47eb )
by Daniel
03:07
created

Access::set()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 26
ccs 14
cts 14
cp 1
rs 8.439
cc 5
eloc 12
nc 4
nop 3
crap 5
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
     * If no key is given to the method, the entire array will be replaced.
13
     *
14
     * @param array  $array
15
     * @param string $key
16
     * @param mixed  $value
17
     *
18
     * @return array
19
     */
20 11
    public function set(array $array, $key, $value)
21
    {
22 11
        if ($key === null) {
23 1
            return $value;
24
        }
25
26 11
        $keys = explode('.', $key);
27 11
        $current = &$array;
28
29 11
        while (count($keys) > 1) {
30 9
            $key = array_shift($keys);
31
32
            // If the key doesn't exist at this depth, we will just create an empty array
33
            // to hold the next value, allowing us to create the arrays to hold final
34
            // values at the correct depth. Then we'll keep digging into the array.
35 9
            if (! isset($current[$key]) || ! is_array($current[$key])) {
36 4
                $current[$key] = [];
37 4
            }
38
39 9
            $current = &$current[$key];
40 9
        }
41
42 11
        $current[array_shift($keys)] = $value;
43
44 11
        return $array;
45
    }
46
47
    /**
48
     * Get an item from an array using "dot" notation.
49
     * If key dont exist, you get a default value back.
50
     *
51
     * @param array                  $array
52
     * @param string[]|callable|null $key
53
     * @param mixed                  $default
54
     *
55
     * @return mixed
56
     */
57 5
    public function get(array $array, $key = null, $default = null)
58
    {
59 5
        if ($key === null) {
60 1
            return $array;
61
        }
62
63 5
        if (isset($array[$key])) {
64 3
            return $this->value($array[$key]);
65
        }
66
67 3
        foreach (explode('.', $key) as $segment) {
68 3
            if (! array_key_exists($segment, $array)) {
69
                return $this->value($default);
70
            }
71
72 3
            $array = $array[$segment];
73 3
        }
74
75 3
        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 4
    public function add(array $array, $key, $value)
89
    {
90 4
        $target = $this->get($array, $key, []);
91
92 4
        if (! is_array($target)) {
93 2
            $target = [$target];
94 2
        }
95
96 4
        $target[] = $value;
97 4
        $array = $this->set($array, $key, $target);
98
99 4
        return $array;
100
    }
101
102
    /**
103
     * Check if any item or items exist in an array using "dot" notation.
104
     *
105
     * @param array        $array
106
     * @param string|array $keys
107
     *
108
     * @return bool
109
     */
110 1
    public function any(array $array, $keys)
111
    {
112 1
        foreach ((array) $keys as $key) {
113 1
            if ($this->has($array, $key)) {
114 1
                return true;
115
            }
116 1
        }
117
118 1
        return false;
119
    }
120
121
    /**
122
     * Check if an item exists in an array using "dot" notation.
123
     *
124
     * @param array  $array
125
     * @param string $key
126
     *
127
     * @return bool
128
     */
129 11
    public function has(array $array, $key)
130
    {
131 11
        if (empty($array) || is_null($key)) {
132 5
            return false;
133
        }
134
135 11
        if (array_key_exists($key, $array)) {
136 9
            return true;
137
        }
138
139 8
        foreach (explode('.', $key) as $segment) {
140 8
            if (! is_array($array) || ! array_key_exists($segment, $array)) {
141 8
                return false;
142
            }
143
144 2
            $array = $array[$segment];
145 2
        }
146
147 2
        return true;
148
    }
149
150
    /**
151
     * Updates data at the given path.
152
     *
153
     * @param array          $array
154
     * @param array|string[] $key
155
     * @param callable       $callback Callback to update the value.
156
     *
157
     * @return mixed Updated data.
158
     */
159 1
    public function update(array $array, $key, callable $callback)
160
    {
161 1
        $keys = explode('.', $key);
162 1
        $current = &$array;
163
164 1
        foreach ($keys as $key) {
165 1
            if (! isset($current[$key])) {
166 1
                return $array;
167
            }
168
169 1
            $current = &$current[$key];
170 1
        }
171
172 1
        $current = call_user_func($callback, $current);
173
174 1
        return $array;
175
    }
176
177
    /**
178
     * Remove one or many array items from a given array using "dot" notation.
179
     *
180
     * @param array        $array
181
     * @param array|string $keys
182
     */
183 9
    public function forget(array $array, $keys)
184
    {
185 9
        $original = &$array;
186 9
        $keys = (array) $keys;
187
188 9
        if (count($keys) === 0) {
189 2
            return $original;
190
        }
191
192 7
        foreach ($keys as $key) {
193 7
            $parts = explode('.', $key);
194
            // clean up before each pass
195 7
            $arr = &$original;
196
197 7
            while (count($parts) > 1) {
198 7
                $part = array_shift($parts);
199
200 7
                if (isset($arr[$part]) && is_array($arr[$part])) {
201 7
                    $arr = &$arr[$part];
202 7
                } else {
203 4
                    continue 2;
204
                }
205 7
            }
206
207 4
            unset($arr[array_shift($parts)]);
208 7
        }
209
210 7
        return $array;
211
    }
212
}
213