ScheduledStructure.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\View\Layout;
  7. /**
  8. * Layout structure model
  9. *
  10. * @api
  11. * @since 100.0.2
  12. */
  13. class ScheduledStructure
  14. {
  15. /**#@+
  16. * Keys for array of elements to sort
  17. */
  18. const ELEMENT_NAME = 'elementName';
  19. const ELEMENT_PARENT_NAME = 'parentName';
  20. const ELEMENT_OFFSET_OR_SIBLING = 'offsetOrSibling';
  21. const ELEMENT_IS_AFTER = 'isAfter';
  22. /**#@-*/
  23. /**#@-*/
  24. private $serializableProperties = [
  25. 'scheduledStructure',
  26. 'scheduledData',
  27. 'scheduledElements',
  28. 'scheduledMoves',
  29. 'scheduledRemoves',
  30. 'scheduledPaths',
  31. 'elementsToSort',
  32. 'brokenParent',
  33. ];
  34. /**
  35. * Information about structural elements, scheduled for creation
  36. *
  37. * @var array
  38. */
  39. protected $scheduledStructure = [];
  40. /**
  41. * Scheduled structure data
  42. *
  43. * @var array
  44. */
  45. protected $scheduledData = [];
  46. /**
  47. * Full information about elements to be populated in the layout structure after generating structure
  48. *
  49. * @var array
  50. */
  51. protected $scheduledElements = [];
  52. /**
  53. * Scheduled structure elements moves
  54. *
  55. * @var array
  56. */
  57. protected $scheduledMoves = [];
  58. /**
  59. * Scheduled structure elements removes
  60. *
  61. * @var array
  62. */
  63. protected $scheduledRemoves = [];
  64. /**
  65. * Materialized paths for overlapping workaround of scheduled structural elements
  66. *
  67. * @var array
  68. */
  69. protected $scheduledPaths = [];
  70. /**
  71. * Elements with reference to non-existing parent element
  72. *
  73. * @var array
  74. */
  75. protected $brokenParent = [];
  76. /**
  77. * Elements that need to sort
  78. *
  79. * @var array
  80. */
  81. protected $elementsToSort = [];
  82. /**
  83. * @param array $data
  84. */
  85. public function __construct(array $data = [])
  86. {
  87. $this->populateWithArray($data);
  88. }
  89. /**
  90. * Set elements to sort
  91. *
  92. * @param string $parentName
  93. * @param string $elementName
  94. * @param string|int|null $offsetOrSibling
  95. * @param bool $isAfter
  96. * @return void
  97. */
  98. public function setElementToSortList($parentName, $elementName, $offsetOrSibling, $isAfter = true)
  99. {
  100. $this->elementsToSort[$elementName] = [
  101. self::ELEMENT_NAME => $elementName,
  102. self::ELEMENT_PARENT_NAME => $parentName,
  103. self::ELEMENT_OFFSET_OR_SIBLING => $offsetOrSibling,
  104. self::ELEMENT_IS_AFTER => $isAfter
  105. ];
  106. }
  107. /**
  108. * Check if elements list of sorting is empty
  109. *
  110. * @return bool
  111. */
  112. public function isListToSortEmpty()
  113. {
  114. return empty($this->elementsToSort);
  115. }
  116. /**
  117. * Unset specified element from list of sorting
  118. *
  119. * @param string $elementName
  120. * @return void
  121. */
  122. public function unsetElementToSort($elementName)
  123. {
  124. unset($this->elementsToSort[$elementName]);
  125. }
  126. /**
  127. * Get element to sort by name
  128. *
  129. * @param string $elementName
  130. * @param array $default
  131. * @return array
  132. */
  133. public function getElementToSort($elementName, array $default = [])
  134. {
  135. return $this->elementsToSort[$elementName] ?? $default;
  136. }
  137. /**
  138. * Get elements to sort
  139. *
  140. * @return array
  141. */
  142. public function getListToSort()
  143. {
  144. return $this->elementsToSort;
  145. }
  146. /**
  147. * Get elements to move
  148. *
  149. * @return array
  150. */
  151. public function getListToMove()
  152. {
  153. return array_keys(array_intersect_key($this->scheduledElements, $this->scheduledMoves));
  154. }
  155. /**
  156. * Get elements to remove
  157. *
  158. * @return array
  159. */
  160. public function getListToRemove()
  161. {
  162. return array_keys(array_intersect_key(
  163. $this->scheduledElements,
  164. array_merge($this->scheduledRemoves, $this->brokenParent)
  165. ));
  166. }
  167. /**
  168. * Get scheduled elements list
  169. *
  170. * @return array
  171. */
  172. public function getElements()
  173. {
  174. return $this->scheduledElements;
  175. }
  176. /**
  177. * Get element by name
  178. *
  179. * @param string $elementName
  180. * @param array $default
  181. * @return bool|array
  182. */
  183. public function getElement($elementName, $default = [])
  184. {
  185. return $this->hasElement($elementName) ? $this->scheduledElements[$elementName] : $default;
  186. }
  187. /**
  188. * Check if scheduled elements list is empty
  189. *
  190. * @return bool
  191. */
  192. public function isElementsEmpty()
  193. {
  194. return empty($this->scheduledElements);
  195. }
  196. /**
  197. * Add element to scheduled elements list
  198. *
  199. * @param string $elementName
  200. * @param array $data
  201. * @return void
  202. */
  203. public function setElement($elementName, array $data)
  204. {
  205. $this->scheduledElements[$elementName] = $data;
  206. }
  207. /**
  208. * Check if element present in scheduled elements list
  209. *
  210. * @param string $elementName
  211. * @return bool
  212. */
  213. public function hasElement($elementName)
  214. {
  215. return isset($this->scheduledElements[$elementName]);
  216. }
  217. /**
  218. * Unset specified element from scheduled elements list
  219. *
  220. * @param string $elementName
  221. * @return void
  222. */
  223. public function unsetElement($elementName)
  224. {
  225. unset($this->scheduledElements[$elementName]);
  226. }
  227. /**
  228. * Get element to move by name
  229. *
  230. * @param string $elementName
  231. * @param mixed $default
  232. * @return mixed
  233. */
  234. public function getElementToMove($elementName, $default = null)
  235. {
  236. return $this->scheduledMoves[$elementName] ?? $default;
  237. }
  238. /**
  239. * Add element to move list
  240. *
  241. * @param string $elementName
  242. * @param array $data
  243. * @return void
  244. */
  245. public function setElementToMove($elementName, array $data)
  246. {
  247. $this->scheduledMoves[$elementName] = $data;
  248. }
  249. /**
  250. * Unset removed element by name
  251. *
  252. * @param string $elementName
  253. * @return void
  254. */
  255. public function unsetElementFromListToRemove($elementName)
  256. {
  257. unset($this->scheduledRemoves[$elementName]);
  258. }
  259. /**
  260. * Set removed element value
  261. *
  262. * @param string $elementName
  263. * @return void
  264. */
  265. public function setElementToRemoveList($elementName)
  266. {
  267. $this->scheduledRemoves[$elementName] = 1;
  268. }
  269. /**
  270. * Get scheduled structure
  271. *
  272. * @return array
  273. */
  274. public function getStructure()
  275. {
  276. return $this->scheduledStructure;
  277. }
  278. /**
  279. * Get element of scheduled structure
  280. *
  281. * @param string $elementName
  282. * @param mixed|null $default
  283. * @return mixed
  284. */
  285. public function getStructureElement($elementName, $default = null)
  286. {
  287. return $this->hasStructureElement($elementName) ? $this->scheduledStructure[$elementName] : $default;
  288. }
  289. /**
  290. * Check if scheduled structure is empty
  291. *
  292. * @return bool
  293. */
  294. public function isStructureEmpty()
  295. {
  296. return empty($this->scheduledStructure);
  297. }
  298. /**
  299. * Check if element present in scheduled structure elements list
  300. *
  301. * @param string $elementName
  302. * @return bool
  303. */
  304. public function hasStructureElement($elementName)
  305. {
  306. return isset($this->scheduledStructure[$elementName]);
  307. }
  308. /**
  309. * Add element to scheduled structure elements list
  310. *
  311. * @param string $elementName
  312. * @param array $data
  313. * @return void
  314. */
  315. public function setStructureElement($elementName, array $data)
  316. {
  317. $this->scheduledStructure[$elementName] = $data;
  318. }
  319. /**
  320. * Unset scheduled structure element by name
  321. *
  322. * @param string $elementName
  323. * @return void
  324. */
  325. public function unsetStructureElement($elementName)
  326. {
  327. unset($this->scheduledStructure[$elementName]);
  328. unset($this->scheduledData[$elementName]);
  329. }
  330. /**
  331. * Get scheduled data for element
  332. *
  333. * @param string $elementName
  334. * @param null $default
  335. * @return null
  336. */
  337. public function getStructureElementData($elementName, $default = null)
  338. {
  339. return $this->scheduledData[$elementName] ?? $default;
  340. }
  341. /**
  342. * Set scheduled data for element
  343. *
  344. * @param string $elementName
  345. * @param array $data
  346. * @return void
  347. */
  348. public function setStructureElementData($elementName, array $data)
  349. {
  350. $this->scheduledData[$elementName] = $data;
  351. }
  352. /**
  353. * Get scheduled paths
  354. *
  355. * @return array
  356. */
  357. public function getPaths()
  358. {
  359. return $this->scheduledPaths;
  360. }
  361. /**
  362. * Get path from paths list
  363. *
  364. * @param string $elementName
  365. * @param mixed $default
  366. * @return mixed
  367. */
  368. public function getPath($elementName, $default = null)
  369. {
  370. return $this->hasPath($elementName) ? $this->scheduledPaths[$elementName] : $default;
  371. }
  372. /**
  373. * Check if element present in scheduled paths list
  374. *
  375. * @param string $elementName
  376. * @return bool
  377. */
  378. public function hasPath($elementName)
  379. {
  380. return isset($this->scheduledPaths[$elementName]);
  381. }
  382. /**
  383. * Add element to scheduled paths elements list
  384. *
  385. * @param string $elementName
  386. * @param string $data
  387. * @return void
  388. */
  389. public function setPathElement($elementName, $data)
  390. {
  391. $this->scheduledPaths[$elementName] = $data;
  392. }
  393. /**
  394. * Unset scheduled paths element by name
  395. *
  396. * @param string $elementName
  397. * @return void
  398. */
  399. public function unsetPathElement($elementName)
  400. {
  401. unset($this->scheduledPaths[$elementName]);
  402. }
  403. /**
  404. * Remove element from broken parent list
  405. *
  406. * @param string $elementName
  407. * @return void
  408. */
  409. public function unsetElementFromBrokenParentList($elementName)
  410. {
  411. unset($this->brokenParent[$elementName]);
  412. }
  413. /**
  414. * Set element to broken parent list
  415. *
  416. * @param string $elementName
  417. * @return void
  418. */
  419. public function setElementToBrokenParentList($elementName)
  420. {
  421. $this->brokenParent[$elementName] = 1;
  422. }
  423. /**
  424. * Flush scheduled paths list
  425. *
  426. * @return void
  427. */
  428. public function flushPaths()
  429. {
  430. $this->scheduledPaths = [];
  431. }
  432. /**
  433. * Flush scheduled structure list
  434. *
  435. * @return void
  436. */
  437. public function flushScheduledStructure()
  438. {
  439. $this->flushPaths();
  440. $this->scheduledElements = [];
  441. $this->scheduledStructure = [];
  442. }
  443. /**
  444. * Reformat 'Layout scheduled structure' to array.
  445. *
  446. * @return array
  447. * @since 101.0.0
  448. */
  449. public function __toArray()
  450. {
  451. $result = [];
  452. foreach ($this->serializableProperties as $property) {
  453. $result[$property] = $this->{$property};
  454. }
  455. return $result;
  456. }
  457. /**
  458. * Update 'Layout scheduled structure' data.
  459. *
  460. * @param array $data
  461. * @return void
  462. * @since 101.0.0
  463. */
  464. public function populateWithArray(array $data)
  465. {
  466. foreach ($this->serializableProperties as $property) {
  467. $this->{$property} = $this->getArrayValueByKey($property, $data);
  468. }
  469. }
  470. /**
  471. * Get value from array by key.
  472. *
  473. * @param string $key
  474. * @param array $array
  475. * @return array
  476. */
  477. private function getArrayValueByKey($key, array $array)
  478. {
  479. return $array[$key] ?? [];
  480. }
  481. }