Completed
Push — master ( aa6cd0...7372cb )
by Randy
02:05
created

Translator::createAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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