/themes/bootstrap/src/Utility/ArrayObject.php

https://gitlab.com/guillaumev/alkarama · PHP · 404 lines · 147 code · 40 blank · 217 comment · 11 complexity · ece61882f5c9e4f4c96687d9af0f440f MD5 · raw file

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