Completed
Push — fix-numbervalidator-comma-deci... ( cad400...eee7b9 )
by Alexander
61:03 queued 21:06
created

XmlResponseFormatter::buildXml()   C

Complexity

Conditions 16
Paths 11

Size

Total Lines 38
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 16

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 38
ccs 26
cts 26
cp 1
rs 5.0151
c 1
b 0
f 0
cc 16
eloc 29
nc 11
nop 2
crap 16

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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. If set to false, null or is empty then no root tag should be added.
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
     * @var bool if object tags should be added
55
     * @since 2.0.11
56
     */
57
    public $useObjectTags = true;
58
59 16
    /**
60
     * Formats the specified response.
61 16
     * @param Response $response the response to be formatted.
62 16
     */
63 16
    public function format($response)
64 16
    {
65 16
        $charset = $this->encoding === null ? $response->charset : $this->encoding;
66 16
        if (stripos($this->contentType, 'charset') === false) {
67 15
            $this->contentType .= '; charset=' . $charset;
68 15
        }
69 15
        $response->getHeaders()->set('Content-Type', $this->contentType);
70 15
        if ($response->data !== null) {
71 15
            $dom = new DOMDocument($this->version, $charset);
72 15
            if (!empty($this->rootTag)) {
73 16
                $root = new DOMElement($this->rootTag);
74
                $dom->appendChild($root);
75
                $this->buildXml($root, $response->data);
76
            } else {
77
                $this->buildXml($dom, $response->data);
0 ignored issues
show
Documentation introduced by
$dom is of type object<DOMDocument>, but the function expects a object<DOMElement>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
78
            }
79 15
            $response->content = $dom->saveXML();
80
        }
81 15
    }
82 10
83 15
    /**
84 10
     * @param DOMElement $element
85 9
     * @param mixed $data
86 3
     */
87 9
    protected function buildXml($element, $data)
88 3
    {
89 3
        if (is_array($data) ||
90 3
            ($data instanceof \Traversable && $this->useTraversableAsArray && !$data instanceof Arrayable)
91 3
        ) {
92 9
            foreach ($data as $name => $value) {
93 9
                if (is_int($name) && is_object($value)) {
94 9
                    $this->buildXml($element, $value);
95
                } elseif (is_array($value) || is_object($value)) {
96 10
                    $child = new DOMElement(is_int($name) ? $this->itemTag : $name);
97 15
                    $element->appendChild($child);
98 5
                    $this->buildXml($child, $value);
99 5
                } else {
100 5
                    $child = new DOMElement(is_int($name) ? $this->itemTag : $name);
101 1
                    $element->appendChild($child);
102 1
                    $child->appendChild(new DOMText($this->formatScalarValue($value)));
103 4
                }
104 4
            }
105 4
        } elseif (is_object($data)) {
106 4
            if ($this->useObjectTags) {
107 4
                $child = new DOMElement(StringHelper::basename(get_class($data)));
108
                $element->appendChild($child);    
109 5
            } else {
110 5
                $child = $element;
111
            }
112 15
            if ($data instanceof Arrayable) {
113
                $this->buildXml($child, $data->toArray());
114
            } else {
115
                $array = [];
116
                foreach ($data as $name => $value) {
117
                    $array[$name] = $value;
118
                }
119
                $this->buildXml($child, $array);
120
            }
121 14
        } else {
122
            $element->appendChild(new DOMText($this->formatScalarValue($data)));
123 14
        }
124 2
    }
125
126
    /**
127 13
     * Formats scalar value to use in XML text node
128 2
     *
129
     * @param int|string|bool $value
130
     * @return string
131 12
     * @since 2.0.11
132
     */
133
    protected function formatScalarValue($value)
134
    {
135
        if ($value === true) {
136
            return 'true';
137
        }
138
139
        if ($value === false) {
140
            return 'false';
141
        }
142
143
        return (string) $value;
144
    }
145
}
146