Completed
Push — master ( f18951...94bfb9 )
by Randy
03:34
created

Translator::translateNode()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 6
cts 6
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 6
nc 3
nop 1
crap 5
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 (!$node->hasChildNodes() || ($node->childNodes->length === 1 && $node->firstChild->nodeType === XML_TEXT_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 XmlElement
66
     */
67 9
    private function createElement(DOMNode $node): XmlElement
68
    {
69 9
        $element = new XmlElement($node->localName, $node->nodeValue, $node->prefix);
70 9
        $this->setAttributes($node, $element);
71
72 9
        return $element;
73
    }
74
75
    /**
76
     * @param DOMNode $node
77
     *
78
     * @return XmlNode
79
     */
80 8
    private function createNode(DOMNode $node): XmlNode
81
    {
82 8
        $element = new XmlNode($node->localName, null, $node->prefix);
83 8
        $this->setAttributes($node, $element);
84 8
        $this->appendChildNodes($node, $element);
85
86 8
        return $element;
87
    }
88
89
    /**
90
     * @param DOMNode    $node
91
     * @param XmlElement $element
92
     */
93 9
    private function setAttributes(DOMNode $node, XmlElement $element)
94
    {
95 9
        foreach ($node->attributes as $attribute) {
96 7
            $element->setAttribute($this->createAttribute($attribute));
97
        }
98 9
    }
99
100
    /**
101
     * @param DOMAttr $attr
102
     *
103
     * @return XmlAttribute
104
     */
105 7
    private function createAttribute(DOMAttr $attr): XmlAttribute
106
    {
107 7
        return new XmlAttribute($attr->name, $attr->value, $attr->prefix);
108
    }
109
110
    /**
111
     * @param DOMNode $node
112
     * @param XmlNode $parent
113
     */
114 8
    private function appendChildNodes(DOMNode $node, XmlNode $parent)
115
    {
116 8
        foreach ($node->childNodes as $childNode) {
117 8
            $child = $this->translateNode($childNode);
118 8
            if ($child !== null) {
119 8
                $parent->appendChild($child);
120 5
            } elseif ($childNode->nodeType === XML_TEXT_NODE) {
121 8
                $parent->setValue($childNode->nodeValue);
122
            }
123
        }
124
    }
125
}