ConvertArray.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Convert;
  7. use Magento\Framework\Exception\LocalizedException;
  8. /**
  9. * Convert the array data to SimpleXMLElement object
  10. */
  11. class ConvertArray
  12. {
  13. /**
  14. * Transform an assoc array to \SimpleXMLElement object
  15. * Array has some limitations. Appropriate exceptions will be thrown
  16. *
  17. * @param array $array
  18. * @param string $rootName
  19. * @return \SimpleXMLElement
  20. * @throws LocalizedException
  21. */
  22. public function assocToXml(array $array, $rootName = '_')
  23. {
  24. if (empty($rootName) || is_numeric($rootName)) {
  25. throw new LocalizedException(
  26. new \Magento\Framework\Phrase(
  27. "The root element can't be empty or use numbers. Change the element and try again."
  28. )
  29. );
  30. }
  31. $xmlStr = <<<XML
  32. <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
  33. <$rootName></$rootName>
  34. XML;
  35. $xml = new \SimpleXMLElement($xmlStr);
  36. foreach (array_keys($array) as $key) {
  37. if (is_numeric($key)) {
  38. throw new LocalizedException(
  39. new \Magento\Framework\Phrase('An error occurred. Use non-numeric array root keys and try again.')
  40. );
  41. }
  42. }
  43. return self::_assocToXml($array, $rootName, $xml);
  44. }
  45. /**
  46. * Convert nested array into flat array.
  47. *
  48. * @param array $data
  49. * @return array
  50. */
  51. public static function toFlatArray($data)
  52. {
  53. foreach ($data as $key => $value) {
  54. if (is_array($value)) {
  55. $value = self::toFlatArray($value);
  56. unset($data[$key]);
  57. $data = array_merge($data, $value);
  58. }
  59. }
  60. return $data;
  61. }
  62. /**
  63. * Function, that actually recursively transforms array to xml
  64. *
  65. * @param array $array
  66. * @param string $rootName
  67. * @param \SimpleXMLElement $xml
  68. * @return \SimpleXMLElement
  69. * @throws LocalizedException
  70. */
  71. private function _assocToXml(array $array, $rootName, \SimpleXMLElement $xml)
  72. {
  73. $hasNumericKey = false;
  74. $hasStringKey = false;
  75. foreach ($array as $key => $value) {
  76. if (!is_array($value)) {
  77. if (is_string($key)) {
  78. if ($key === $rootName) {
  79. throw new LocalizedException(
  80. new \Magento\Framework\Phrase(
  81. "An associative key can't be the same as its parent associative key. "
  82. . "Verify and try again."
  83. )
  84. );
  85. }
  86. $hasStringKey = true;
  87. $xml->addChild($key, $value);
  88. } elseif (is_int($key)) {
  89. $hasNumericKey = true;
  90. $xml->addChild($key, $value);
  91. }
  92. } else {
  93. $xml->addChild($key);
  94. self::_assocToXml($value, $key, $xml->{$key});
  95. }
  96. }
  97. if ($hasNumericKey && $hasStringKey) {
  98. throw new LocalizedException(
  99. new \Magento\Framework\Phrase(
  100. "Associative and numeric keys can't be mixed at one level. Verify and try again."
  101. )
  102. );
  103. }
  104. return $xml;
  105. }
  106. }