Completed
Push — master ( 66d141...d54425 )
by Randy
02:23
created

Translator::isElement()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 3
eloc 2
nc 3
nop 1
crap 3
1
<?php
2
3
namespace Dgame\Soap\Dom;
4
5
use Dgame\Soap\Attribute\XmlAttribute;
6
use Dgame\Soap\XmlElement;
7
use Dgame\Soap\XmlNode;
8
use DOMAttr;
9
use DOMDocument;
10
use DOMNode;
11
12
/**
13
 * Class DomTranslator
14
 * @package Dgame\Soap
15
 */
16
final class Translator
17
{
18
    /**
19
     * @return Translator
0 ignored issues
show
Documentation introduced by
Should the return type not be \self?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
20
     */
21 6
    public static function new(): self
22
    {
23 6
        return new self();
24
    }
25
26
    /**
27
     * @param DOMDocument $document
28
     *
29
     * @return XmlElement[]|XmlNode[]
30
     */
31 7
    public function translateDocument(DOMDocument $document): array
32
    {
33 7
        $elements = [];
34 7
        foreach ($document->childNodes as $node) {
35 7
            $element = $this->translateNode($node);
36 7
            if ($element !== null) {
37 7
                $elements[] = $element;
38
            }
39
        }
40
41 7
        return $elements;
42
    }
43
44
    /**
45
     * @param DOMNode $node
46
     *
47
     * @return XmlNode|XmlElement|null
48
     */
49 9
    public function translateNode(DOMNode $node)
50
    {
51 9
        if ($node->nodeType !== XML_ELEMENT_NODE) {
52 5
            return null;
53
        }
54
55 9
        if ($this->isElement($node)) {
56 9
            return $this->createElement($node);
57
        }
58
59 8
        return $this->createNode($node);
60
    }
61
62
    /**
63
     * @param DOMNode $node
64
     *
65
     * @return bool
66
     */
67 9
    public function isElement(DOMNode $node): bool
68
    {
69 9
        return !$node->hasChildNodes() || ($node->childNodes->length === 1 && $node->firstChild->nodeType === XML_TEXT_NODE);
70
    }
71
72
    /**
73
     * @param DOMNode $node
74
     *
75
     * @return XmlElement
76
     */
77 9
    private function createElement(DOMNode $node): XmlElement
78
    {
79 9
        $element = new XmlElement($node->localName, $node->nodeValue, $node->prefix);
80 9
        $this->setAttributes($node, $element);
81
82 9
        return $element;
83
    }
84
85
    /**
86
     * @param DOMNode $node
87
     *
88
     * @return XmlNode
89
     */
90 8
    private function createNode(DOMNode $node): XmlNode
91
    {
92 8
        $element = new XmlNode($node->localName, null, $node->prefix);
93 8
        $this->setAttributes($node, $element);
94 8
        $this->appendChildNodes($node, $element);
95
96 8
        return $element;
97
    }
98
99
    /**
100
     * @param DOMNode    $node
101
     * @param XmlElement $element
102
     */
103 9
    private function setAttributes(DOMNode $node, XmlElement $element)
104
    {
105 9
        foreach ($node->attributes as $attribute) {
106 7
            $element->setAttribute($this->createAttribute($attribute));
107
        }
108 9
    }
109
110
    /**
111
     * @param DOMAttr $attr
112
     *
113
     * @return XmlAttribute
114
     */
115 7
    private function createAttribute(DOMAttr $attr): XmlAttribute
116
    {
117 7
        return new XmlAttribute($attr->name, $attr->value, $attr->prefix);
118
    }
119
120
    /**
121
     * @param DOMNode $node
122
     * @param XmlNode $parent
123
     */
124 8
    private function appendChildNodes(DOMNode $node, XmlNode $parent)
125
    {
126 8
        foreach ($node->childNodes as $childNode) {
127 8
            $child = $this->translateNode($childNode);
128 8
            if ($child !== null) {
129 8
                $parent->appendChild($child);
130 5
            } elseif ($childNode->nodeType === XML_TEXT_NODE) {
131 8
                $parent->setValue($childNode->nodeValue);
132
            }
133
        }
134
    }
135
}