Passed
Push — master ( cfe8d0...a21b74 )
by Brent
02:28
created

WalkableArray::set()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 17
nc 16
nop 3
dl 0
loc 29
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
namespace Brendt\Stitcher\Lib;
4
5
class WalkableArray implements \ArrayAccess, \Iterator
6
{
7
    const TOKEN_NESTING = '.';
8
9
    private $array = [];
10
    private $position = 0;
11
12
    public function __construct(array $array = []) {
13
        $this->array = $array;
14
    }
15
16
    public static function fromArray(array $array): WalkableArray {
17
        return new self($array);
18
    }
19
20
    public function get($pathParts) {
21
        if (!is_array($pathParts)) {
22
            $pathParts = explode(self::TOKEN_NESTING, $pathParts);
23
        }
24
25
        $element = $this->array;
26
27
        foreach ($pathParts as $key => $pathPart) {
28
            if (!isset($element[$pathPart])) {
29
                return null;
30
            }
31
32
            $element = $element[$pathPart];
33
        }
34
35
        return $element;
36
    }
37
38
    public function set($pathParts, $value, array $callbackArguments = []): WalkableArray {
39
        if (!is_array($pathParts)) {
40
            $pathParts = explode(self::TOKEN_NESTING, $pathParts);
41
        }
42
43
        end($pathParts);
44
        $lastPathKey = key($pathParts);
45
        reset($pathParts);
46
47
        $element = &$this->array;
48
49
        foreach ($pathParts as $key => $pathPart) {
50
            if (!isset($element[$pathPart])) {
51
                $element[$pathPart] = $key === $lastPathKey ? null : [];
52
            }
53
54
            $element = &$element[$pathPart];
55
        }
56
57
        if ($value instanceof \Closure) {
58
            $element = call_user_func_array($value, $callbackArguments);
59
        } else {
60
            $element = $value;
61
        }
62
63
        unset($element);
64
65
        return $this;
66
    }
67
68
    public function toArray(): array {
69
        $array = $this->array;
70
        reset($array);
71
72
        return $array;
73
    }
74
75
    public function current() {
76
        return current($this->array);
77
    }
78
79
    public function offsetGet($offset) {
80
        return isset($this->array[$offset]) ? $this->array[$offset] : $this->get($offset);
81
    }
82
83
    public function offsetSet($offset, $value) {
84
        if (is_null($offset)) {
85
            $this->array[] = $value;
86
        } elseif (isset($this->array[$offset])) {
87
            $this->array[$offset] = $value;
88
        } else {
89
            $this->set($offset, $value);
90
        }
91
    }
92
93
    public function offsetExists($offset) {
94
        return isset($this->array[$offset]) || $this->get($offset) !== null;
95
    }
96
97
    public function offsetUnset($offset) {
98
        unset($this->array[$offset]);
99
    }
100
101
    public function next() {
102
        ++$this->position;
103
    }
104
105
    public function key() {
106
        return $this->position;
107
    }
108
109
    public function valid() {
110
        return isset($this->array[$this->position]);
111
    }
112
113
    public function rewind() {
114
        $this->position = 0;
115
    }
116
}
117