Arrays::set()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 10
c 1
b 0
f 0
nc 4
nop 3
dl 0
loc 20
rs 9.6111
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Flextype\Component\Arrays;
6
7
use function array_key_exists;
8
use function array_merge;
9
use function array_shift;
10
use function count;
11
use function explode;
12
use function is_array;
13
use function is_null;
14
15
class Arrays
16
{
17
    /**
18
     * Expands a dot notation array into a full multi-dimensional array.
19
     *
20
     * @param array $array Array
21
     *
22
     * @return array
23
     */
24
    public static function undot(array $array) : array
25
    {
26
        $results_array = [];
27
        foreach ($array as $key => $value) {
28
            self::set($results_array, $key, $value);
29
        }
30
31
        return $results_array;
32
    }
33
34
    /**
35
     * Flatten a multi-dimensional associative array with dots.
36
     *
37
     * @param  array  $array   Array
38
     * @param  string $prepend Prepend string
39
     *
40
     * @return array
41
     *
42
     * @access  public
43
     */
44
    public static function dot(array $array, string $prepend = '') : array
45
    {
46
        $results = [];
47
48
        foreach ($array as $key => $value) {
49
            if (is_array($value) && ! empty($value)) {
50
                $results = array_merge($results, static::dot($value, $prepend . $key . '.'));
51
            } else {
52
                $results[$prepend . $key] = $value;
53
            }
54
        }
55
56
        return $results;
57
    }
58
59
    /**
60
     * Set an array item to a given value using "dot" notation.
61
     *
62
     * If no key is given to the method, the entire array will be replaced.
63
     *
64
     * @param array  $array Array you want to modify
65
     * @param string $key   Array path
66
     * @param mixed  $value Value to set
67
     *
68
     * @return array
69
     *
70
     * @access  public
71
     */
72
    public static function set(array &$array, string $key, $value) : array
73
    {
74
        if (is_null($key)) {
0 ignored issues
show
introduced by
The condition is_null($key) is always false.
Loading history...
75
            return $array = $value;
76
        }
77
78
        $keys = explode('.', $key);
79
80
        while (count($keys) > 1) {
81
            $key = array_shift($keys);
82
            if (! isset($array[$key]) || ! is_array($array[$key])) {
83
                $array[$key] = [];
84
            }
85
86
            $array = &$array[$key];
87
        }
88
89
        $array[array_shift($keys)] = $value;
90
91
        return $array;
92
    }
93
94
    /**
95
     * Checks if the given dot-notated key exists in the array.
96
     *
97
     * @param  array $array The search array
98
     * @param  mixed $key   Array path
99
     *
100
     * @access  public
101
     */
102
    public static function has(array $array, $key) : bool
103
    {
104
        foreach (explode('.', $key) as $segment) {
105
            if (! is_array($array) or ! array_key_exists($segment, $array)) {
106
                return false;
107
            }
108
109
            $array = $array[$segment];
110
        }
111
112
        return true;
113
    }
114
115
    /**
116
     * Returns value from array using "dot notation".
117
     * If the key does not exist in the array, the default value will be returned instead.
118
     *
119
     * @param  array  $array   Array to extract from
120
     * @param  string $key     Array path
121
     * @param  mixed  $default Default value
122
     *
123
     * @return mixed
124
     *
125
     * @access  public
126
     */
127
    public static function get(array $array, string $key, $default = null)
128
    {
129
        // Get segments from path
130
        $segments = explode('.', $key);
131
132
        // Loop through segments
133
        foreach ($segments as $segment) {
134
            // Check
135
            if (! is_array($array) || ! isset($array[$segment])) {
136
                return $default;
137
            }
138
139
            // Write
140
            $array = $array[$segment];
141
        }
142
143
        // Return
144
        return $array;
145
    }
146
147
    /**
148
     * Deletes an array value using "dot notation".
149
     *
150
     * @param  array  $array Array you want to modify
151
     * @param  string $key   Array path
152
     *
153
     * @return mixed
154
     *
155
     * @access  public
156
     */
157
    public static function delete(array &$array, string $key) : bool
158
    {
159
        // Get segments from path
160
        $segments = explode('.', $key);
161
162
        // Loop through segments
163
        while (count($segments) > 1) {
164
            $segment = array_shift($segments);
165
166
            if (! isset($array[$segment]) || ! is_array($array[$segment])) {
167
                return false;
168
            }
169
170
            $array =& $array[$segment];
171
        }
172
173
        unset($array[array_shift($segments)]);
174
175
        return true;
176
    }
177
178
    /**
179
     * Sorts a multi-dimensional array by a certain field path
180
     *
181
     * @param  array  $array     The source array
182
     * @param  string $field     The name of the field path
183
     * @param  string $direction Order type DESC (descending) or ASC (ascending)
184
     * @param  const  $method    A PHP sort method flag or 'natural' for natural sorting, which is not supported in PHP by sort flags
0 ignored issues
show
Bug introduced by
The type Flextype\Component\Arrays\const was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
185
     *
186
     * @return array
187
     *
188
     * @access  public
189
     */
190
    public static function sort(array $array, string $field, string $direction = 'ASC', $method = SORT_REGULAR) : array
191
    {
192
        if (count($array) > 0) {
193
            // Create the helper array
194
            foreach ($array as $key => $row) {
195
                $helper[$key] = function_exists('mb_strtolower') ? mb_strtolower(strval(static::get($row, $field))) : strtolower(strval(static::get($row, $field)));
196
            }
197
198
            // Sort
199
            if ($method === SORT_NATURAL) {
200
                natsort($helper);
201
                ($direction === 'DESC') and $helper = array_reverse($helper);
202
            } elseif ($direction === 'DESC') {
203
                arsort($helper, $method);
0 ignored issues
show
Bug introduced by
It seems like $method can also be of type Flextype\Component\Arrays\const; however, parameter $sort_flags of arsort() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

203
                arsort($helper, /** @scrutinizer ignore-type */ $method);
Loading history...
204
            } else {
205
                asort($helper, $method);
0 ignored issues
show
Bug introduced by
It seems like $method can also be of type Flextype\Component\Arrays\const; however, parameter $sort_flags of asort() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

205
                asort($helper, /** @scrutinizer ignore-type */ $method);
Loading history...
206
            }
207
208
            // Rebuild the original array
209
            foreach ($helper as $key => $val) {
210
                $result[$key] = $array[$key];
211
            }
212
213
            // Return result array
214
            return $result;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $result seems to be defined by a foreach iteration on line 209. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
215
        }
0 ignored issues
show
Bug Best Practice introduced by
The function implicitly returns null when the if condition on line 192 is false. This is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
216
    }
217
}
218