Compiler.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\View\TemplateEngine\Xhtml;
  7. use Magento\Framework\DataObject;
  8. use Magento\Framework\View\TemplateEngine\Xhtml\Compiler\AttributeInterface;
  9. use Magento\Framework\View\TemplateEngine\Xhtml\Compiler\CdataInterface;
  10. use Magento\Framework\View\TemplateEngine\Xhtml\Compiler\CommentInterface;
  11. use Magento\Framework\View\TemplateEngine\Xhtml\Compiler\Element\ElementInterface;
  12. use Magento\Framework\View\TemplateEngine\Xhtml\Compiler\TextInterface;
  13. /**
  14. * Class Compiler
  15. */
  16. class Compiler implements CompilerInterface
  17. {
  18. /**
  19. * @var TextInterface
  20. */
  21. protected $compilerText;
  22. /**
  23. * @var AttributeInterface
  24. */
  25. protected $compilerAttribute;
  26. /**
  27. * @var CdataInterface
  28. */
  29. protected $compilerCdata;
  30. /**
  31. * @var CommentInterface
  32. */
  33. protected $compilerComment;
  34. /**
  35. * @var ElementInterface[]
  36. */
  37. protected $elementCompilers;
  38. /**
  39. * Postprocessing data
  40. *
  41. * @var array
  42. */
  43. protected $data;
  44. /**
  45. * Constructor
  46. *
  47. * @param TextInterface $compilerText
  48. * @param AttributeInterface $compilerAttribute
  49. * @param AttributeInterface|CdataInterface $compilerCdata
  50. * @param CommentInterface $compilerComment
  51. * @param ElementInterface[] $elementCompilers
  52. */
  53. public function __construct(
  54. TextInterface $compilerText,
  55. AttributeInterface $compilerAttribute,
  56. CdataInterface $compilerCdata,
  57. CommentInterface $compilerComment,
  58. array $elementCompilers
  59. ) {
  60. $this->compilerText = $compilerText;
  61. $this->compilerAttribute = $compilerAttribute;
  62. $this->compilerCdata = $compilerCdata;
  63. $this->compilerComment = $compilerComment;
  64. $this->elementCompilers = $elementCompilers;
  65. }
  66. /**
  67. * The compilation of the template and filling in the data
  68. *
  69. * @param \DOMNode $node
  70. * @param DataObject $processedObject
  71. * @param DataObject $context
  72. * @return void
  73. */
  74. public function compile(\DOMNode $node, DataObject $processedObject, DataObject $context)
  75. {
  76. switch ($node->nodeType) {
  77. case XML_TEXT_NODE:
  78. $this->compilerText->compile($node, $processedObject);
  79. break;
  80. case XML_CDATA_SECTION_NODE:
  81. $this->compilerCdata->compile($node, $processedObject);
  82. break;
  83. case XML_COMMENT_NODE:
  84. $this->compilerComment->compile($node, $processedObject);
  85. break;
  86. default:
  87. /** @var \DomElement $node */
  88. if ($node->hasAttributes()) {
  89. foreach ($node->attributes as $attribute) {
  90. $this->compilerAttribute->compile($attribute, $processedObject);
  91. }
  92. }
  93. $compiler = $this->getElementCompiler($node->nodeName);
  94. if (null !== $compiler) {
  95. $compiler->compile($this, $node, $processedObject, $context);
  96. } elseif ($node->hasChildNodes()) {
  97. foreach ($this->getChildNodes($node) as $child) {
  98. $this->compile($child, $processedObject, $context);
  99. }
  100. }
  101. }
  102. }
  103. /**
  104. * Run postprocessing contents
  105. *
  106. * @param string $content
  107. * @return string
  108. */
  109. public function postprocessing($content)
  110. {
  111. $patternTag = preg_quote(CompilerInterface::PATTERN_TAG);
  112. return preg_replace_callback(
  113. '#' . $patternTag . '(.+?)' . $patternTag . '#',
  114. function ($match) {
  115. return $this->data[$match[1]] ?? '';
  116. },
  117. $content
  118. );
  119. }
  120. /**
  121. * Set postprocessing data
  122. *
  123. * @param string $key
  124. * @param string $content
  125. * @return void
  126. */
  127. public function setPostprocessingData($key, $content)
  128. {
  129. $this->data[$key] = $content;
  130. }
  131. /**
  132. * Get child nodes
  133. *
  134. * @param \DOMElement $node
  135. * @return \DOMElement[]
  136. */
  137. protected function getChildNodes(\DOMElement $node)
  138. {
  139. $childNodes = [];
  140. foreach ($node->childNodes as $child) {
  141. $childNodes[] = $child;
  142. }
  143. return $childNodes;
  144. }
  145. /**
  146. * Get element compiler by name
  147. *
  148. * @param string $name
  149. * @return ElementInterface
  150. */
  151. protected function getElementCompiler($name)
  152. {
  153. if (isset($this->elementCompilers[$name])) {
  154. return $this->elementCompilers[$name];
  155. }
  156. return null;
  157. }
  158. }