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