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 (#6)
by
unknown
01:54
created

ArrayToXml   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 200
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 10
Bugs 0 Features 3
Metric Value
wmc 25
c 10
b 0
f 3
lcom 1
cbo 0
dl 0
loc 200
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 22 4
A convert() 0 6 1
A toXml() 0 4 1
C convertElement() 0 26 8
A addNode() 0 10 2
A addCollectionNode() 0 12 2
A addSequentialNode() 0 12 2
A isArrayAllKeySequential() 0 12 3
A addAttributes() 0 6 2
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
0 ignored issues
show
Bug introduced by
There is no parameter named $replaceSpacesByUnderScoresInKeyNames. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
31
     *
32
     * @throws DOMException
33
     */
34
    public function __construct(array $array, $rootElementName = '', $options = [])
35
    {
36
        $options = array_merge([
37
            'replaceSpacesByUnderScoresInKeyNames' => true,
38
            'version'   => '1.0',
39
            'encoding'  => 'UTF-8'
40
        ],
41
        $options);
42
43
        $this->document = new DOMDocument($options['version'], $options['encoding']);
44
        $this->replaceSpacesByUnderScoresInKeyNames = $options['replaceSpacesByUnderScoresInKeyNames'];
45
46
        if ($this->isArrayAllKeySequential($array) && !empty($array)) {
47
            throw new DOMException('Invalid Character Error');
48
        }
49
50
        $root = $this->document->createElement($rootElementName == '' ? 'root' : $rootElementName);
51
52
        $this->document->appendChild($root);
53
54
        $this->convertElement($root, $array);
55
    }
56
57
    /**
58
     * Convert the given array to an xml string.
59
     *
60
     * @param string[] $array
61
     * @param string   $rootElementName
62
     * @param bool     $replaceSpacesByUnderScoresInKeyNames
0 ignored issues
show
Bug introduced by
There is no parameter named $replaceSpacesByUnderScoresInKeyNames. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
63
     *
64
     * @return type
65
     */
66
    public static function convert(array $array, $rootElementName = '', $options = [])
67
    {
68
        $converter = new static($array, $rootElementName, $options);
69
70
        return $converter->toXml();
71
    }
72
73
    /**
74
     * Return as XML.
75
     *
76
     * @return string
77
     */
78
    public function toXml()
79
    {
80
        return $this->document->saveXML();
81
    }
82
83
    /**
84
     * Parse individual element.
85
     *
86
     * @param \DOMElement     $element
87
     * @param string|string[] $value
88
     */
89
    private function convertElement(DOMElement $element, $value)
90
    {
91
        $sequential = $this->isArrayAllKeySequential($value);
92
93
        if (!is_array($value)) {
94
            $element->nodeValue = htmlspecialchars($value);
95
96
            return;
97
        }
98
99
        foreach ($value as $key => $data) {
100
            if (!$sequential) {
101
                if ($key === '_attributes') {
102
                    $this->addAttributes($element, $data);
103
                } elseif ($key === '_value' && is_string($data)) {
104
                    $element->nodeValue = $data;
105
                } else {
106
                    $this->addNode($element, $key, $data);
107
                }
108
            } elseif (is_array($data)) {
109
                $this->addCollectionNode($element, $data);
110
            } else {
111
                $this->addSequentialNode($element, $data);
112
            }
113
        }
114
    }
115
116
    /**
117
     * Add node.
118
     *
119
     * @param \DOMElement     $element
120
     * @param string          $key
121
     * @param string|string[] $value
122
     */
123
    protected function addNode(DOMElement $element, $key, $value)
124
    {
125
        if ($this->replaceSpacesByUnderScoresInKeyNames) {
126
            $key = str_replace(' ', '_', $key);
127
        }
128
129
        $child = $this->document->createElement($key);
130
        $element->appendChild($child);
131
        $this->convertElement($child, $value);
132
    }
133
134
    /**
135
     * Add collection node.
136
     *
137
     * @param \DOMElement     $element
138
     * @param string|string[] $value
139
     *
140
     * @internal param string $key
141
     */
142
    protected function addCollectionNode(DOMElement $element, $value)
143
    {
144
        if ($element->childNodes->length == 0) {
145
            $this->convertElement($element, $value);
146
147
            return;
148
        }
149
150
        $child = $element->cloneNode();
151
        $element->parentNode->appendChild($child);
152
        $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...
153
    }
154
155
    /**
156
     * Add sequential node.
157
     *
158
     * @param \DOMElement     $element
159
     * @param string|string[] $value
160
     *
161
     * @internal param string $key
162
     */
163
    protected function addSequentialNode(DOMElement $element, $value)
164
    {
165
        if (empty($element->nodeValue)) {
166
            $element->nodeValue = htmlspecialchars($value);
167
168
            return;
169
        }
170
171
        $child = $element->cloneNode();
172
        $child->nodeValue = htmlspecialchars($value);
173
        $element->parentNode->appendChild($child);
174
    }
175
176
    /**
177
     * Check if array are all sequential.
178
     *
179
     * @param array|string $value
180
     *
181
     * @return bool
182
     */
183
    protected function isArrayAllKeySequential($value)
184
    {
185
        if (!is_array($value)) {
186
            return false;
187
        }
188
189
        if (count($value) <= 0) {
190
            return true;
191
        }
192
193
        return array_unique(array_map('is_int', array_keys($value))) === array(true);
194
    }
195
196
    /**
197
     * Add attributes.
198
     *
199
     * @param \DOMElement $element
200
     * @param string[]    $data
201
     */
202
    protected function addAttributes($element, $data)
203
    {
204
        foreach ($data as $attrKey => $attrVal) {
205
            $element->setAttribute($attrKey, $attrVal);
206
        }
207
    }
208
}
209