Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
MultiDimArray
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 6
420
0.00% covered (danger)
0.00%
0 / 1
 all
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getIterator
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 offsetSet
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 offsetGet
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
 offsetUnset
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
56
 offsetExists
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace Flow\Data\Utils;
4
5use RecursiveArrayIterator;
6use RecursiveIteratorIterator;
7
8/**
9 * This object can be used to easily set keys in a multi-dimensional array.
10 *
11 * Usage:
12 *
13 *   $arr = new Flow\Data\MultiDimArray;
14 *   $arr[[1,2,3]] = 4;
15 *   $arr[[2,3,4]] = 5;
16 *   var_export( $arr->all() );
17 *
18 *   array (
19 *     1 => array (
20 *       2 => array (
21 *         3 => 4,
22 *       ),
23 *     ),
24 *     2 => array (
25 *       3 => array (
26 *         4 => 5,
27 *       ),
28 *     ),
29 *   )
30 */
31class MultiDimArray implements \ArrayAccess {
32    /** @var array */
33    protected $data = [];
34
35    public function all() {
36        return $this->data;
37    }
38
39    /**
40     * Probably not what you want.  primary key value is lost, you only
41     * receive the final key in a composite key set.
42     * @return RecursiveIteratorIterator
43     */
44    public function getIterator() {
45        $it = new RecursiveArrayIterator( $this->data );
46        return new RecursiveIteratorIterator( $it );
47    }
48
49    public function offsetSet( $offset, $value ): void {
50        $data =& $this->data;
51        foreach ( (array)$offset as $key ) {
52            if ( !isset( $data[$key] ) ) {
53                $data[$key] = [];
54            }
55            $data =& $data[$key];
56        }
57        $data = $value;
58    }
59
60    #[\ReturnTypeWillChange]
61    public function offsetGet( $offset ) {
62        $data =& $this->data;
63        foreach ( (array)$offset as $key ) {
64            if ( !isset( $data[$key] ) ) {
65                throw new \OutOfBoundsException( 'Does not exist' );
66            } elseif ( !is_array( $data ) ) {
67                throw new \OutOfBoundsException( "Requested offset {$key} (full offset " . implode( ':', $offset ) .
68                    "), but $data is not an array." );
69            }
70            $data =& $data[$key];
71        }
72        return $data;
73    }
74
75    public function offsetUnset( $offset ): void {
76        $offset = (array)$offset;
77        // while loop is required to not leave behind empty arrays
78        $first = true;
79        while ( $offset ) {
80            $end = array_pop( $offset );
81            $data =& $this->data;
82            foreach ( $offset as $key ) {
83                if ( !isset( $data[$key] ) ) {
84                    return;
85                }
86                $data =& $data[$key];
87            }
88            if ( $first === true || ( is_array( $data[$end] ) && !count( $data[$end] ) ) ) {
89                unset( $data[$end] );
90                $first = false;
91            }
92        }
93    }
94
95    public function offsetExists( $offset ): bool {
96        $data =& $this->data;
97        foreach ( (array)$offset as $key ) {
98            if ( !isset( $data[$key] ) ) {
99                return false;
100            } elseif ( !is_array( $data ) ) {
101                throw new \OutOfBoundsException( "Requested offset {$key} (full offset " . implode( ':', $offset ) .
102                    "), but $data is not an array." );
103            }
104            $data =& $data[$key];
105        }
106        return true;
107    }
108}