Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
59 / 59
100.00% covered (success)
100.00%
25 / 25
CRAP
100.00% covered (success)
100.00%
1 / 1
AbstractArray
100.00% covered (success)
100.00%
59 / 59
100.00% covered (success)
100.00%
25 / 25
44
100.00% covered (success)
100.00%
1 / 1
 getIterator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 count
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 first
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 next
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 current
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 last
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 key
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 contains
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 sort
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 sortDesc
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 ksort
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 ksortDesc
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 usort
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 uksort
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 split
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 join
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 toArray
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
9
 __set
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 __get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 __isset
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __unset
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 offsetSet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 offsetGet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 offsetExists
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 offsetUnset
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Utils;
15
16use ArrayIterator;
17use ArrayAccess;
18use Countable;
19use IteratorAggregate;
20
21/**
22 * Pop utils abstract array object class
23 *
24 * @category   Pop
25 * @package    Pop\Utils
26 * @author     Nick Sagona, III <dev@nolainteractive.com>
27 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
28 * @license    http://www.popphp.org/license     New BSD License
29 * @version    2.1.0
30 */
31abstract class AbstractArray implements ArrayableInterface, ArrayAccess, Countable, IteratorAggregate
32{
33
34    /**
35     * Array data
36     * @var mixed
37     */
38    protected mixed $data = null;
39
40    /**
41     * Method to iterate over the array object
42     *
43     * @return \ArrayIterator
44     */
45    public function getIterator(): \ArrayIterator
46    {
47        return new \ArrayIterator($this->data);
48    }
49
50    /**
51     * Method to get the count of data in the collection
52     *
53     * @return int
54     */
55    public function count(): int
56    {
57        return count($this->data);
58    }
59
60    /**
61     * Get the first item of the array
62     *
63     * @return mixed
64     */
65    public function first(): mixed
66    {
67        return reset($this->data);
68    }
69
70    /**
71     * Get the next item of the array
72     *
73     * @return mixed
74     */
75    public function next(): mixed
76    {
77        return next($this->data);
78    }
79
80    /**
81     * Get the current item of the array
82     *
83     * @return mixed
84     */
85    public function current(): mixed
86    {
87        return current($this->data);
88    }
89
90    /**
91     * Get the last item of the array
92     *
93     * @return mixed
94     */
95    public function last(): mixed
96    {
97        return end($this->data);
98    }
99
100    /**
101     * Get the key of the current item of the array
102     *
103     * @return mixed
104     */
105    public function key(): mixed
106    {
107        return key($this->data);
108    }
109
110    /**
111     * Determine if an item exists in the array
112     *
113     * @param  mixed $key
114     * @param  bool  $strict
115     * @return bool
116     */
117    public function contains(mixed $key, bool $strict = false): bool
118    {
119        return in_array($key, $this->data, $strict);
120    }
121
122    /**
123     * Sort array
124     *
125     * @param  int  $flags
126     * @param  bool $assoc
127     * @param  bool $descending
128     * @return array
129     */
130    public function sort(int $flags = SORT_REGULAR, bool $assoc = true, bool $descending = false): static
131    {
132        if ($descending) {
133            $func = ($assoc) ? 'arsort' : 'rsort';
134        } else {
135            $func = ($assoc) ? 'asort' : 'sort';
136        }
137
138        $func($this->data, $flags);
139
140        return $this;
141    }
142
143    /**
144     * Sort array descending
145     *
146     * @param  int  $flags
147     * @param  bool $assoc
148     * @return static
149     */
150    public function sortDesc(int $flags = SORT_REGULAR, bool $assoc = true): static
151    {
152        return $this->sort($flags, $assoc, true);
153    }
154
155    /**
156     * Sort array by keys
157     *
158     * @param  int  $flags
159     * @param  bool $descending
160     * @return array
161     */
162    public function ksort(int $flags = SORT_REGULAR, bool $descending = false): static
163    {
164        if ($descending) {
165            krsort($this->data, $flags);
166        } else {
167            ksort($this->data, $flags);
168        }
169
170        return $this;
171    }
172
173    /**
174     * Sort array by keys, descending
175     *
176     * @param  int $flags
177     * @return static
178     */
179    public function ksortDesc(int $flags = SORT_REGULAR): static
180    {
181        return $this->ksort($flags, true);
182    }
183
184    /**
185     * Sort array by user-defined callback
186     *
187     * @param  mixed $callback
188     * @param  bool  $assoc
189     * @return static
190     */
191    public function usort(mixed $callback, bool $assoc = true): static
192    {
193        if ($assoc) {
194            uasort($this->data, $callback);
195        } else {
196            usort($this->data, $callback);
197        }
198
199        return $this;
200    }
201
202    /**
203     * Sort array by user-defined callback using keys
204     *
205     * @param  mixed $callback
206     * @return array
207     */
208    public function uksort(mixed $callback): static
209    {
210        uksort($this->data, $callback);
211        return $this;
212    }
213
214    /**
215     * Split a string into an array object
216     *
217     * @param  string $string
218     * @param  string $separator
219     * @param  int    $limit
220     * @return static
221     */
222    public static function split(string $string, string $separator, int $limit = PHP_INT_MAX): static
223    {
224        return new static(explode($separator, $string, $limit));
225    }
226
227    /**
228     * Join the array values into a string
229     *
230     * @param  string $glue
231     * @param  string $finalGlue
232     * @return string
233     */
234    public function join(string $glue, string $finalGlue = ''): string
235    {
236        if ($finalGlue === '') {
237            return implode($glue, $this->data);
238        }
239
240        if (count($this->data) == 0) {
241            return '';
242        }
243
244        if (count($this->data) == 1) {
245            return end($this->data);
246        }
247
248        $finalItem = array_pop($this->data);
249
250        return implode($glue, $this->data) . $finalGlue . $finalItem;
251    }
252
253    /**
254     * Get the values as an array
255     *
256     * @return array
257     */
258    public function toArray(): array
259    {
260        $data = [];
261
262        if (!is_array($this->data)) {
263            if (is_object($this->data) && method_exists($this->data, 'toArray')) {
264                $data = $this->data->toArray();
265            } else if ($this->data instanceof \ArrayObject) {
266                $data = (array)$this->data;
267            } else if ($this->data instanceof \Traversable) {
268                $data = iterator_to_array($this->data);
269            }
270        } else {
271            $data = $this->data;
272        }
273
274        foreach ($data as $key => $value) {
275            if (is_object($value) && method_exists($value, 'toArray')) {
276                $data[$key] = $value->toArray();
277            }
278        }
279
280        return $data;
281    }
282
283    /**
284     * Magic method to set the property to the value of $this->data[$name]
285     *
286     * @param  ?string $name
287     * @param  mixed $value
288     * @return static
289     */
290    public function __set(?string $name = null, mixed $value = null)
291    {
292        if ($name !== null) {
293            $this->data[$name] = $value;
294        } else {
295            $this->data[] = $value;
296        }
297
298        return $this;
299    }
300
301    /**
302     * Get a value
303     *
304     * @param  string $name
305     * @return mixed
306     */
307    public function __get(string $name): mixed
308    {
309        return (array_key_exists($name, (array)$this->data)) ? $this->data[$name] : null;
310    }
311
312    /**
313     * Is value set
314     *
315     * @param  string $name
316     * @return bool
317     */
318    public function __isset(string $name): bool
319    {
320        return array_key_exists($name, (array)$this->data);
321    }
322
323    /**
324     * Unset a value
325     *
326     * @param  string $name
327     * @return void
328     */
329    public function __unset(string $name): void
330    {
331        if (array_key_exists($name, (array)$this->data)) {
332            unset($this->data[$name]);
333        }
334    }
335
336    /**
337     * ArrayAccess offsetSet
338     *
339     * @param  mixed $offset
340     * @param  mixed $value
341     * @return void
342     */
343    public function offsetSet(mixed $offset, mixed $value): void
344    {
345        $this->__set($offset, $value);
346    }
347
348    /**
349     * ArrayAccess offsetGet
350     *
351     * @param  mixed $offset
352     * @return mixed
353     */
354    public function offsetGet(mixed $offset): mixed
355    {
356        return $this->__get($offset);
357    }
358
359    /**
360     * ArrayAccess offsetExists
361     *
362     * @param  mixed $offset
363     * @return bool
364     */
365    public function offsetExists(mixed $offset): bool
366    {
367        return $this->__isset($offset);
368    }
369
370    /**
371     * ArrayAccess offsetUnset
372     *
373     * @param  mixed $offset
374     * @return void
375     */
376    public function offsetUnset(mixed $offset): void
377    {
378        $this->__unset($offset);
379    }
380
381}