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

src/Enumerator.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Narrowspark\Arr;
3
4
use ArrayAccess;
5
use Narrowspark\Arr\Traits\ValueTrait;
6
7
class Enumerator
8
{
9
    use ValueTrait;
10
11
    /**
12
     * Return the first element in an array passing a given truth test.
13
     *
14
     * @param array    $array
15
     * @param callable $callback
16
     * @param mixed    $default
17
     *
18
     * @return mixed
19
     */
20
    public function first(array $array, callable $callback, $default = null)
21
    {
22
        foreach ($array as $key => $value) {
23
            if (call_user_func($callback, $key, $value)) {
24
                return $value;
25
            }
26
        }
27
28
        return $this->value($default);
29
    }
30
31
    /**
32
     * Return the last element in an array passing a given truth test.
33
     *
34
     * @param array    $array
35
     * @param callable $callback
36
     * @param mixed    $default
37
     *
38
     * @return mixed
39
     */
40
    public function last(array $array, callable $callback, $default = null)
41
    {
42
        return $this->first(array_reverse($array), $callback, $default);
43
    }
44
45
    /**
46
     * Get a random element from the array supplied.
47
     *
48
     * @param array $array the source array
49
     *
50
     * @return mixed
51
     */
52
    public function random(array $array)
53
    {
54
        if (!count($array)) {
55
            return;
56
        }
57
58
        $keys = array_rand($array, 1);
59
60
        return $this->value($array[$keys]);
61
    }
62
63
    /**
64
     * Get a subset of the items from the given array.
65
     *
66
     * @param string[] $array
67
     * @param string[] $keys
68
     *
69
     * @return string[]
70
     */
71
    public function only(array $array, $keys)
72
    {
73
        return array_intersect_key($array, array_flip((array) $keys));
74
    }
75
76
    /**
77
     * Split an array in the given amount of pieces.
78
     *
79
     * @param array $array
80
     * @param int   $numberOfPieces
81
     * @param bool  $preserveKeys
82
     *
83
     * @return array
84
     */
85
    public function split(array $array, $numberOfPieces = 2, $preserveKeys = false)
86
    {
87
        if (count($array) === 0) {
88
            return [];
89
        }
90
91
        $splitSize = ceil(count($array) / $numberOfPieces);
92
93
        return array_chunk($array, $splitSize, $preserveKeys);
94
    }
95
96
    /**
97
     * Pluck an array of values from an array.
98
     *
99
     * @param array|\ArrayAccess $array
100
     * @param string             $value
101
     * @param string|null        $key
102
     *
103
     * @return array
104
     */
105
    public function pluck(array $array, $value, $key = null)
106
    {
107
        $results = [];
108
109
        list($value, $key) = $this->explodePluckParameters($value, $key);
110
111
        // If the key is "null", we will just append the value to the array and keep
112
        // looping. Otherwise we will key the array using the value of the key we
113
        // received from the developer. Then we'll return the final array form.
114
        if (is_null($key)) {
115
            foreach ($array as $item) {
116
                $results[] = $this->dataGet($item, $value);
117
            }
118
        } else {
119
            foreach ($array as $item) {
120
                $results[$this->dataGet($item, $key)] = $this->dataGet($item, $value);
121
            }
122
        }
123
124
        return $results;
125
    }
126
127
    /**
128
     * Filter the array using the given Closure.
129
     *
130
     * @param array    $array
131
     * @param callable $callback
132
     *
133
     * @return array
134
     */
135
    public function where(array $array, callable $callback)
136
    {
137
        $filtered = [];
138
139
        foreach ($array as $key => $value) {
140
            if (call_user_func($callback, $key, $value)) {
141
                $filtered[$key] = $value;
142
            }
143
        }
144
145
        return $filtered;
146
    }
147
148
    /**
149
     * Push an item onto the beginning of an array.
150
     *
151
     * @param array $array
152
     * @param mixed $value
153
     * @param mixed $key
154
     *
155
     * @return array
156
     */
157
    public function prepend(array $array, $value, $key = null)
158
    {
159
        if (is_null($key)) {
160
            array_unshift($array, $value);
161
        } else {
162
            $array = [$key => $value] + $array;
163
        }
164
165
        return $array;
166
    }
167
168
    /**
169
     * Get an item from an array or object using "dot" notation.
170
     *
171
     * @param mixed        $target
172
     * @param string|array $key
173
     * @param string|null  $default
174
     *
175
     * @return mixed
176
     */
177
    public function dataGet($target, $key, $default = null)
178
    {
179
        if (is_null($key)) {
180
            return $target;
181
        }
182
183
        $key = is_array($key) ? $key : explode('.', $key);
184
185
        while (($segment = array_shift($key)) !== null) {
186
            if ($segment === '*') {
187
                if (!is_array($target) && !$target instanceof ArrayAccess) {
188
                    return $this->value($default);
189
                }
190
191
                $result = $this->pluck($target, $key);
0 ignored issues
show
$key is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
It seems like $target defined by parameter $target on line 177 can also be of type object<ArrayAccess>; however, Narrowspark\Arr\Enumerator::pluck() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
192
193
                return in_array('*', $key, true) ? (new Transform())->collapse($result) : $result;
194
            }
195
196
            if (is_array($target)) {
197
                if (!array_key_exists($segment, $target)) {
198
                    return $this->value($default);
199
                }
200
201
                $target = $target[$segment];
202
            } elseif ($target instanceof ArrayAccess) {
203
                if (!isset($target[$segment])) {
204
                    return $this->value($default);
205
                }
206
207
                $target = $target[$segment];
208
            } elseif (is_object($target)) {
209
                if (!isset($target->{$segment})) {
210
                    return $this->value($default);
211
                }
212
213
                $target = $target->{$segment};
214
            } else {
215
                return $this->value($default);
216
            }
217
        }
218
219
        return $target;
220
    }
221
222
    /**
223
     * Replace a given pattern with each value in the array in sequentially.
224
     *
225
     * @param string $pattern
226
     * @param array  $replacements
227
     * @param string $subject
228
     *
229
     * @return string
230
     */
231
    public function pregReplaceSub($pattern, &$replacements, $subject)
232
    {
233
        return preg_replace_callback($pattern, function ($match) use (&$replacements) {
1 ignored issue
show
The parameter $match is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
234
            return array_shift($replacements);
235
        }, $subject);
236
    }
237
238
    /**
239
     * A shorter way to run a match on the array's keys rather than the values.
240
     *
241
     * @param string $pattern
242
     * @param array  $input
243
     * @param int    $flags
244
     *
245
     * @return array
246
     */
247
    public function pregGrepKeys($pattern, array $input, $flags = 0)
248
    {
249
        return array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags)));
250
    }
251
252
    /**
253
     * Explode the "value" and "key" arguments passed to "pluck".
254
     *
255
     * @param string      $value
256
     * @param string|null $key
257
     *
258
     * @return array[]
259
     */
260
    protected function explodePluckParameters($value, $key)
261
    {
262
        $value = is_array($value) ? $value : explode('.', $key);
263
264
        $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
265
266
        return [$value, $key];
267
    }
268
}
269