XmlResponseFormatter.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\web;
  8. use DOMDocument;
  9. use DOMElement;
  10. use DOMText;
  11. use yii\base\Arrayable;
  12. use yii\base\Component;
  13. use yii\helpers\StringHelper;
  14. /**
  15. * XmlResponseFormatter formats the given data into an XML response content.
  16. *
  17. * It is used by [[Response]] to format response data.
  18. *
  19. * @author Qiang Xue <[email protected]>
  20. * @since 2.0
  21. */
  22. class XmlResponseFormatter extends Component implements ResponseFormatterInterface
  23. {
  24. /**
  25. * @var string the Content-Type header for the response
  26. */
  27. public $contentType = 'application/xml';
  28. /**
  29. * @var string the XML version
  30. */
  31. public $version = '1.0';
  32. /**
  33. * @var string the XML encoding. If not set, it will use the value of [[Response::charset]].
  34. */
  35. public $encoding;
  36. /**
  37. * @var string the name of the root element.
  38. */
  39. public $rootTag = 'response';
  40. /**
  41. * @var string the name of the elements that represent the array elements with numeric keys.
  42. */
  43. public $itemTag = 'item';
  44. /**
  45. * Formats the specified response.
  46. * @param Response $response the response to be formatted.
  47. */
  48. public function format($response)
  49. {
  50. $response->getHeaders()->set('Content-Type', $this->contentType);
  51. $dom = new DOMDocument($this->version, $this->encoding === null ? $response->charset : $this->encoding);
  52. $root = new DOMElement($this->rootTag);
  53. $dom->appendChild($root);
  54. $this->buildXml($root, $response->data);
  55. $response->content = $dom->saveXML();
  56. }
  57. /**
  58. * @param DOMElement $element
  59. * @param mixed $data
  60. */
  61. protected function buildXml($element, $data)
  62. {
  63. if (is_object($data)) {
  64. $child = new DOMElement(StringHelper::basename(get_class($data)));
  65. $element->appendChild($child);
  66. if ($data instanceof Arrayable) {
  67. $this->buildXml($child, $data->toArray());
  68. } else {
  69. $array = [];
  70. foreach ($data as $name => $value) {
  71. $array[$name] = $value;
  72. }
  73. $this->buildXml($child, $array);
  74. }
  75. } elseif (is_array($data)) {
  76. foreach ($data as $name => $value) {
  77. if (is_int($name) && is_object($value)) {
  78. $this->buildXml($element, $value);
  79. } elseif (is_array($value) || is_object($value)) {
  80. $child = new DOMElement(is_int($name) ? $this->itemTag : $name);
  81. $element->appendChild($child);
  82. $this->buildXml($child, $value);
  83. } else {
  84. $child = new DOMElement(is_int($name) ? $this->itemTag : $name);
  85. $element->appendChild($child);
  86. $child->appendChild(new DOMText((string)$value));
  87. }
  88. }
  89. } else {
  90. $element->appendChild(new DOMText((string)$data));
  91. }
  92. }
  93. }