Container.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\View\Layout\Reader;
  7. use Magento\Framework\View\Layout;
  8. /**
  9. * Class Container
  10. */
  11. class Container implements Layout\ReaderInterface
  12. {
  13. /**#@+
  14. * Supported types
  15. */
  16. const TYPE_CONTAINER = 'container';
  17. const TYPE_REFERENCE_CONTAINER = 'referenceContainer';
  18. /**#@-*/
  19. /**#@+
  20. * Names of container options in layout
  21. */
  22. const CONTAINER_OPT_HTML_TAG = 'htmlTag';
  23. const CONTAINER_OPT_HTML_CLASS = 'htmlClass';
  24. const CONTAINER_OPT_HTML_ID = 'htmlId';
  25. const CONTAINER_OPT_LABEL = 'label';
  26. const CONTAINER_OPT_DISPLAY = 'display';
  27. /**#@-*/
  28. /**#@-*/
  29. protected $helper;
  30. /**
  31. * @var \Magento\Framework\View\Layout\ReaderPool
  32. */
  33. protected $readerPool;
  34. /**
  35. * Constructor
  36. *
  37. * @param Layout\ScheduledStructure\Helper $helper
  38. * @param Layout\ReaderPool $readerPool
  39. */
  40. public function __construct(
  41. Layout\ScheduledStructure\Helper $helper,
  42. Layout\ReaderPool $readerPool
  43. ) {
  44. $this->helper = $helper;
  45. $this->readerPool = $readerPool;
  46. }
  47. /**
  48. * @return string[]
  49. */
  50. public function getSupportedNodes()
  51. {
  52. return [self::TYPE_CONTAINER, self::TYPE_REFERENCE_CONTAINER];
  53. }
  54. /**
  55. * {@inheritdoc}
  56. *
  57. * @param Context $readerContext
  58. * @param Layout\Element $currentElement
  59. * @param Layout\Element $parentElement
  60. * @return $this
  61. */
  62. public function interpret(Context $readerContext, Layout\Element $currentElement)
  63. {
  64. switch ($currentElement->getName()) {
  65. case self::TYPE_CONTAINER:
  66. $this->helper->scheduleStructure(
  67. $readerContext->getScheduledStructure(),
  68. $currentElement,
  69. $currentElement->getParent()
  70. );
  71. $this->mergeContainerAttributes($readerContext->getScheduledStructure(), $currentElement);
  72. break;
  73. case self::TYPE_REFERENCE_CONTAINER:
  74. $this->containerReference($readerContext->getScheduledStructure(), $currentElement);
  75. break;
  76. default:
  77. break;
  78. }
  79. $this->readerPool->interpret($readerContext, $currentElement);
  80. return $this;
  81. }
  82. /**
  83. * Merge Container attributes
  84. *
  85. * @param \Magento\Framework\View\Layout\ScheduledStructure $scheduledStructure
  86. * @param \Magento\Framework\View\Layout\Element $currentElement
  87. * @return void
  88. */
  89. protected function mergeContainerAttributes(
  90. Layout\ScheduledStructure $scheduledStructure,
  91. Layout\Element $currentElement
  92. ) {
  93. $containerName = $currentElement->getAttribute('name');
  94. $elementData = $scheduledStructure->getStructureElementData($containerName);
  95. if (isset($elementData['attributes'])) {
  96. $keys = array_keys($elementData['attributes']);
  97. foreach ($keys as $key) {
  98. if (isset($currentElement[$key])) {
  99. $elementData['attributes'][$key] = (string)$currentElement[$key];
  100. }
  101. }
  102. } else {
  103. $elementData['attributes'] = [
  104. self::CONTAINER_OPT_HTML_TAG => (string)$currentElement[self::CONTAINER_OPT_HTML_TAG],
  105. self::CONTAINER_OPT_HTML_ID => (string)$currentElement[self::CONTAINER_OPT_HTML_ID],
  106. self::CONTAINER_OPT_HTML_CLASS => (string)$currentElement[self::CONTAINER_OPT_HTML_CLASS],
  107. self::CONTAINER_OPT_LABEL => (string)$currentElement[self::CONTAINER_OPT_LABEL],
  108. self::CONTAINER_OPT_DISPLAY => (string)$currentElement[self::CONTAINER_OPT_DISPLAY],
  109. ];
  110. }
  111. $scheduledStructure->setStructureElementData($containerName, $elementData);
  112. }
  113. /**
  114. * Handling reference of container
  115. *
  116. * If attribute remove="true" then add the element to list remove,
  117. * else merge container attributes
  118. *
  119. * @param Layout\ScheduledStructure $scheduledStructure
  120. * @param Layout\Element $currentElement
  121. * @return void
  122. */
  123. protected function containerReference(
  124. Layout\ScheduledStructure $scheduledStructure,
  125. Layout\Element $currentElement
  126. ) {
  127. $containerName = $currentElement->getAttribute('name');
  128. $containerRemove = filter_var($currentElement->getAttribute('remove'), FILTER_VALIDATE_BOOLEAN);
  129. if ($containerRemove) {
  130. $scheduledStructure->setElementToRemoveList($containerName);
  131. return;
  132. } elseif ($currentElement->getAttribute('remove')) {
  133. $scheduledStructure->unsetElementFromListToRemove($containerName);
  134. }
  135. $this->mergeContainerAttributes($scheduledStructure, $currentElement);
  136. }
  137. }