Completed
Push — master ( b139e2...07b7da )
by Daniel
03:29
created

Access::reset()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 2
Metric Value
c 3
b 1
f 2
dl 0
loc 18
rs 8.8571
cc 5
eloc 10
nc 5
nop 2
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
        foreach ($keys as $key) {
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