Completed
Push — master ( 56a459...0ee720 )
by Randy
03:34
created

XmlTranslator::appendChildNodes()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 2
1
<?php
2
3
namespace Dgame\Soap;
4
5
use Dgame\Soap\Attribute\Attribute;
6
use Dgame\Soap\Attribute\XmlAttribute;
7
use DOMAttr;
8
use DOMDocument;
9
use DOMNode;
10
11
/**
12
 * Class XmlTranslator
13
 * @package Dgame\Soap
14
 */
15
final class XmlTranslator
16
{
17
    /**
18
     * @param DOMDocument $document
19
     *
20
     * @return Element[]|XmlNode[]
21
     */
22
    public function translateDocument(DOMDocument $document): array
23
    {
24
        $elements = [];
25
        foreach ($document->childNodes as $node) {
26
            $element = $this->translateNode($node);
27
            if ($element !== null) {
28
                $elements[] = $element;
29
            }
30
        }
31
32
        return $elements;
33
    }
34
35
    /**
36
     * @param DOMNode $node
37
     *
38
     * @return XmlNode|Element|null
39
     */
40
    public function translateNode(DOMNode $node)
41
    {
42
        if ($node->nodeType === XML_ELEMENT_NODE) {
43
            if ($this->isElementNode($node)) {
44
                return $this->createElement($node);
45
            }
46
47
            return $this->createNode($node);
48
        }
49
50
        return null;
51
    }
52
53
    /**
54
     * @param DOMNode $node
55
     *
56
     * @return Element
57
     */
58
    private function createElement(DOMNode $node): Element
59
    {
60
        $element = new XmlElement($node->localName, $node->nodeValue, $node->prefix);
61
        $this->setAttributes($node, $element);
62
63
        return $element;
64
    }
65
66
    /**
67
     * @param DOMNode $node
68
     *
69
     * @return XmlNode
70
     */
71
    private function createNode(DOMNode $node): XmlNode
72
    {
73
        $element = new XmlNode($node->localName, null, $node->prefix);
74
        $this->setAttributes($node, $element);
75
        $this->appendChildNodes($node, $element);
76
77
        return $element;
78
    }
79
80
    /**
81
     * @param DOMNode $node
82
     * @param Element $element
83
     */
84
    private function setAttributes(DOMNode $node, Element $element)
85
    {
86
        foreach ($node->attributes as $attribute) {
87
            $element->setAttribute($this->createAttribute($attribute));
88
        }
89
    }
90
91
    /**
92
     * @param DOMAttr $attr
93
     *
94
     * @return Attribute
95
     */
96
    private function createAttribute(DOMAttr $attr): Attribute
97
    {
98
        return new XmlAttribute($attr->name, $attr->value, $attr->prefix);
99
    }
100
101
    /**
102
     * @param DOMNode $node
103
     * @param XmlNode $parent
104
     */
105
    private function appendChildNodes(DOMNode $node, XmlNode $parent)
106
    {
107
        foreach ($node->childNodes as $childNode) {
108
            $child = $this->translateNode($childNode);
109
            if ($child !== null) {
110
                $parent->appendChild($child);
111
            }
112
        }
113
    }
114
115
    /**
116
     * @param DOMNode $node
117
     *
118
     * @return bool
119
     */
120
    private function isElementNode(DOMNode $node): bool
121
    {
122
        return $node->childNodes->length === 0 || ($node->childNodes->length === 1 && $node->firstChild->nodeType === XML_TEXT_NODE);
123
    }
124
}