Element.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. * Class Element
  9. *
  10. * @api
  11. * @since 100.0.2
  12. */
  13. class Element extends \Magento\Framework\Simplexml\Element
  14. {
  15. /**#@+
  16. * Supported layout directives
  17. */
  18. const TYPE_RENDERER = 'renderer';
  19. const TYPE_TEMPLATE = 'template';
  20. const TYPE_DATA = 'data';
  21. const TYPE_BLOCK = 'block';
  22. const TYPE_CONTAINER = 'container';
  23. const TYPE_ACTION = 'action';
  24. const TYPE_ARGUMENTS = 'arguments';
  25. const TYPE_ARGUMENT = 'argument';
  26. const TYPE_REFERENCE_BLOCK = 'referenceBlock';
  27. const TYPE_REFERENCE_CONTAINER = 'referenceContainer';
  28. const TYPE_REMOVE = 'remove';
  29. const TYPE_MOVE = 'move';
  30. const TYPE_UI_COMPONENT = 'uiComponent';
  31. const TYPE_HEAD = 'head';
  32. /**#@-*/
  33. /**#@+
  34. * Names of container options in layout
  35. */
  36. const CONTAINER_OPT_HTML_TAG = 'htmlTag';
  37. const CONTAINER_OPT_HTML_CLASS = 'htmlClass';
  38. const CONTAINER_OPT_HTML_ID = 'htmlId';
  39. const CONTAINER_OPT_LABEL = 'label';
  40. /**#@-*/
  41. /**
  42. * Prepare the element
  43. *
  44. * @return $this
  45. *
  46. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  47. */
  48. public function prepare()
  49. {
  50. switch ($this->getName()) {
  51. case self::TYPE_BLOCK:
  52. case self::TYPE_RENDERER:
  53. case self::TYPE_TEMPLATE:
  54. case self::TYPE_DATA:
  55. case self::TYPE_UI_COMPONENT:
  56. $this->prepareBlock();
  57. break;
  58. case self::TYPE_REFERENCE_BLOCK:
  59. case self::TYPE_REFERENCE_CONTAINER:
  60. $this->prepareReference();
  61. break;
  62. case self::TYPE_ACTION:
  63. $this->prepareAction();
  64. break;
  65. case self::TYPE_ARGUMENT:
  66. $this->prepareActionArgument();
  67. break;
  68. default:
  69. break;
  70. }
  71. foreach ($this as $child) {
  72. /** @var Element $child */
  73. $child->prepare();
  74. }
  75. return $this;
  76. }
  77. /**
  78. * Get block name
  79. *
  80. * @return bool|string
  81. */
  82. public function getBlockName()
  83. {
  84. $tagName = (string)$this->getName();
  85. $isThisBlock = empty($this['name']) || !in_array(
  86. $tagName,
  87. [self::TYPE_BLOCK, self::TYPE_REFERENCE_BLOCK]
  88. );
  89. if ($isThisBlock) {
  90. return false;
  91. }
  92. return (string)$this['name'];
  93. }
  94. /**
  95. * Get element name
  96. *
  97. * Advanced version of getBlockName() method: gets name for container as well as for block
  98. *
  99. * @return string|bool
  100. */
  101. public function getElementName()
  102. {
  103. $tagName = $this->getName();
  104. $isThisContainer = !in_array(
  105. $tagName,
  106. [self::TYPE_BLOCK, self::TYPE_REFERENCE_BLOCK, self::TYPE_CONTAINER, self::TYPE_REFERENCE_CONTAINER]
  107. );
  108. if ($isThisContainer) {
  109. return false;
  110. }
  111. return $this->getAttribute('name');
  112. }
  113. /**
  114. * Extracts sibling from 'before' and 'after' attributes
  115. *
  116. * @return string
  117. */
  118. public function getSibling()
  119. {
  120. $sibling = null;
  121. if ($this->getAttribute('before')) {
  122. $sibling = $this->getAttribute('before');
  123. } elseif ($this->getAttribute('after')) {
  124. $sibling = $this->getAttribute('after');
  125. }
  126. return $sibling;
  127. }
  128. /**
  129. * Add parent element name to parent attribute
  130. *
  131. * @return $this
  132. */
  133. public function prepareBlock()
  134. {
  135. $parent = $this->getParent();
  136. if (isset($parent['name']) && !isset($this['parent'])) {
  137. $this->addAttribute('parent', (string)$parent['name']);
  138. }
  139. return $this;
  140. }
  141. /**
  142. * Prepare references
  143. *
  144. * @return $this
  145. */
  146. public function prepareReference()
  147. {
  148. return $this;
  149. }
  150. /**
  151. * Add parent element name to block attribute
  152. *
  153. * @return $this
  154. */
  155. public function prepareAction()
  156. {
  157. $parent = $this->getParent();
  158. $this->addAttribute('block', (string)$parent['name']);
  159. return $this;
  160. }
  161. /**
  162. * Prepare action argument
  163. *
  164. * @return $this
  165. */
  166. public function prepareActionArgument()
  167. {
  168. return $this;
  169. }
  170. /**
  171. * Returns information is this element allows caching
  172. *
  173. * @return bool
  174. */
  175. public function isCacheable()
  176. {
  177. return !(bool)count($this->xpath('//' . self::TYPE_BLOCK . '[@cacheable="false"]'));
  178. }
  179. }