Completed
Push — 2.1 ( 224aac...d335fd )
by Dmitry
54:21 queued 13:00
created

XmlResponseFormatter::formatScalarValue()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 0
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
crap 12
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
8
namespace yii\web;
9
10
use DOMDocument;
11
use DOMElement;
12
use DOMText;
13
use yii\base\Arrayable;
14
use yii\base\Component;
15
use yii\helpers\StringHelper;
16
17
/**
18
 * XmlResponseFormatter formats the given data into an XML response content.
19
 *
20
 * It is used by [[Response]] to format response data.
21
 *
22
 * @author Qiang Xue <[email protected]>
23
 * @since 2.0
24
 */
25
class XmlResponseFormatter extends Component implements ResponseFormatterInterface
26
{
27
    /**
28
     * @var string the Content-Type header for the response
29
     */
30
    public $contentType = 'application/xml';
31
    /**
32
     * @var string the XML version
33
     */
34
    public $version = '1.0';
35
    /**
36
     * @var string the XML encoding. If not set, it will use the value of [[Response::charset]].
37
     */
38
    public $encoding;
39
    /**
40
     * @var string the name of the root element.
41
     */
42
    public $rootTag = 'response';
43
    /**
44
     * @var string the name of the elements that represent the array elements with numeric keys.
45
     */
46
    public $itemTag = 'item';
47
    /**
48
     * @var bool whether to interpret objects implementing the [[\Traversable]] interface as arrays.
49
     * Defaults to `true`.
50
     * @since 2.0.7
51
     */
52
    public $useTraversableAsArray = true;
53
54
55
    /**
56
     * Formats the specified response.
57
     * @param Response $response the response to be formatted.
58
     */
59 15
    public function format($response)
60
    {
61 15
        $charset = $this->encoding === null ? $response->charset : $this->encoding;
62 15
        if (stripos($this->contentType, 'charset') === false) {
63 15
            $this->contentType .= '; charset=' . $charset;
64 15
        }
65 15
        $response->getHeaders()->set('Content-Type', $this->contentType);
66 15
        if ($response->data !== null) {
67 14
            $dom = new DOMDocument($this->version, $charset);
68 14
            $root = new DOMElement($this->rootTag);
69 14
            $dom->appendChild($root);
70 14
            $this->buildXml($root, $response->data);
71 14
            $response->content = $dom->saveXML();
72 14
        }
73 15
    }
74
75
    /**
76
     * @param DOMElement $element
77
     * @param mixed $data
78
     */
79 14
    protected function buildXml($element, $data)
80
    {
81 14
        if (is_array($data) ||
82 9
            ($data instanceof \Traversable && $this->useTraversableAsArray && !$data instanceof Arrayable)
83 14
        ) {
84 10
            foreach ($data as $name => $value) {
85 9
                if (is_int($name) && is_object($value)) {
86 3
                    $this->buildXml($element, $value);
87 9
                } elseif (is_array($value) || is_object($value)) {
88 3
                    $child = new DOMElement(is_int($name) ? $this->itemTag : $name);
89 3
                    $element->appendChild($child);
90 3
                    $this->buildXml($child, $value);
91 3
                } else {
92 9
                    $child = new DOMElement(is_int($name) ? $this->itemTag : $name);
93 9
                    $element->appendChild($child);
94 9
                    $child->appendChild(new DOMText($this->formatScalarValue($value)));
95
                }
96 10
            }
97 14
        } elseif (is_object($data)) {
98 5
            $child = new DOMElement(StringHelper::basename(get_class($data)));
99 5
            $element->appendChild($child);
100 5
            if ($data instanceof Arrayable) {
101 1
                $this->buildXml($child, $data->toArray());
102 1
            } else {
103 4
                $array = [];
104 4
                foreach ($data as $name => $value) {
105 4
                    $array[$name] = $value;
106 4
                }
107 4
                $this->buildXml($child, $array);
108
            }
109 5
        } else {
110 4
            $element->appendChild(new DOMText($this->formatScalarValue($data)));
111
        }
112 14
    }
113
114
    /**
115
     * Formats scalar value to use in XML text node
116
     *
117
     * @param int|string|bool $value
118
     * @return string
119
     * @since 2.0.11
120
     */
121
    protected function formatScalarValue($value)
122
    {
123
        if ($value === true) {
124
            return 'true';
125
        }
126
127
        if ($value === false) {
128
            return 'false';
129
        }
130
131
        return (string) $value;
132
    }
133
}
134