Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / web / themes / contrib / bootstrap / src / Utility / ArrayObject.php
1 <?php
2
3 namespace Drupal\bootstrap\Utility;
4
5 use Drupal\Component\Utility\NestedArray;
6 use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
7 use Drupal\Core\Render\AttachmentsInterface;
8 use Drupal\Core\Render\BubbleableMetadata;
9
10 /**
11  * Custom ArrayObject implementation.
12  *
13  * The native ArrayObject is unnecessarily complicated.
14  *
15  * @ingroup utility
16  */
17 class ArrayObject implements \IteratorAggregate, \ArrayAccess, \Serializable, \Countable, AttachmentsInterface, RefinableCacheableDependencyInterface {
18
19   /**
20    * The array.
21    *
22    * @var array
23    */
24   protected $array;
25
26   /**
27    * Array object constructor.
28    *
29    * @param array $array
30    *   An array.
31    */
32   public function __construct(array $array = []) {
33     $this->array = $array;
34   }
35
36   /**
37    * Returns whether the requested key exists.
38    *
39    * @param mixed $key
40    *   A key.
41    *
42    * @return bool
43    *   TRUE or FALSE
44    */
45   public function __isset($key) {
46     return $this->offsetExists($key);
47   }
48
49   /**
50    * Sets the value at the specified key to value.
51    *
52    * @param mixed $key
53    *   A key.
54    * @param mixed $value
55    *   A value.
56    */
57   public function __set($key, $value) {
58     $this->offsetSet($key, $value);
59   }
60
61   /**
62    * Unsets the value at the specified key.
63    *
64    * @param mixed $key
65    *   A key.
66    */
67   public function __unset($key) {
68     $this->offsetUnset($key);
69   }
70
71   /**
72    * Returns the value at the specified key by reference.
73    *
74    * @param mixed $key
75    *   A key.
76    *
77    * @return mixed
78    *   The stored value.
79    */
80   public function &__get($key) {
81     $ret =& $this->offsetGet($key);
82     return $ret;
83   }
84
85   /**
86    * {@inheritdoc}
87    */
88   public function addAttachments(array $attachments) {
89     BubbleableMetadata::createFromRenderArray($this->array)->addAttachments($attachments)->applyTo($this->array);
90     return $this;
91   }
92
93   /**
94    * {@inheritdoc}
95    */
96   public function addCacheContexts(array $cache_contexts) {
97     BubbleableMetadata::createFromRenderArray($this->array)->addCacheContexts($cache_contexts)->applyTo($this->array);
98     return $this;
99   }
100
101   /**
102    * {@inheritdoc}
103    */
104   public function addCacheTags(array $cache_tags) {
105     BubbleableMetadata::createFromRenderArray($this->array)->addCacheTags($cache_tags)->applyTo($this->array);
106     return $this;
107   }
108
109   /**
110    * {@inheritdoc}
111    */
112   public function addCacheableDependency($other_object) {
113     BubbleableMetadata::createFromRenderArray($this->array)->addCacheableDependency($other_object)->applyTo($this->array);
114     return $this;
115   }
116
117   /**
118    * Appends the value.
119    *
120    * @param mixed $value
121    *   A value.
122    */
123   public function append($value) {
124     $this->array[] = $value;
125   }
126
127   /**
128    * Sort the entries by value.
129    */
130   public function asort() {
131     asort($this->array);
132   }
133
134   /**
135    * Merges an object's cacheable metadata into the variables array.
136    *
137    * @param \Drupal\Core\Cache\CacheableDependencyInterface|mixed $object
138    *   The object whose cacheability metadata to retrieve. If it implements
139    *   CacheableDependencyInterface, its cacheability metadata will be used,
140    *   otherwise, the passed in object must be assumed to be uncacheable, so
141    *   max-age 0 is set.
142    *
143    * @return $this
144    */
145   public function bubbleObject($object) {
146     BubbleableMetadata::createFromRenderArray($this->array)->merge(BubbleableMetadata::createFromObject($object))->applyTo($this->array);
147     return $this;
148   }
149
150   /**
151    * Merges a render array's cacheable metadata into the variables array.
152    *
153    * @param array $build
154    *   A render array.
155    *
156    * @return $this
157    */
158   public function bubbleRenderArray(array $build) {
159     BubbleableMetadata::createFromRenderArray($this->array)->merge(BubbleableMetadata::createFromRenderArray($build))->applyTo($this->array);
160     return $this;
161   }
162
163   /**
164    * Get the number of public properties in the ArrayObject.
165    *
166    * @return int
167    *   The count.
168    */
169   public function count() {
170     return count($this->array);
171   }
172
173   /**
174    * Exchange the array for another one.
175    *
176    * @param array|ArrayObject $data
177    *   New data.
178    *
179    * @return array
180    *   The old array.
181    *
182    * @throws \InvalidArgumentException
183    *   When the passed data is not an array or an instance of ArrayObject.
184    */
185   public function exchangeArray($data) {
186     if (!is_array($data) && is_object($data) && !($data instanceof ArrayObject)) {
187       throw new \InvalidArgumentException('Passed variable is not an array or an instance of \Drupal\bootstrap\Utility\ArrayObject.');
188     }
189     if (is_object($data) && $data instanceof ArrayObject) {
190       $data = $data->getArrayCopy();
191     }
192     $old = $this->array;
193     $this->array = $data;
194     return $old;
195   }
196
197   /**
198    * Creates a copy of the ArrayObject.
199    *
200    * @return array
201    *   A copy of the array.
202    */
203   public function getArrayCopy() {
204     return $this->array;
205   }
206
207   /**
208    * {@inheritdoc}
209    */
210   public function getAttachments() {
211     return BubbleableMetadata::createFromRenderArray($this->array)->getAttachments();
212   }
213
214   /**
215    * {@inheritdoc}
216    */
217   public function getCacheContexts() {
218     return BubbleableMetadata::createFromRenderArray($this->array)->getCacheContexts();
219   }
220
221   /**
222    * {@inheritdoc}
223    */
224   public function getCacheTags() {
225     return BubbleableMetadata::createFromRenderArray($this->array)->getCacheTags();
226   }
227
228   /**
229    * {@inheritdoc}
230    */
231   public function getCacheMaxAge() {
232     return BubbleableMetadata::createFromRenderArray($this->array)->getCacheMaxAge();
233   }
234
235   /**
236    * Creates a new iterator from an ArrayObject instance.
237    *
238    * @return \ArrayIterator
239    *   An array iterator.
240    */
241   public function getIterator() {
242     return new \ArrayIterator($this->array);
243   }
244
245   /**
246    * Sort the entries by key.
247    */
248   public function ksort() {
249     ksort($this->array);
250   }
251
252   /**
253    * Merges multiple values into the array.
254    *
255    * @param array $values
256    *   An associative key/value array.
257    * @param bool $recursive
258    *   Flag determining whether or not to recursively merge key/value pairs.
259    */
260   public function merge(array $values, $recursive = TRUE) {
261     if ($recursive) {
262       $this->array = NestedArray::mergeDeepArray([$this->array, $values], TRUE);
263     }
264     else {
265       $this->array += $values;
266     }
267   }
268
269   /**
270    * {@inheritdoc}
271    */
272   public function mergeCacheMaxAge($max_age) {
273     BubbleableMetadata::createFromRenderArray($this->array)->mergeCacheMaxAge($max_age)->applyTo($this->array);
274     return $this;
275   }
276
277   /**
278    * Sort an array using a case insensitive "natural order" algorithm.
279    */
280   public function natcasesort() {
281     natcasesort($this->array);
282   }
283
284   /**
285    * Sort entries using a "natural order" algorithm.
286    */
287   public function natsort() {
288     natsort($this->array);
289   }
290
291   /**
292    * Returns whether the requested key exists.
293    *
294    * @param mixed $key
295    *   A key.
296    *
297    * @return bool
298    *   TRUE or FALSE
299    */
300   public function offsetExists($key) {
301     return isset($this->array[$key]);
302   }
303
304   /**
305    * Returns the value at the specified key.
306    *
307    * @param mixed $key
308    *   A key.
309    * @param mixed $default
310    *   The default value to set if $key does not exist.
311    *
312    * @return mixed
313    *   The value.
314    */
315   public function &offsetGet($key, $default = NULL) {
316     if (!$this->offsetExists($key)) {
317       $this->array[$key] = $default;
318     }
319     $ret = &$this->array[$key];
320     return $ret;
321   }
322
323   /**
324    * Sets the value at the specified key to value.
325    *
326    * @param mixed $key
327    *   A key.
328    * @param mixed $value
329    *   A value.
330    */
331   public function offsetSet($key, $value) {
332     $this->array[$key] = $value;
333   }
334
335   /**
336    * Unsets the value at the specified key.
337    *
338    * @param mixed $key
339    *   A key.
340    */
341   public function offsetUnset($key) {
342     if ($this->offsetExists($key)) {
343       unset($this->array[$key]);
344     }
345   }
346
347   /**
348    * Serialize an ArrayObject.
349    *
350    * @return string
351    *   The serialized value.
352    */
353   public function serialize() {
354     return serialize(get_object_vars($this));
355   }
356
357   /**
358    * {@inheritdoc}
359    */
360   public function setAttachments(array $attachments) {
361     BubbleableMetadata::createFromRenderArray($this->array)->setAttachments($attachments)->applyTo($this->array);
362     return $this;
363   }
364
365   /**
366    * Sort entries with a user-defined function and maintain key association.
367    *
368    * @param mixed $function
369    *   A callable function.
370    */
371   public function uasort($function) {
372     if (is_callable($function)) {
373       uasort($this->array, $function);
374     }
375   }
376
377   /**
378    * Sort the entries by keys using a user-defined comparison function.
379    *
380    * @param mixed $function
381    *   A callable function.
382    */
383   public function uksort($function) {
384     if (is_callable($function)) {
385       uksort($this->array, $function);
386     }
387   }
388
389   /**
390    * Unserialize an ArrayObject.
391    *
392    * @param string $data
393    *   The serialized data.
394    */
395   public function unserialize($data) {
396     $data = unserialize($data);
397     $this->exchangeArray($data['array']);
398   }
399
400 }