Generator.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Xml;
  7. class Generator
  8. {
  9. /**
  10. * This value is used to replace numeric keys while formatting data for xml output.
  11. */
  12. const DEFAULT_ENTITY_ITEM_NAME = 'item';
  13. /**
  14. * @var \DOMDocument|null
  15. */
  16. protected $_dom = null;
  17. /**
  18. * @var \DOMDocument
  19. */
  20. protected $_currentDom;
  21. /**
  22. * @var string
  23. */
  24. protected $_defaultIndexedArrayItemName;
  25. /**
  26. *
  27. */
  28. public function __construct()
  29. {
  30. $this->_dom = new \DOMDocument('1.0');
  31. $this->_dom->formatOutput = true;
  32. $this->_currentDom = $this->_dom;
  33. return $this;
  34. }
  35. /**
  36. * @return \DOMDocument|null
  37. */
  38. public function getDom()
  39. {
  40. return $this->_dom;
  41. }
  42. /**
  43. * @return \DOMDocument
  44. */
  45. protected function _getCurrentDom()
  46. {
  47. return $this->_currentDom;
  48. }
  49. /**
  50. * @param \DOMDocument $node
  51. * @return $this
  52. */
  53. protected function _setCurrentDom($node)
  54. {
  55. $this->_currentDom = $node;
  56. return $this;
  57. }
  58. /**
  59. * @param array $content
  60. * @return $this
  61. * @throws \DOMException
  62. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  63. */
  64. public function arrayToXml($content)
  65. {
  66. $parentNode = $this->_getCurrentDom();
  67. if (!$content || !count($content)) {
  68. return $this;
  69. }
  70. foreach ($content as $_key => $_item) {
  71. $node = $this->getDom()->createElement(preg_replace('/[^\w-]/i', '', $_key));
  72. $parentNode->appendChild($node);
  73. if (is_array($_item) && isset($_item['_attribute'])) {
  74. if (is_array($_item['_value'])) {
  75. if (isset($_item['_value'][0])) {
  76. foreach ($_item['_value'] as $_v) {
  77. $this->_setCurrentDom($node)->arrayToXml($_v);
  78. }
  79. } else {
  80. $this->_setCurrentDom($node)->arrayToXml($_item['_value']);
  81. }
  82. } else {
  83. $child = $this->getDom()->createTextNode($_item['_value']);
  84. $node->appendChild($child);
  85. }
  86. foreach ($_item['_attribute'] as $_attributeKey => $_attributeValue) {
  87. $node->setAttribute($_attributeKey, $_attributeValue);
  88. }
  89. } elseif (is_string($_item)) {
  90. $text = $this->getDom()->createTextNode($_item);
  91. $node->appendChild($text);
  92. } elseif (is_array($_item) && !isset($_item[0])) {
  93. $this->_setCurrentDom($node)->arrayToXml($_item);
  94. } elseif (is_array($_item) && isset($_item[0])) {
  95. foreach ($_item as $v) {
  96. $this->_setCurrentDom($node)->arrayToXml([$this->_getIndexedArrayItemName() => $v]);
  97. }
  98. }
  99. }
  100. return $this;
  101. }
  102. /**
  103. * @return string
  104. */
  105. public function __toString()
  106. {
  107. return $this->getDom()->saveXML();
  108. }
  109. /**
  110. * @param string $file
  111. * @return $this
  112. */
  113. public function save($file)
  114. {
  115. $this->getDom()->save($file);
  116. return $this;
  117. }
  118. /**
  119. * Set xml node name to use instead of numeric index during numeric arrays conversion.
  120. *
  121. * @param string $name
  122. * @return $this
  123. */
  124. public function setIndexedArrayItemName($name)
  125. {
  126. $this->_defaultIndexedArrayItemName = $name;
  127. return $this;
  128. }
  129. /**
  130. * Get xml node name to use instead of numeric index during numeric arrays conversion.
  131. *
  132. * @return string
  133. */
  134. protected function _getIndexedArrayItemName()
  135. {
  136. return $this->_defaultIndexedArrayItemName ?? self::DEFAULT_ENTITY_ITEM_NAME;
  137. }
  138. }