Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is a part of dflydev/dot-access-data.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Dragonfly Development Inc.
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Dflydev\DotAccessData;
|
Chris@0
|
13
|
Chris@0
|
14 class Data implements DataInterface
|
Chris@0
|
15 {
|
Chris@0
|
16 /**
|
Chris@0
|
17 * Internal representation of data data
|
Chris@0
|
18 *
|
Chris@0
|
19 * @var array
|
Chris@0
|
20 */
|
Chris@0
|
21 protected $data;
|
Chris@0
|
22
|
Chris@0
|
23 /**
|
Chris@0
|
24 * Constructor
|
Chris@0
|
25 *
|
Chris@0
|
26 * @param array|null $data
|
Chris@0
|
27 */
|
Chris@0
|
28 public function __construct(array $data = null)
|
Chris@0
|
29 {
|
Chris@0
|
30 $this->data = $data ?: array();
|
Chris@0
|
31 }
|
Chris@0
|
32
|
Chris@0
|
33 /**
|
Chris@0
|
34 * {@inheritdoc}
|
Chris@0
|
35 */
|
Chris@0
|
36 public function append($key, $value = null)
|
Chris@0
|
37 {
|
Chris@0
|
38 if (0 == strlen($key)) {
|
Chris@0
|
39 throw new \RuntimeException("Key cannot be an empty string");
|
Chris@0
|
40 }
|
Chris@0
|
41
|
Chris@0
|
42 $currentValue =& $this->data;
|
Chris@0
|
43 $keyPath = explode('.', $key);
|
Chris@0
|
44
|
Chris@0
|
45 if (1 == count($keyPath)) {
|
Chris@0
|
46 if (!isset($currentValue[$key])) {
|
Chris@0
|
47 $currentValue[$key] = array();
|
Chris@0
|
48 }
|
Chris@0
|
49 if (!is_array($currentValue[$key])) {
|
Chris@0
|
50 // Promote this key to an array.
|
Chris@0
|
51 // TODO: Is this really what we want to do?
|
Chris@0
|
52 $currentValue[$key] = array($currentValue[$key]);
|
Chris@0
|
53 }
|
Chris@0
|
54 $currentValue[$key][] = $value;
|
Chris@0
|
55
|
Chris@0
|
56 return;
|
Chris@0
|
57 }
|
Chris@0
|
58
|
Chris@0
|
59 $endKey = array_pop($keyPath);
|
Chris@0
|
60 for ( $i = 0; $i < count($keyPath); $i++ ) {
|
Chris@0
|
61 $currentKey =& $keyPath[$i];
|
Chris@0
|
62 if ( ! isset($currentValue[$currentKey]) ) {
|
Chris@0
|
63 $currentValue[$currentKey] = array();
|
Chris@0
|
64 }
|
Chris@0
|
65 $currentValue =& $currentValue[$currentKey];
|
Chris@0
|
66 }
|
Chris@0
|
67
|
Chris@0
|
68 if (!isset($currentValue[$endKey])) {
|
Chris@0
|
69 $currentValue[$endKey] = array();
|
Chris@0
|
70 }
|
Chris@0
|
71 if (!is_array($currentValue[$endKey])) {
|
Chris@0
|
72 $currentValue[$endKey] = array($currentValue[$endKey]);
|
Chris@0
|
73 }
|
Chris@0
|
74 // Promote this key to an array.
|
Chris@0
|
75 // TODO: Is this really what we want to do?
|
Chris@0
|
76 $currentValue[$endKey][] = $value;
|
Chris@0
|
77 }
|
Chris@0
|
78
|
Chris@0
|
79 /**
|
Chris@0
|
80 * {@inheritdoc}
|
Chris@0
|
81 */
|
Chris@0
|
82 public function set($key, $value = null)
|
Chris@0
|
83 {
|
Chris@0
|
84 if (0 == strlen($key)) {
|
Chris@0
|
85 throw new \RuntimeException("Key cannot be an empty string");
|
Chris@0
|
86 }
|
Chris@0
|
87
|
Chris@0
|
88 $currentValue =& $this->data;
|
Chris@0
|
89 $keyPath = explode('.', $key);
|
Chris@0
|
90
|
Chris@0
|
91 if (1 == count($keyPath)) {
|
Chris@0
|
92 $currentValue[$key] = $value;
|
Chris@0
|
93
|
Chris@0
|
94 return;
|
Chris@0
|
95 }
|
Chris@0
|
96
|
Chris@0
|
97 $endKey = array_pop($keyPath);
|
Chris@0
|
98 for ( $i = 0; $i < count($keyPath); $i++ ) {
|
Chris@0
|
99 $currentKey =& $keyPath[$i];
|
Chris@0
|
100 if (!isset($currentValue[$currentKey])) {
|
Chris@0
|
101 $currentValue[$currentKey] = array();
|
Chris@0
|
102 }
|
Chris@0
|
103 if (!is_array($currentValue[$currentKey])) {
|
Chris@0
|
104 throw new \RuntimeException("Key path at $currentKey of $key cannot be indexed into (is not an array)");
|
Chris@0
|
105 }
|
Chris@0
|
106 $currentValue =& $currentValue[$currentKey];
|
Chris@0
|
107 }
|
Chris@0
|
108 $currentValue[$endKey] = $value;
|
Chris@0
|
109 }
|
Chris@0
|
110
|
Chris@0
|
111 /**
|
Chris@0
|
112 * {@inheritdoc}
|
Chris@0
|
113 */
|
Chris@0
|
114 public function remove($key)
|
Chris@0
|
115 {
|
Chris@0
|
116 if (0 == strlen($key)) {
|
Chris@0
|
117 throw new \RuntimeException("Key cannot be an empty string");
|
Chris@0
|
118 }
|
Chris@0
|
119
|
Chris@0
|
120 $currentValue =& $this->data;
|
Chris@0
|
121 $keyPath = explode('.', $key);
|
Chris@0
|
122
|
Chris@0
|
123 if (1 == count($keyPath)) {
|
Chris@0
|
124 unset($currentValue[$key]);
|
Chris@0
|
125
|
Chris@0
|
126 return;
|
Chris@0
|
127 }
|
Chris@0
|
128
|
Chris@0
|
129 $endKey = array_pop($keyPath);
|
Chris@0
|
130 for ( $i = 0; $i < count($keyPath); $i++ ) {
|
Chris@0
|
131 $currentKey =& $keyPath[$i];
|
Chris@0
|
132 if (!isset($currentValue[$currentKey])) {
|
Chris@0
|
133 return;
|
Chris@0
|
134 }
|
Chris@0
|
135 $currentValue =& $currentValue[$currentKey];
|
Chris@0
|
136 }
|
Chris@0
|
137 unset($currentValue[$endKey]);
|
Chris@0
|
138 }
|
Chris@0
|
139
|
Chris@0
|
140 /**
|
Chris@0
|
141 * {@inheritdoc}
|
Chris@0
|
142 */
|
Chris@0
|
143 public function get($key, $default = null)
|
Chris@0
|
144 {
|
Chris@0
|
145 $currentValue = $this->data;
|
Chris@0
|
146 $keyPath = explode('.', $key);
|
Chris@0
|
147
|
Chris@0
|
148 for ( $i = 0; $i < count($keyPath); $i++ ) {
|
Chris@0
|
149 $currentKey = $keyPath[$i];
|
Chris@0
|
150 if (!isset($currentValue[$currentKey]) ) {
|
Chris@0
|
151 return $default;
|
Chris@0
|
152 }
|
Chris@0
|
153 if (!is_array($currentValue)) {
|
Chris@0
|
154 return $default;
|
Chris@0
|
155 }
|
Chris@0
|
156 $currentValue = $currentValue[$currentKey];
|
Chris@0
|
157 }
|
Chris@0
|
158
|
Chris@0
|
159 return $currentValue === null ? $default : $currentValue;
|
Chris@0
|
160 }
|
Chris@0
|
161
|
Chris@0
|
162 /**
|
Chris@0
|
163 * {@inheritdoc}
|
Chris@0
|
164 */
|
Chris@0
|
165 public function has($key)
|
Chris@0
|
166 {
|
Chris@0
|
167 $currentValue = &$this->data;
|
Chris@0
|
168 $keyPath = explode('.', $key);
|
Chris@0
|
169
|
Chris@0
|
170 for ( $i = 0; $i < count($keyPath); $i++ ) {
|
Chris@0
|
171 $currentKey = $keyPath[$i];
|
Chris@0
|
172 if (
|
Chris@0
|
173 !is_array($currentValue) ||
|
Chris@0
|
174 !array_key_exists($currentKey, $currentValue)
|
Chris@0
|
175 ) {
|
Chris@0
|
176 return false;
|
Chris@0
|
177 }
|
Chris@0
|
178 $currentValue = &$currentValue[$currentKey];
|
Chris@0
|
179 }
|
Chris@0
|
180
|
Chris@0
|
181 return true;
|
Chris@0
|
182 }
|
Chris@0
|
183
|
Chris@0
|
184 /**
|
Chris@0
|
185 * {@inheritdoc}
|
Chris@0
|
186 */
|
Chris@0
|
187 public function getData($key)
|
Chris@0
|
188 {
|
Chris@0
|
189 $value = $this->get($key);
|
Chris@0
|
190 if (is_array($value) && Util::isAssoc($value)) {
|
Chris@0
|
191 return new Data($value);
|
Chris@0
|
192 }
|
Chris@0
|
193
|
Chris@0
|
194 throw new \RuntimeException("Value at '$key' could not be represented as a DataInterface");
|
Chris@0
|
195 }
|
Chris@0
|
196
|
Chris@0
|
197 /**
|
Chris@0
|
198 * {@inheritdoc}
|
Chris@0
|
199 */
|
Chris@0
|
200 public function import(array $data, $clobber = true)
|
Chris@0
|
201 {
|
Chris@0
|
202 $this->data = Util::mergeAssocArray($this->data, $data, $clobber);
|
Chris@0
|
203 }
|
Chris@0
|
204
|
Chris@0
|
205 /**
|
Chris@0
|
206 * {@inheritdoc}
|
Chris@0
|
207 */
|
Chris@0
|
208 public function importData(DataInterface $data, $clobber = true)
|
Chris@0
|
209 {
|
Chris@0
|
210 $this->import($data->export(), $clobber);
|
Chris@0
|
211 }
|
Chris@0
|
212
|
Chris@0
|
213 /**
|
Chris@0
|
214 * {@inheritdoc}
|
Chris@0
|
215 */
|
Chris@0
|
216 public function export()
|
Chris@0
|
217 {
|
Chris@0
|
218 return $this->data;
|
Chris@0
|
219 }
|
Chris@0
|
220 }
|