GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#9)
by
unknown
03:48
created

ArrayToXml::toDom()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Spatie\ArrayToXml;
4
5
use DOMElement;
6
use DOMDocument;
7
use DOMException;
8
9
class ArrayToXml
10
{
11
    /**
12
     * The root DOM Document.
13
     *
14
     * @var \DOMDocument
15
     */
16
    protected $document;
17
18
    /**
19
     * Set to enable replacing space with underscore.
20
     *
21
     * @var bool
22
     */
23
    protected $replaceSpacesByUnderScoresInKeyNames = true;
24
25
    /**
26
     * Construct a new instance.
27
     *
28
     * @param string[] $array
29
     * @param string   $rootElementName
30
     * @param bool     $replaceSpacesByUnderScoresInKeyNames
31
     *
32
     * @throws DOMException
33
     */
34
    public function __construct(array $array, $rootElementName = '', $replaceSpacesByUnderScoresInKeyNames = true)
35
    {
36
        $this->document = new DOMDocument();
37
        $this->replaceSpacesByUnderScoresInKeyNames = $replaceSpacesByUnderScoresInKeyNames;
38
39
        if ($this->isArrayAllKeySequential($array) && !empty($array)) {
40
            throw new DOMException('Invalid Character Error');
41
        }
42
43
        $root = $this->document->createElement($rootElementName == '' ? 'root' : $rootElementName);
44
45
        $this->document->appendChild($root);
46
47
        $this->convertElement($root, $array);
48
    }
49
50
    /**
51
     * Convert the given array to an xml string.
52
     *
53
     * @param string[] $array
54
     * @param string   $rootElementName
55
     * @param bool     $replaceSpacesByUnderScoresInKeyNames
56
     *
57
     * @return string
58
     */
59
    public static function convert(array $array, $rootElementName = '', $replaceSpacesByUnderScoresInKeyNames = true)
60
    {
61
        $converter = new static($array, $rootElementName, $replaceSpacesByUnderScoresInKeyNames);
62
63
        return $converter->toXml();
64
    }
65
66
    /**
67
     * Return as XML.
68
     *
69
     * @return string
70
     */
71
    public function toXml()
72
    {
73
        return $this->document->saveXML();
74
    }
75
76
    /**
77
     * Return as DOM object.
78
     *
79
     * @return DOMDocument
80
     */
81
    public function toDom()
82
    {
83
        return $this->document;
84
    }
85
86
    /**
87
     * Parse individual element.
88
     *
89
     * @param \DOMElement     $element
90
     * @param string|string[] $value
91
     */
92
    private function convertElement(DOMElement $element, $value)
93
    {
94
        $sequential = $this->isArrayAllKeySequential($value);
95
96
        if (!is_array($value)) {
97
            $element->nodeValue = htmlspecialchars($value);
98
99
            return;
100
        }
101
102
        foreach ($value as $key => $data) {
103
            if (!$sequential) {
104
                if ($key === '_attributes') {
105
                    $this->addAttributes($element, $data);
106
                } elseif ($key === '_value' && is_string($data)) {
107
                    $element->nodeValue = $data;
108
                } else {
109
                    $this->addNode($element, $key, $data);
110
                }
111
            } elseif (is_array($data)) {
112
                $this->addCollectionNode($element, $data);
113
            } else {
114
                $this->addSequentialNode($element, $data);
115
            }
116
        }
117
    }
118
119
    /**
120
     * Add node.
121
     *
122
     * @param \DOMElement     $element
123
     * @param string          $key
124
     * @param string|string[] $value
125
     */
126
    protected function addNode(DOMElement $element, $key, $value)
127
    {
128
        if ($this->replaceSpacesByUnderScoresInKeyNames) {
129
            $key = str_replace(' ', '_', $key);
130
        }
131
132
        $child = $this->document->createElement($key);
133
        $element->appendChild($child);
134
        $this->convertElement($child, $value);
135
    }
136
137
    /**
138
     * Add collection node.
139
     *
140
     * @param \DOMElement     $element
141
     * @param string|string[] $value
142
     *
143
     * @internal param string $key
144
     */
145
    protected function addCollectionNode(DOMElement $element, $value)
146
    {
147
        if ($element->childNodes->length == 0) {
148
            $this->convertElement($element, $value);
149
150
            return;
151
        }
152
153
        $child = $element->cloneNode();
154
        $element->parentNode->appendChild($child);
155
        $this->convertElement($child, $value);
0 ignored issues
show
Compatibility introduced by
$child of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
156
    }
157
158
    /**
159
     * Add sequential node.
160
     *
161
     * @param \DOMElement     $element
162
     * @param string|string[] $value
163
     *
164
     * @internal param string $key
165
     */
166
    protected function addSequentialNode(DOMElement $element, $value)
167
    {
168
        if (empty($element->nodeValue)) {
169
            $element->nodeValue = htmlspecialchars($value);
170
171
            return;
172
        }
173
174
        $child = $element->cloneNode();
175
        $child->nodeValue = htmlspecialchars($value);
176
        $element->parentNode->appendChild($child);
177
    }
178
179
    /**
180
     * Check if array are all sequential.
181
     *
182
     * @param array|string $value
183
     *
184
     * @return bool
185
     */
186
    protected function isArrayAllKeySequential($value)
187
    {
188
        if (!is_array($value)) {
189
            return false;
190
        }
191
192
        if (count($value) <= 0) {
193
            return true;
194
        }
195
196
        return array_unique(array_map('is_int', array_keys($value))) === array(true);
197
    }
198
199
    /**
200
     * Add attributes.
201
     *
202
     * @param \DOMElement $element
203
     * @param string[]    $data
204
     */
205
    protected function addAttributes($element, $data)
206
    {
207
        foreach ($data as $attrKey => $attrVal) {
208
            $element->setAttribute($attrKey, $attrVal);
209
        }
210
    }
211
}
212