Collection   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 47
c 1
b 0
f 0
dl 0
loc 168
ccs 52
cts 52
cp 1
rs 10
wmc 20

4 Methods

Rating   Name   Duplication   Size   Complexity  
A set() 0 25 6
A get() 0 13 4
A add() 0 25 6
A has() 0 14 4
1
<?php
2
3
/**
4
 * Bluz Framework Component
5
 *
6
 * @copyright Bluz PHP Team
7
 * @link      https://github.com/bluzphp/framework
8
 */
9
10
declare(strict_types=1);
11
12
namespace Bluz\Collection;
13
14
use ArgumentCountError;
15
use InvalidArgumentException;
16
17
/**
18
 * Collection is array :)
19
 *
20
 * @package  Bluz\Collection
21
 *
22
 * @author   Anton Shevchuk
23
 */
24
class Collection
25
{
26
    /**
27
     * Get an element of the array by key(s)
28
     *   this method created to avoid error `undefined index`
29
     *
30
     * <code>
31
     *   $arr = ['a' => [10, 20], 'b' => [30, 40]];
32
     *
33
     *   Collection::get($arr, 'a');    // [10, 20]
34
     *   Collection::get($arr, 'a', 0); // 10
35
     *   Collection::get($arr, 'a', 1); // 20
36
     *   Collection::get($arr, 'a', 3); // null
37
     *   Collection::get($arr, 'c');    // null
38
     *   Collection::get($arr, 'c', 0); // null
39
     *   Collection::get($arr, 'c', 1); // null
40
     * </code>
41
     *
42
     * @param array $array
43
     * @param array $keys
44
     *
45
     * @return mixed|null
46
     */
47 12
    public static function get(array $array, ...$keys): mixed
48
    {
49 12
        $key = array_shift($keys);
50
51 12
        if (empty($keys)) {
52 9
            return $array[$key] ?? null;
53
        }
54
55 10
        if (!array_key_exists($key, $array) || !is_array($array[$key])) {
56 3
            return null;
57
        }
58
59 7
        return self::get($array[$key], ...$keys);
60
    }
61
62
    /**
63
     * Get an element of the array by key(s)
64
     *   this method created to avoid error `undefined index` with call `array_key_exists`
65
     *
66
     * <code>
67
     *   $arr = ['a' => ['a' => 1, 'b' => null]];
68
     *
69
     *   Collection::has($arr, 'a');           // true
70
     *   Collection::has($arr, 'a', 'a');      // true
71
     *   Collection::has($arr, 'a', 'b');      // true
72
     *   Collection::has($arr, 'a', 'c');      // false
73
     *   Collection::has($arr, 'a', 'c', 'c'); // false
74
     *
75
     *   // compare with isset
76
     *   isset($arr['a']['b'])                  // false
77
     *   // compare with array_key_exists
78
     *   array_key_exists('c', $arr['a']['c']); // undefined index
79
     * </code>
80
     *
81
     * @param array $array
82
     * @param array $keys
83
     *
84
     * @link https://php.net/manual/function.isset.php
85
     * @link https://php.net/manual/function.array-key-exists.php
86
     *
87
     * @return bool
88
     */
89 16
    public static function has(array $array, ...$keys): bool
90
    {
91 16
        $key = array_shift($keys);
92 16
        $exist = array_key_exists($key, $array);
93
94 16
        if (!$exist || empty($keys)) {
95 15
            return $exist;
96
        }
97
98 8
        if (!is_array($array[$key])) {
99 1
            return false;
100
        }
101
102 7
        return self::has($array[$key], ...$keys);
103
    }
104
105
    /**
106
     * Add an element to the array by key(s)
107
     *
108
     *
109
     * <code>
110
     *   $arr = ['a' => ['a' => 1, 'b' => null]];
111
     *
112
     *   Collection::add($arr, 'b', 1);           // $arr['b'][] = 1
113
     *   Collection::add($arr, 'b', 'a', 1);      // $arr['b']['a'] = 1
114
     *   Collection::add($arr, 'b', 'b', 'a', 1); // $arr['b']['b']['a'] = 1
115
     *
116
     *   // errors
117
     *   Collection::add($arr, 'a', 'b', 1); // $arr['a']['b'] already exists, and it is not an array
118
     * </code>
119
     *
120
     * @param array $array
121
     * @param mixed $key
122
     * @param array $values
123
     *
124
     * @return void
125
     * @throws InvalidArgumentException
126
     */
127 4
    public static function add(array &$array, mixed $key, ...$values): void
128
    {
129 4
        $countValues = count($values);
130
131 4
        if ($countValues === 0) {
132 1
            throw new ArgumentCountError(
133 1
                'Method `Collection::add()` expected three or more arguments'
134 1
            );
135
        }
136 3
        $value = array_pop($values);
137
138 3
        while (true) {
139 3
            if (!array_key_exists($key, $array)) {
140 2
                $array[$key] = [];
141 3
            } elseif (!is_array($array[$key])) {
142 1
                throw new InvalidArgumentException(
143 1
                    '`Collection` can\'t change element with key `' . $key . '`, is not an array'
144 1
                );
145
            }
146 2
            if (count($values)) {
147 2
                $array = &$array[$key];
148 2
                $key = array_shift($values);
149
            } else {
150 2
                $array[$key][] = $value;
151 2
                return;
152
            }
153
        }
154
    }
155
156
    /**
157
     * Set an element of the array by key(s)
158
     *   this method is equal to native set value
159
     *
160
     * @param array $array
161
     * @param mixed $key
162
     * @param array $values
163
     *
164
     * @return void
165
     * @throws InvalidArgumentException
166
     */
167 4
    public static function set(array &$array, mixed $key, ...$values): void
168
    {
169 4
        if (count($values) === 0) {
170 1
            throw new ArgumentCountError(
171 1
                'Method `Collection::set()` expected three or more arguments'
172 1
            );
173
        }
174
175 3
        $value = array_pop($values);
176
177 3
        while (true) {
178 3
            if (!array_key_exists($key, $array)) {
179 2
                $array[$key] = [];
180
            }
181 3
            if (count($values)) {
182 3
                $array = &$array[$key];
183 3
                $key = array_shift($values);
184 3
                if (!is_array($array)) {
185 3
                    throw new InvalidArgumentException(
186 3
                        '`Collection` can\'t change element with key `' . $key . '`, is not an array'
187 3
                    );
188
                }
189
            } else {
190 2
                $array[$key] = $value;
191 2
                return;
192
            }
193
        }
194
    }
195
}
196