Issues (9)

src/Support/Collection.php (3 issues)

1
<?php
2
3
/*
4
 * This file is part of the overtrue/http.
5
 *
6
 * (c) overtrue <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Overtrue\Http\Support;
13
14
use ArrayAccess;
15
use ArrayIterator;
16
use Countable;
17
use IteratorAggregate;
18
use JsonSerializable;
19
use Serializable;
20
use Traversable;
21
22
/**
23
 * Class Collection.
24
 */
25
class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable, Serializable
26
{
27
    /**
28
     * The collection data.
29
     *
30
     * @var array
31
     */
32
    protected $items = [];
33
34
    /**
35
     * set data.
36
     *
37
     * @param mixed $items
38
     */
39
    public function __construct(array $items = [])
40
    {
41
        foreach ($items as $key => $value) {
42
            $this->set($key, $value);
43
        }
44
    }
45
46
    /**
47
     * Return all items.
48
     *
49
     * @return array
50
     */
51
    public function all(): array
52
    {
53
        return $this->items;
54
    }
55
56
    /**
57
     * Return specific items.
58
     *
59
     * @param array $keys
60
     *
61
     * @return \Overtrue\Http\Support\Collection
62
     */
63
    public function only(array $keys): self
64
    {
65
        $return = [];
66
67
        foreach ($keys as $key) {
68
            $value = $this->get($key);
69
70
            if (!is_null($value)) {
71
                $return[$key] = $value;
72
            }
73
        }
74
75
        return new static($return);
76
    }
77
78
    /**
79
     * Get all items except for those with the specified keys.
80
     *
81
     * @param mixed $keys
82
     *
83
     * @return \Overtrue\Http\Support\Collection
84
     */
85
    public function except($keys): self
86
    {
87
        $keys = is_array($keys) ? $keys : func_get_args();
88
89
        return new static(array_diff($this->items, array_combine($keys, array_pad([], count($keys), null))));
90
    }
91
92
    /**
93
     * Merge data.
94
     *
95
     * @param \Overtrue\Http\Support\Collection|array $items
96
     *
97
     * @return \Overtrue\Http\Support\Collection
98
     */
99
    public function merge($items): self
100
    {
101
        foreach ($items as $key => $value) {
102
            $this->set($key, $value);
103
        }
104
105
        return new static($this->all());
106
    }
107
108
    /**
109
     * To determine Whether the specified element exists.
110
     *
111
     * @param string $key
112
     *
113
     * @return bool
114
     */
115
    public function has($key): bool
116
    {
117
        return !is_null($this->dotGet($this->items, $key));
118
    }
119
120
    /**
121
     * Retrieve the first item.
122
     *
123
     * @return mixed
124
     */
125
    public function first()
126
    {
127
        return reset($this->items);
128
    }
129
130
    /**
131
     * Retrieve the last item.
132
     *
133
     * @return mixed
134
     */
135
    public function last()
136
    {
137
        $end = end($this->items);
138
139
        reset($this->items);
140
141
        return $end;
142
    }
143
144
    /**
145
     * add the item value.
146
     *
147
     * @param string $key
148
     * @param mixed  $value
149
     */
150
    public function add($key, $value)
151
    {
152
        $this->dotSet($this->items, $key, $value);
153
    }
154
155
    /**
156
     * Set the item value.
157
     *
158
     * @param string $key
159
     * @param mixed  $value
160
     */
161
    public function set($key, $value)
162
    {
163
        $this->dotSet($this->items, $key, $value);
164
    }
165
166
    /**
167
     * Remove item form Collection.
168
     *
169
     * @param string $key
170
     */
171
    public function forget($key)
172
    {
173
        $this->dotRemove($this->items, $key);
174
    }
175
176
    /**
177
     * Retrieve item from Collection.
178
     *
179
     * @param string $key
180
     * @param mixed  $default
181
     *
182
     * @return mixed
183
     */
184
    public function get($key, $default = null)
185
    {
186
        return $this->dotGet($this->items, $key, $default);
187
    }
188
189
    /**
190
     * @param array      $array
191
     * @param string     $key
192
     * @param mixed|null $default
193
     *
194
     * @return mixed
195
     */
196
    public function dotGet($array, $key, $default = null)
197
    {
198
        if (is_null($key)) {
0 ignored issues
show
The condition is_null($key) is always false.
Loading history...
199
            return $array;
200
        }
201
        if (array_key_exists($key, $array)) {
202
            return $array[$key];
203
        }
204
        foreach (explode('.', $key) as $segment) {
205
            if (array_key_exists($segment, $array)) {
206
                $array = $array[$segment];
207
            } else {
208
                return $default;
209
            }
210
        }
211
    }
212
213
    /**
214
     * @param array  $array
215
     * @param string $key
216
     * @param mixed  $value
217
     *
218
     * @return array
219
     */
220
    public function dotSet(array &$array, string $key, $value): array
221
    {
222
        $keys = explode('.', $key);
223
        while (count($keys) > 1) {
224
            $key = array_shift($keys);
225
            if (!isset($array[$key]) || !is_array($array[$key])) {
226
                $array[$key] = [];
227
            }
228
            $array = &$array[$key];
229
        }
230
        $array[array_shift($keys)] = $value;
231
232
        return $array;
233
    }
234
235
    /**
236
     * @param array        $array
237
     * @param array|string $keys
238
     */
239
    public function dotRemove(array &$array, $keys)
240
    {
241
        $original = &$array;
242
        $keys = (array) $keys;
243
        if (0 === count($keys)) {
244
            return;
245
        }
246
247
        foreach ($keys as $key) {
248
            if (array_key_exists($key, $array)) {
249
                unset($array[$key]);
250
                continue;
251
            }
252
            $parts = explode('.', $key);
253
254
            $array = &$original;
255
256
            while (count($parts) > 1) {
257
                $part = array_shift($parts);
258
                if (isset($array[$part]) && is_array($array[$part])) {
259
                    $array = &$array[$part];
260
                } else {
261
                    continue 2;
262
                }
263
            }
264
            unset($array[array_shift($parts)]);
265
        }
266
    }
267
268
    /**
269
     * Build to array.
270
     *
271
     * @return array
272
     */
273
    public function toArray(): array
274
    {
275
        return $this->all();
276
    }
277
278
    /**
279
     * Build to json.
280
     *
281
     * @param int $option
282
     *
283
     * @return string
284
     */
285
    public function toJson($option = JSON_UNESCAPED_UNICODE): string
286
    {
287
        return json_encode($this->all(), $option);
288
    }
289
290
    /**
291
     * To string.
292
     *
293
     * @return string
294
     */
295
    public function __toString(): string
296
    {
297
        return $this->toJson();
298
    }
299
300
    /**
301
     * (PHP 5 &gt;= 5.4.0)<br/>
302
     * Specify data which should be serialized to JSON.
303
     *
304
     * @see http://php.net/manual/en/jsonserializable.jsonserialize.php
305
     *
306
     * @return mixed data which can be serialized by <b>json_encode</b>,
307
     *               which is a value of any type other than a resource
308
     */
309
    public function jsonSerialize(): array
310
    {
311
        return $this->items;
312
    }
313
314
    /**
315
     * (PHP 5 &gt;= 5.1.0)<br/>
316
     * String representation of object.
317
     *
318
     * @see http://php.net/manual/en/serializable.serialize.php
319
     *
320
     * @return string the string representation of the object or null
321
     */
322
    public function serialize(): string
323
    {
324
        return serialize($this->items);
325
    }
326
327
    /**
328
     * (PHP 5 &gt;= 5.0.0)<br/>
329
     * Retrieve an external iterator.
330
     *
331
     * @see http://php.net/manual/en/iteratoraggregate.getiterator.php
332
     *
333
     * @return \ArrayIterator An instance of an object implementing <b>Iterator</b> or
334
     *                        <b>Traversable</b>
335
     */
336
    public function getIterator(): ArrayIterator
337
    {
338
        return new ArrayIterator($this->items);
339
    }
340
341
    /**
342
     * (PHP 5 &gt;= 5.1.0)<br/>
343
     * Count elements of an object.
344
     *
345
     * @see http://php.net/manual/en/countable.count.php
346
     *
347
     * @return int the custom count as an integer.
348
     *             </p>
349
     *             <p>
350
     *             The return value is cast to an integer
351
     */
352
    public function count(): int
353
    {
354
        return count($this->items);
355
    }
356
357
    /**
358
     * (PHP 5 &gt;= 5.1.0)<br/>
359
     * Constructs the object.
360
     *
361
     * @see  http://php.net/manual/en/serializable.unserialize.php
362
     *
363
     * @param string $serialized <p>
364
     *                           The string representation of the object.
365
     *                           </p>
366
     *
367
     * @return mixed|void
368
     */
369
    public function unserialize($serialized)
370
    {
371
        return $this->items = unserialize($serialized);
372
    }
373
374
    /**
375
     * Get a data by key.
376
     *
377
     * @param string $key
378
     *
379
     * @return mixed
380
     */
381
    public function __get($key)
382
    {
383
        return $this->get($key);
384
    }
385
386
    /**
387
     * Assigns a value to the specified data.
388
     *
389
     * @param string $key
390
     * @param mixed  $value
391
     */
392
    public function __set($key, $value)
393
    {
394
        $this->set($key, $value);
395
    }
396
397
    /**
398
     * Whether or not an data exists by key.
399
     *
400
     * @param string $key
401
     *
402
     * @return bool
403
     */
404
    public function __isset($key): bool
405
    {
406
        return $this->has($key);
407
    }
408
409
    /**
410
     * Unset an data by key.
411
     *
412
     * @param string $key
413
     */
414
    public function __unset($key)
415
    {
416
        $this->forget($key);
417
    }
418
419
    /**
420
     * var_export.
421
     *
422
     * @param array properties
0 ignored issues
show
The type Overtrue\Http\Support\properties 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...
423
     * 
424
     * @return object
425
     */
426
    public static function __set_state($array): object
427
    {
428
        return new self($array);
0 ignored issues
show
$array of type Overtrue\Http\Support\properties is incompatible with the type array expected by parameter $items of Overtrue\Http\Support\Collection::__construct(). ( Ignorable by Annotation )

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

428
        return new self(/** @scrutinizer ignore-type */ $array);
Loading history...
429
    }
430
431
    /**
432
     * (PHP 5 &gt;= 5.0.0)<br/>
433
     * Whether a offset exists.
434
     *
435
     * @see http://php.net/manual/en/arrayaccess.offsetexists.php
436
     *
437
     * @param mixed $offset <p>
438
     *                      An offset to check for.
439
     *                      </p>
440
     *
441
     * @return bool true on success or false on failure.
442
     *              The return value will be casted to boolean if non-boolean was returned
443
     */
444
    public function offsetExists($offset): bool
445
    {
446
        return $this->has($offset);
447
    }
448
449
    /**
450
     * (PHP 5 &gt;= 5.0.0)<br/>
451
     * Offset to unset.
452
     *
453
     * @see http://php.net/manual/en/arrayaccess.offsetunset.php
454
     *
455
     * @param mixed $offset <p>
456
     *                      The offset to unset.
457
     *                      </p>
458
     */
459
    public function offsetUnset($offset)
460
    {
461
        if ($this->offsetExists($offset)) {
462
            $this->forget($offset);
463
        }
464
    }
465
466
    /**
467
     * (PHP 5 &gt;= 5.0.0)<br/>
468
     * Offset to retrieve.
469
     *
470
     * @see http://php.net/manual/en/arrayaccess.offsetget.php
471
     *
472
     * @param mixed $offset <p>
473
     *                      The offset to retrieve.
474
     *                      </p>
475
     *
476
     * @return mixed Can return all value types
477
     */
478
    public function offsetGet($offset)
479
    {
480
        return $this->offsetExists($offset) ? $this->get($offset) : null;
481
    }
482
483
    /**
484
     * (PHP 5 &gt;= 5.0.0)<br/>
485
     * Offset to set.
486
     *
487
     * @see http://php.net/manual/en/arrayaccess.offsetset.php
488
     *
489
     * @param mixed $offset <p>
490
     *                      The offset to assign the value to.
491
     *                      </p>
492
     * @param mixed $value  <p>
493
     *                      The value to set.
494
     *                      </p>
495
     */
496
    public function offsetSet($offset, $value)
497
    {
498
        $this->set($offset, $value);
499
    }
500
}
501