Converter.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Widget\Model\Config;
  7. class Converter implements \Magento\Framework\Config\ConverterInterface
  8. {
  9. /**
  10. * {@inheritdoc}
  11. * @SuppressWarnings(PHPMD.NPathComplexity)
  12. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  13. */
  14. public function convert($source)
  15. {
  16. $widgets = [];
  17. $xpath = new \DOMXPath($source);
  18. /** @var $widget \DOMNode */
  19. foreach ($xpath->query('/widgets/widget') as $widget) {
  20. $widgetAttributes = $widget->attributes;
  21. $widgetArray = ['@' => []];
  22. $widgetArray['@']['type'] = $widgetAttributes->getNamedItem('class')->nodeValue;
  23. $isEmailCompatible = $widgetAttributes->getNamedItem('is_email_compatible');
  24. if ($isEmailCompatible !== null) {
  25. $widgetArray['is_email_compatible'] = $isEmailCompatible->nodeValue == 'true' ? '1' : '0';
  26. }
  27. $placeholderImage = $widgetAttributes->getNamedItem('placeholder_image');
  28. if ($placeholderImage !== null) {
  29. $widgetArray['placeholder_image'] = $placeholderImage->nodeValue;
  30. }
  31. $widgetId = $widgetAttributes->getNamedItem('id');
  32. /** @var $widgetSubNode \DOMNode */
  33. foreach ($widget->childNodes as $widgetSubNode) {
  34. switch ($widgetSubNode->nodeName) {
  35. case 'label':
  36. $widgetArray['name'] = $widgetSubNode->nodeValue;
  37. break;
  38. case 'description':
  39. $widgetArray['description'] = $widgetSubNode->nodeValue;
  40. break;
  41. case 'parameters':
  42. /** @var $parameter \DOMNode */
  43. foreach ($widgetSubNode->childNodes as $parameter) {
  44. if ($parameter->nodeName === '#text' || $parameter->nodeName === '#comment') {
  45. continue;
  46. }
  47. $subNodeAttributes = $parameter->attributes;
  48. $parameterName = $subNodeAttributes->getNamedItem('name')->nodeValue;
  49. $widgetArray['parameters'][$parameterName] = $this->_convertParameter($parameter);
  50. }
  51. break;
  52. case 'containers':
  53. if (!isset($widgetArray['supported_containers'])) {
  54. $widgetArray['supported_containers'] = [];
  55. }
  56. foreach ($widgetSubNode->childNodes as $container) {
  57. if ($container->nodeName === '#text' || $container->nodeName === '#comment') {
  58. continue;
  59. }
  60. $widgetArray['supported_containers'] = array_merge(
  61. $widgetArray['supported_containers'],
  62. $this->_convertContainer($container)
  63. );
  64. }
  65. break;
  66. case "#text":
  67. break;
  68. case '#comment':
  69. break;
  70. default:
  71. throw new \LogicException(
  72. sprintf(
  73. "Unsupported child xml node '%s' found in the 'widget' node",
  74. $widgetSubNode->nodeName
  75. )
  76. );
  77. }
  78. }
  79. $widgets[$widgetId->nodeValue] = $widgetArray;
  80. }
  81. return $widgets;
  82. }
  83. /**
  84. * Convert dom Container node to Magento array
  85. *
  86. * @param \DOMNode $source
  87. * @return array
  88. * @throws \LogicException
  89. */
  90. protected function _convertContainer($source)
  91. {
  92. $supportedContainers = [];
  93. $containerAttributes = $source->attributes;
  94. $template = [];
  95. foreach ($source->childNodes as $containerTemplate) {
  96. if (!$containerTemplate instanceof \DOMElement) {
  97. continue;
  98. }
  99. if ($containerTemplate->nodeName !== 'template') {
  100. throw new \LogicException("Only 'template' node can be child of 'container' node");
  101. }
  102. $templateAttributes = $containerTemplate->attributes;
  103. $template[$templateAttributes->getNamedItem(
  104. 'name'
  105. )->nodeValue] = $templateAttributes->getNamedItem(
  106. 'value'
  107. )->nodeValue;
  108. }
  109. $supportedContainers[] = [
  110. 'container_name' => $containerAttributes->getNamedItem('name')->nodeValue,
  111. 'template' => $template,
  112. ];
  113. return $supportedContainers;
  114. }
  115. /**
  116. * Convert dom Parameter node to Magento array
  117. *
  118. * @param \DOMNode $source
  119. * @return array
  120. * @throws \LogicException
  121. * @SuppressWarnings(PHPMD.NPathComplexity)
  122. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  123. */
  124. protected function _convertParameter($source)
  125. {
  126. $parameter = [];
  127. $sourceAttributes = $source->attributes;
  128. $xsiType = $sourceAttributes->getNamedItem('type')->nodeValue;
  129. if ($xsiType == 'block') {
  130. $parameter['type'] = 'label';
  131. $parameter['@'] = [];
  132. $parameter['@']['type'] = 'complex';
  133. foreach ($source->childNodes as $blockSubNode) {
  134. if ($blockSubNode->nodeName == 'block') {
  135. $parameter['helper_block'] = $this->_convertBlock($blockSubNode);
  136. break;
  137. }
  138. }
  139. } elseif ($xsiType == 'select' || $xsiType == 'multiselect') {
  140. $sourceModel = $sourceAttributes->getNamedItem('source_model');
  141. if ($sourceModel !== null) {
  142. $parameter['source_model'] = $sourceModel->nodeValue;
  143. }
  144. $parameter['type'] = $xsiType;
  145. /** @var $paramSubNode \DOMNode */
  146. foreach ($source->childNodes as $paramSubNode) {
  147. if ($paramSubNode->nodeName == 'options') {
  148. /** @var $option \DOMNode */
  149. foreach ($paramSubNode->childNodes as $option) {
  150. if ($option->nodeName === '#text') {
  151. continue;
  152. }
  153. $optionAttributes = $option->attributes;
  154. $optionName = $optionAttributes->getNamedItem('name')->nodeValue;
  155. $selected = $optionAttributes->getNamedItem('selected');
  156. if ($selected !== null) {
  157. $parameter['value'] = $optionAttributes->getNamedItem('value')->nodeValue;
  158. }
  159. if (!isset($parameter['values'])) {
  160. $parameter['values'] = [];
  161. }
  162. $parameter['values'][$optionName] = $this->_convertOption($option);
  163. }
  164. }
  165. }
  166. } elseif ($xsiType == 'text') {
  167. $parameter['type'] = $xsiType;
  168. foreach ($source->childNodes as $textSubNode) {
  169. if ($textSubNode->nodeName == 'value') {
  170. $parameter['value'] = $textSubNode->nodeValue;
  171. }
  172. }
  173. } elseif ($xsiType == 'conditions') {
  174. $parameter['type'] = $sourceAttributes->getNamedItem('class')->nodeValue;
  175. } else {
  176. $parameter['type'] = $xsiType;
  177. }
  178. $visible = $sourceAttributes->getNamedItem('visible');
  179. if ($visible) {
  180. $parameter['visible'] = $visible->nodeValue == 'true' ? '1' : '0';
  181. } else {
  182. $parameter['visible'] = true;
  183. }
  184. $required = $sourceAttributes->getNamedItem('required');
  185. if ($required) {
  186. $parameter['required'] = $required->nodeValue == 'false' ? '0' : '1';
  187. }
  188. $sortOrder = $sourceAttributes->getNamedItem('sort_order');
  189. if ($sortOrder) {
  190. $parameter['sort_order'] = $sortOrder->nodeValue;
  191. }
  192. foreach ($source->childNodes as $paramSubNode) {
  193. switch ($paramSubNode->nodeName) {
  194. case 'label':
  195. $parameter['label'] = $paramSubNode->nodeValue;
  196. break;
  197. case 'description':
  198. $parameter['description'] = $paramSubNode->nodeValue;
  199. break;
  200. case 'depends':
  201. $parameter['depends'] = $this->_convertDepends($paramSubNode);
  202. break;
  203. }
  204. }
  205. return $parameter;
  206. }
  207. /**
  208. * Convert dom Depends node to Magento array
  209. *
  210. * @param \DOMNode $source
  211. * @return array
  212. * @throws \LogicException
  213. */
  214. protected function _convertDepends($source)
  215. {
  216. $depends = [];
  217. foreach ($source->childNodes as $childNode) {
  218. if ($childNode->nodeName === '#text') {
  219. continue;
  220. }
  221. if ($childNode->nodeName !== 'parameter') {
  222. throw new \LogicException(
  223. sprintf("Only 'parameter' node can be child of 'depends' node, %s found", $childNode->nodeName)
  224. );
  225. }
  226. $parameterAttributes = $childNode->attributes;
  227. $dependencyName = $parameterAttributes->getNamedItem('name')->nodeValue;
  228. $dependencyValue = $parameterAttributes->getNamedItem('value')->nodeValue;
  229. if (!isset($depends[$dependencyName])) {
  230. $depends[$dependencyName] = [
  231. 'value' => $dependencyValue,
  232. ];
  233. continue;
  234. } else if (!isset($depends[$dependencyName]['values'])) {
  235. $depends[$dependencyName]['values'] = [$depends[$dependencyName]['value']];
  236. unset($depends[$dependencyName]['value']);
  237. }
  238. $depends[$dependencyName]['values'][] = $dependencyValue;
  239. }
  240. return $depends;
  241. }
  242. /**
  243. * Convert dom Renderer node to Magento array
  244. *
  245. * @param \DOMNode $source
  246. * @return array
  247. * @throws \LogicException
  248. */
  249. protected function _convertBlock($source)
  250. {
  251. $helperBlock = [];
  252. $helperBlock['type'] = $source->attributes->getNamedItem('class')->nodeValue;
  253. foreach ($source->childNodes as $blockSubNode) {
  254. if ($blockSubNode->nodeName == '#text') {
  255. continue;
  256. }
  257. if ($blockSubNode->nodeName !== 'data') {
  258. throw new \LogicException(
  259. sprintf("Only 'data' node can be child of 'block' node, %s found", $blockSubNode->nodeName)
  260. );
  261. }
  262. $helperBlock['data'] = $this->_convertData($blockSubNode);
  263. }
  264. return $helperBlock;
  265. }
  266. /**
  267. * Convert dom Data node to Magento array
  268. *
  269. * @param \DOMElement $source
  270. * @return array
  271. */
  272. protected function _convertData($source)
  273. {
  274. $data = [];
  275. if (!$source->hasChildNodes()) {
  276. return $data;
  277. }
  278. foreach ($source->childNodes as $dataChild) {
  279. if ($dataChild instanceof \DOMElement) {
  280. $data[$dataChild->attributes->getNamedItem('name')->nodeValue] = $this->_convertData($dataChild);
  281. } else {
  282. if (strlen(trim($dataChild->nodeValue))) {
  283. $data = $dataChild->nodeValue;
  284. }
  285. }
  286. }
  287. return $data;
  288. }
  289. /**
  290. * Convert dom Option node to Magento array
  291. *
  292. * @param \DOMNode $source
  293. * @return array
  294. * @throws \LogicException
  295. */
  296. protected function _convertOption($source)
  297. {
  298. $option = [];
  299. $optionAttributes = $source->attributes;
  300. $option['value'] = $optionAttributes->getNamedItem('value')->nodeValue;
  301. foreach ($source->childNodes as $childNode) {
  302. if ($childNode->nodeName == '#text') {
  303. continue;
  304. }
  305. if ($childNode->nodeName !== 'label') {
  306. throw new \LogicException("Only 'label' node can be child of 'option' node");
  307. }
  308. $option['label'] = $childNode->nodeValue;
  309. }
  310. return $option;
  311. }
  312. }