/vendor/magento/framework/Webapi/Rest/Response/Renderer/Xml.php

https://gitlab.com/yousafsyed/easternglamor · PHP · 166 lines · 97 code · 11 blank · 58 comment · 9 complexity · 0161f80eaadf0f3865449d8ea73cfd25 MD5 · raw file

  1. <?php
  2. /**
  3. * XML Renderer allows to format array or object as valid XML document.
  4. *
  5. * Copyright © 2016 Magento. All rights reserved.
  6. * See COPYING.txt for license details.
  7. */
  8. namespace Magento\Framework\Webapi\Rest\Response\Renderer;
  9. class Xml implements \Magento\Framework\Webapi\Rest\Response\RendererInterface
  10. {
  11. /**
  12. * Renderer mime type.
  13. */
  14. const MIME_TYPE = 'application/xml';
  15. /**
  16. * Root node in XML output.
  17. */
  18. const XML_ROOT_NODE = 'response';
  19. /**
  20. * This value is used to replace numeric keys while formatting data for XML output.
  21. */
  22. const DEFAULT_ENTITY_ITEM_NAME = 'item';
  23. /** @var \Magento\Framework\Xml\Generator */
  24. protected $_xmlGenerator;
  25. /**
  26. * Initialize dependencies.
  27. *
  28. * @param \Magento\Framework\Xml\Generator $xmlGenerator
  29. */
  30. public function __construct(\Magento\Framework\Xml\Generator $xmlGenerator)
  31. {
  32. $this->_xmlGenerator = $xmlGenerator;
  33. }
  34. /**
  35. * Get XML renderer MIME type.
  36. *
  37. * @return string
  38. */
  39. public function getMimeType()
  40. {
  41. return self::MIME_TYPE;
  42. }
  43. /**
  44. * Format object|array to valid XML.
  45. *
  46. * @param object|array|int|string|bool|float|null $data
  47. * @return string
  48. */
  49. public function render($data)
  50. {
  51. $formattedData = $this->_formatData($data, true);
  52. /** Wrap response in a single node. */
  53. $formattedData = [self::XML_ROOT_NODE => $formattedData];
  54. $this->_xmlGenerator->setIndexedArrayItemName(self::DEFAULT_ENTITY_ITEM_NAME)->arrayToXml($formattedData);
  55. return $this->_xmlGenerator->getDom()->saveXML();
  56. }
  57. /**
  58. * Reformat mixed data to multidimensional array.
  59. *
  60. * This method is recursive.
  61. *
  62. * @param array|\Magento\Framework\DataObject $data
  63. * @param bool $isRoot
  64. * @return array
  65. * @throws \InvalidArgumentException
  66. */
  67. protected function _formatData($data, $isRoot = false)
  68. {
  69. if (!is_array($data) && !is_object($data)) {
  70. if ($isRoot) {
  71. return $this->_formatValue($data);
  72. }
  73. } elseif ($data instanceof \Magento\Framework\DataObject) {
  74. $data = $data->toArray();
  75. } else {
  76. $data = (array)$data;
  77. }
  78. $isAssoc = !preg_match('/^\d+$/', implode(array_keys($data), ''));
  79. $formattedData = [];
  80. foreach ($data as $key => $value) {
  81. $value = is_array($value) || is_object($value) ? $this->_formatData($value) : $this->_formatValue($value);
  82. if ($isAssoc) {
  83. $formattedData[$this->_prepareKey($key)] = $value;
  84. } else {
  85. $formattedData[] = $value;
  86. }
  87. }
  88. return $formattedData;
  89. }
  90. /**
  91. * Prepare value in contrast with key.
  92. *
  93. * @param string $value
  94. * @return string
  95. */
  96. protected function _formatValue($value)
  97. {
  98. if (is_bool($value)) {
  99. /** Without the following transformation boolean values are rendered incorrectly */
  100. $value = $value ? 'true' : 'false';
  101. }
  102. $replacementMap = ['&' => '&amp;'];
  103. return str_replace(array_keys($replacementMap), array_values($replacementMap), $value);
  104. }
  105. /**
  106. * Format array key or field name to be valid array key name.
  107. *
  108. * Replaces characters that are invalid in array key names.
  109. *
  110. * @param string $key
  111. * @return string
  112. */
  113. protected function _prepareKey($key)
  114. {
  115. $replacementMap = [
  116. '!' => '',
  117. '"' => '',
  118. '#' => '',
  119. '$' => '',
  120. '%' => '',
  121. '&' => '',
  122. '\'' => '',
  123. '(' => '',
  124. ')' => '',
  125. '*' => '',
  126. '+' => '',
  127. ',' => '',
  128. '/' => '',
  129. ';' => '',
  130. '<' => '',
  131. '=' => '',
  132. '>' => '',
  133. '?' => '',
  134. '@' => '',
  135. '[' => '',
  136. '\\' => '',
  137. ']' => '',
  138. '^' => '',
  139. '`' => '',
  140. '{' => '',
  141. '|' => '',
  142. '}' => '',
  143. '~' => '',
  144. ' ' => '_',
  145. ':' => '_',
  146. ];
  147. $key = str_replace(array_keys($replacementMap), array_values($replacementMap), $key);
  148. $key = trim($key, '_');
  149. $prohibitedTagPattern = '/^[0-9,.-]/';
  150. if (preg_match($prohibitedTagPattern, $key)) {
  151. $key = self::DEFAULT_ENTITY_ITEM_NAME . '_' . $key;
  152. }
  153. return $key;
  154. }
  155. }