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