Completed
Push — master ( e960f4...d2d510 )
by Randy
02:01
created

Translator   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 3
dl 0
loc 127
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A new() 0 4 1
A translate() 0 9 2
A translateDocument() 0 4 1
A translateNode() 0 12 3
A isElement() 0 4 3
A createElement() 0 7 1
A createNode() 0 8 1
A setAttributes() 0 6 2
A createAttribute() 0 4 1
A appendChildNodes() 0 11 4
1
<?php
2
3
namespace Dgame\Soap\Hydrator;
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 Translator
14
 * @package Dgame\Soap\Hydrator
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
    public static function new(): self
22
    {
23
        return new self();
24
    }
25
26
    /**
27
     * @param DOMNode $node
28
     *
29
     * @return XmlElement|XmlNode|null
30
     */
31
    public function translate(DOMNode $node)
32
    {
33
        if ($node->nodeType === XML_DOCUMENT_NODE) {
34
            /** @var DOMDocument $node */
35
            return $this->translateDocument($node);
36
        }
37
38
        return $this->translateNode($node);
39
    }
40
41
    /**
42
     * @param DOMDocument $document
43
     *
44
     * @return XmlNode|null
0 ignored issues
show
Documentation introduced by
Should the return type not be XmlElement|null?

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...
45
     */
46
    public function translateDocument(DOMDocument $document)
47
    {
48
        return $this->translateNode($document->documentElement);
49
    }
50
51
    /**
52
     * @param DOMNode $node
53
     *
54
     * @return XmlNode|XmlElement|null
55
     */
56
    public function translateNode(DOMNode $node)
57
    {
58
        if ($node->nodeType !== XML_ELEMENT_NODE) {
59
            return null;
60
        }
61
62
        if ($this->isElement($node)) {
63
            return $this->createElement($node);
64
        }
65
66
        return $this->createNode($node);
67
    }
68
69
    /**
70
     * @param DOMNode $node
71
     *
72
     * @return bool
73
     */
74
    public function isElement(DOMNode $node): bool
75
    {
76
        return !$node->hasChildNodes() || ($node->childNodes->length === 1 && $node->firstChild->nodeType === XML_TEXT_NODE);
77
    }
78
79
    /**
80
     * @param DOMNode $node
81
     *
82
     * @return XmlElement
83
     */
84
    private function createElement(DOMNode $node): XmlElement
85
    {
86
        $element = new XmlElement($node->localName, $node->nodeValue, $node->prefix);
87
        $this->setAttributes($node, $element);
88
89
        return $element;
90
    }
91
92
    /**
93
     * @param DOMNode $node
94
     *
95
     * @return XmlNode
96
     */
97
    private function createNode(DOMNode $node): XmlNode
98
    {
99
        $element = new XmlNode($node->localName, null, $node->prefix);
100
        $this->setAttributes($node, $element);
101
        $this->appendChildNodes($node, $element);
102
103
        return $element;
104
    }
105
106
    /**
107
     * @param DOMNode    $node
108
     * @param XmlElement $element
109
     */
110
    private function setAttributes(DOMNode $node, XmlElement $element)
111
    {
112
        foreach ($node->attributes as $attribute) {
113
            $element->setAttribute($this->createAttribute($attribute));
114
        }
115
    }
116
117
    /**
118
     * @param DOMAttr $attr
119
     *
120
     * @return XmlAttribute
121
     */
122
    private function createAttribute(DOMAttr $attr): XmlAttribute
123
    {
124
        return new XmlAttribute($attr->name, $attr->value, $attr->prefix);
125
    }
126
127
    /**
128
     * @param DOMNode $node
129
     * @param XmlNode $parent
130
     */
131
    private function appendChildNodes(DOMNode $node, XmlNode $parent)
132
    {
133
        foreach ($node->childNodes as $childNode) {
134
            $child = $this->translateNode($childNode);
135
            if ($child !== null) {
136
                $parent->appendElement($child);
137
            } elseif ($childNode->nodeType === XML_TEXT_NODE) {
138
                $parent->setValue($childNode->nodeValue);
139
            }
140
        }
141
    }
142
}