Passed
Push — 1.0 ( 1757a3...241f9e )
by Vladimir
02:41
created

Arr::set()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 0
cts 11
cp 0
rs 8.7624
c 0
b 0
f 0
cc 5
eloc 11
nc 4
nop 3
crap 30
1
<?php
2
3
declare(strict_types=1);
4
5
namespace FondBot\Helpers;
6
7
use ArrayAccess;
8
9
class Arr
10
{
11
    /**
12
     * Determine whether the given value is array accessible.
13
     *
14
     * @param mixed $value
15
     *
16
     * @return bool
17
     */
18 7
    public static function accessible($value): bool
19
    {
20 7
        return is_array($value) || $value instanceof ArrayAccess;
21
    }
22
23
    /**
24
     * Determine if the given key exists in the provided array.
25
     *
26
     * @param \ArrayAccess|array $array
27
     * @param string|int         $key
28
     *
29
     * @return bool
30
     */
31 8
    public static function exists($array, $key): bool
32
    {
33 8
        if ($array instanceof ArrayAccess) {
34 2
            return $array->offsetExists($key);
35
        }
36
37 8
        return array_key_exists($key, $array);
38
    }
39
40
    /**
41
     * Check if an item or items exist in an array using "dot" notation.
42
     *
43
     * @param  \ArrayAccess|array $array
44
     * @param  array              $keys
45
     *
46
     * @return bool
47
     */
48 2
    public static function has($array, array $keys): bool
49
    {
50 2
        if ($keys === []) {
51 1
            return false;
52
        }
53
54 2
        foreach ($keys as $key) {
55 2
            $subKeyArray = $array;
56 2
            if (static::exists($array, $key)) {
57 2
                continue;
58
            }
59 2
            foreach (explode('.', $key) as $segment) {
60 2
                if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) {
61 1
                    $subKeyArray = $subKeyArray[$segment];
62
                } else {
63 2
                    return false;
64
                }
65
            }
66
        }
67
68 2
        return true;
69
    }
70
71
    /**
72
     * Get an item from an array using "dot" notation.
73
     *
74
     * @param \ArrayAccess|array $array
75
     * @param string|null        $key
76
     * @param mixed              $default
77
     *
78
     * @return mixed
79
     */
80 6
    public static function get($array, ?string $key, $default = null)
81
    {
82 6
        if ($key === null) {
83 3
            return $array;
84
        }
85
86 6
        if (static::exists($array, $key)) {
87 5
            return $array[$key];
88
        }
89 5
        foreach (explode('.', $key) as $segment) {
90 5
            if (static::accessible($array) && static::exists($array, $segment)) {
91 1
                $array = $array[$segment];
92
            } else {
93 5
                return value($default);
94
            }
95
        }
96
97 1
        return $array;
98
    }
99
100
    /**
101
     * Set an array item to a given value using "dot" notation.
102
     *
103
     * If no key is given to the method, the entire array will be replaced.
104
     *
105
     * @param  array  $array
106
     * @param  string $key
107
     * @param  mixed  $value
108
     *
109
     * @return array
110
     */
111
    public static function set(&$array, $key, $value): array
112
    {
113
        if ($key === null) {
114
            return $array = $value;
115
        }
116
117
        $keys = explode('.', $key);
118
        while (count($keys) > 1) {
119
            $key = array_shift($keys);
120
            // If the key doesn't exist at this depth, we will just create an empty array
121
            // to hold the next value, allowing us to create the arrays to hold final
122
            // values at the correct depth. Then we'll keep digging into the array.
123
            if (!isset($array[$key]) || !is_array($array[$key])) {
124
                $array[$key] = [];
125
            }
126
            $array = &$array[$key];
127
        }
128
        $array[array_shift($keys)] = $value;
129
130
        return $array;
131
    }
132
133
    /**
134
     * Remove one or many array items from a given array using "dot" notation.
135
     *
136
     * @param  array        $array
137
     * @param  array|string $keys
138
     *
139
     * @return void
140
     */
141
    public static function forget(&$array, $keys): void
142
    {
143
        $original = &$array;
144
        $keys = (array) $keys;
145
        if (count($keys) === 0) {
146
            return;
147
        }
148
        foreach ($keys as $key) {
149
            // if the exact key exists in the top-level, remove it
150
            if (static::exists($array, $key)) {
151
                unset($array[$key]);
152
                continue;
153
            }
154
            $parts = explode('.', $key);
155
            // clean up before each pass
156
            $array = &$original;
157
            while (count($parts) > 1) {
158
                $part = array_shift($parts);
159
                if (isset($array[$part]) && is_array($array[$part])) {
160
                    $array = &$array[$part];
161
                } else {
162
                    continue 2;
163
                }
164
            }
165
            unset($array[array_shift($parts)]);
166
        }
167
    }
168
}
169