Converter.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Ui\Config\Reader\DefinitionMap;
  7. use Magento\Framework\Config\ConverterInterface;
  8. use Magento\Framework\View\Layout\Argument\Parser;
  9. /**
  10. * Converter for definition.map.xml
  11. */
  12. class Converter implements ConverterInterface
  13. {
  14. /**
  15. * The key of the argument node
  16. */
  17. const ARGUMENT_KEY = 'argument';
  18. /**
  19. * The key of the include component
  20. */
  21. const INCLUDE_KEY = 'include';
  22. /**
  23. * The array key sub components
  24. */
  25. const CURRENT_SCHEMA_KEY = 'current';
  26. /**
  27. * Key name attribute value
  28. */
  29. const NAME_ATTRIBUTE_KEY = 'name';
  30. /**
  31. * @var Parser
  32. */
  33. private $argumentParser;
  34. /**
  35. * Converter constructor.
  36. *
  37. * @param Parser $argumentParser
  38. */
  39. public function __construct(Parser $argumentParser)
  40. {
  41. $this->argumentParser = $argumentParser;
  42. }
  43. /**
  44. * Transform Xml to array
  45. *
  46. * @param \DOMNode $node
  47. * @return array|string
  48. */
  49. private function toArray(\DOMNode $node)
  50. {
  51. $result = [];
  52. $attributes = [];
  53. // Collect data from attributes
  54. if ($node->hasAttributes()) {
  55. foreach ($node->attributes as $attribute) {
  56. $attributes[$attribute->name] = $attribute->value;
  57. }
  58. }
  59. if (isset($attributes[static::INCLUDE_KEY])) {
  60. $result[static::INCLUDE_KEY] = $attributes[static::INCLUDE_KEY];
  61. unset($attributes[static::INCLUDE_KEY]);
  62. }
  63. switch ($node->nodeType) {
  64. case XML_TEXT_NODE:
  65. case XML_COMMENT_NODE:
  66. case XML_CDATA_SECTION_NODE:
  67. break;
  68. default:
  69. if ($node->localName === static::ARGUMENT_KEY) {
  70. if (!isset($attributes[static::NAME_ATTRIBUTE_KEY])) {
  71. throw new \InvalidArgumentException(
  72. 'Attribute "' . static::NAME_ATTRIBUTE_KEY . '" is absent in the attributes node.'
  73. );
  74. }
  75. $result[ $attributes[static::NAME_ATTRIBUTE_KEY] ] = $this->argumentParser->parse($node);
  76. } else {
  77. list($arguments, $childResult) = $this->convertChildNodes($node);
  78. $result += $this->processArguments($arguments);
  79. $result += $childResult;
  80. }
  81. break;
  82. }
  83. return $result;
  84. }
  85. /**
  86. * Retrieve component name
  87. *
  88. * @param \DOMNode $node
  89. * @return string
  90. */
  91. private function getComponentName(\DOMNode $node)
  92. {
  93. $result = $node->localName;
  94. if (!$node->hasAttributes()) {
  95. return $result;
  96. }
  97. foreach ($node->attributes as $attribute) {
  98. if ($attribute->name == static::NAME_ATTRIBUTE_KEY) {
  99. $result = $attribute->value;
  100. break;
  101. }
  102. }
  103. return $result;
  104. }
  105. /**
  106. * Convert configuration
  107. *
  108. * @param \DOMDocument|null $source
  109. * @return array
  110. */
  111. public function convert($source)
  112. {
  113. if ($source === null) {
  114. return [];
  115. }
  116. $result = $this->toArray($source);
  117. $result = empty($result) ? $result : reset($result);
  118. $schemaMap = [];
  119. foreach ($result as $componentName => $componentData) {
  120. $schemaMap[$componentName] = $this->processMap($componentData, $result);
  121. }
  122. return $schemaMap;
  123. }
  124. /**
  125. * Process include directives and return current schema
  126. *
  127. * @param array $componentData
  128. * @param array $sourceMap
  129. * @return array
  130. */
  131. private function processMap($componentData, $sourceMap)
  132. {
  133. $result = [];
  134. if (isset($componentData[static::INCLUDE_KEY])) {
  135. if (isset($sourceMap[$componentData[static::INCLUDE_KEY]])) {
  136. $result = array_replace_recursive(
  137. $this->processMap($sourceMap[$componentData[static::INCLUDE_KEY]], $sourceMap),
  138. $result
  139. );
  140. }
  141. }
  142. if (isset($componentData[static::CURRENT_SCHEMA_KEY])) {
  143. $result = array_replace_recursive($componentData[static::CURRENT_SCHEMA_KEY], $result);
  144. }
  145. return $result;
  146. }
  147. /**
  148. * Convert child nodes of $node
  149. *
  150. * @param \DOMNode $node
  151. * @return array
  152. */
  153. private function convertChildNodes(\DOMNode $node)
  154. {
  155. $arguments = [];
  156. $childResult = [];
  157. foreach ($node->childNodes as $itemNode) {
  158. if (empty($itemNode->localName)) {
  159. continue;
  160. }
  161. if ($itemNode->localName === static::ARGUMENT_KEY) {
  162. $arguments += $this->toArray($itemNode);
  163. } else {
  164. $childResult[$this->getComponentName($itemNode)] = $this->toArray($itemNode);
  165. }
  166. }
  167. return [$arguments, $childResult];
  168. }
  169. /**
  170. * Process component arguments
  171. *
  172. * @param array $arguments
  173. * @return array
  174. */
  175. private function processArguments(array $arguments)
  176. {
  177. $result = [];
  178. if (!empty($arguments)) {
  179. $result[static::ARGUMENT_KEY] = $arguments;
  180. }
  181. return $result;
  182. }
  183. }