Completed
Pull Request — master (#3)
by
unknown
02:05
created

XmlToArray::isHomogenous()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Vyuldashev\XmlToArray;
6
7
use DOMAttr;
8
use DOMText;
9
use DOMElement;
10
use DOMDocument;
11
use DOMCdataSection;
12
use DOMNamedNodeMap;
13
14
class XmlToArray
15
{
16
    protected $document;
17
18
    public function __construct(string $xml)
19
    {
20
        $this->document = new DOMDocument();
21
        $this->document->loadXML($xml);
22
    }
23
24
    public static function convert(string $xml): array
25
    {
26
        $converter = new static($xml);
27
28
        return $converter->toArray();
29
    }
30
31
    protected function convertAttributes(DOMNamedNodeMap $nodeMap): ?array
32
    {
33
        if ($nodeMap->length === 0) {
0 ignored issues
show
Bug introduced by
The property length does not seem to exist on DOMNamedNodeMap.
Loading history...
34
            return null;
35
        }
36
37
        $result = [];
38
39
        /** @var DOMAttr $item */
40
        foreach ($nodeMap as $item) {
41
            $result[$item->name] = $item->value;
42
        }
43
44
        return ['_attributes' => $result];
45
    }
46
47
    protected function isHomogenous(Array $arr) {
48
        $firstValue = current($arr);
49
        foreach ($arr as $val) {
50
            if ($firstValue !== $val) {
51
                return false;
52
            }
53
        }
54
        return true;
55
    }
56
57
    protected function convertDomElement(DOMElement $element)
58
    {
59
        $sameNames = false;
60
        $result = $this->convertAttributes($element->attributes);
61
62
        if( count($element->childNodes)  > 1){
63
            $childNodeNames = [];
64
            foreach ($element->childNodes as $key => $node) {
65
                $childNodeNames[] = $node->nodeName;
66
            }
67
            $sameNames = $this->isHomogenous($childNodeNames);
68
        }
69
70
        foreach ($element->childNodes as $key => $node) {
71
            if ($node instanceof DOMCdataSection) {
72
                $result['_cdata'] = $node->data;
73
74
                continue;
75
            }
76
            if ($node instanceof DOMText) {
77
                $result = $node->textContent;
78
79
                continue;
80
            }
81
            if ($node instanceof DOMElement) {
82
83
                if( $sameNames ) {
84
                    $result[$node->nodeName][$key] = $this->convertDomElement($node);
85
                } else {
86
                    $result[$node->nodeName] = $this->convertDomElement($node);
87
                }
88
89
                continue;
90
            }
91
        }
92
93
        return $result;
94
    }
95
96
    public function toArray(): array
97
    {
98
        $result = [];
99
100
        if ($this->document->hasChildNodes()) {
101
            $children = $this->document->childNodes;
102
103
            foreach ($children as $child) {
104
                $result[$child->nodeName] = $this->convertDomElement($child);
105
            }
106
        }
107
108
        return $result;
109
    }
110
}
111