Completed
Push — develop ( 5697fc...ff1568 )
by Mikaël
01:59
created

AbstractDomDocumentHandler::getNodeHandler()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
ccs 0
cts 0
cp 0
c 0
b 0
f 0
nc 1
1
<?php
2
3
namespace WsdlToPhp\DomHandler;
4
5
abstract class AbstractDomDocumentHandler
6
{
7
    /**
8
     * @var \DOMDocument
9
     */
10
    protected $domDocument;
11
    /**
12
     * @var ElementHandler
13
     */
14
    protected $rootElement;
15
    /**
16
     * @param \DOMDocument $domDocument
17
     */
18 16
    public function __construct(\DOMDocument $domDocument)
19
    {
20 16
        $this->domDocument = $domDocument;
21 16
        $this->initRootElement();
22 12
    }
23
    /**
24
     * Find valid root node (not a comment, at least a DOMElement node)
25
     * @throws \InvalidArgumentException
26
     */
27 16
    protected function initRootElement()
28
    {
29 16
        if ($this->domDocument->hasChildNodes()) {
30 12
            foreach ($this->domDocument->childNodes as $node) {
31 12
                if ($node instanceof \DOMElement) {
32 12
                    $this->rootElement = $this->getElementHandler($node, $this);
33 12
                    break;
34
                }
35 9
            }
36 9
        } else {
37 4
            throw new \InvalidArgumentException('Document seems to be invalid', __LINE__);
38
        }
39 12
    }
40
    /**
41
     * Return the matching node handler based on current \DomNode type
42
     * @param \DOMNode|\DOMNameSpaceNode $node
43
     * @param int $index
44
     * @return NodeHandler|ElementHandler|AttributeHandler|NameSpaceHandler
45
     */
46 156
    public function getHandler($node, $index = -1)
47
    {
48 156
        if ($node instanceof \DOMElement) {
49 120
            return $this->getElementHandler($node, $this, $index);
50 90
        } elseif ($node instanceof \DOMAttr) {
51 92
            return $this->getAttributeHandler($node, $this, $index);
52 21
        } elseif ($node instanceof \DOMNameSpaceNode) {
53 12
            return new NameSpaceHandler($node, $this, $index);
54
        }
55 16
        return $this->getNodeHandler($node, $this, $index);
56
    }
57
    /**
58
     * @param \DOMNode $node
59
     * @param AbstractDomDocumentHandler $domDocument
60
     * @param int $index
61
     * @return NodeHandler
62
     */
63
    abstract protected function getNodeHandler(\DOMNode $node, AbstractDomDocumentHandler $domDocument, $index = -1);
64
    /**
65
     * @param \DOMElement $element
66
     * @param AbstractDomDocumentHandler $domDocument
67
     * @param int $index
68
     * @return ElementHandler
69
     */
70
    abstract protected function getElementHandler(\DOMElement $element, AbstractDomDocumentHandler $domDocument, $index = -1);
71
    /**
72
     * @param \DOMAttr $attribute
73
     * @param AbstractDomDocumentHandler $domDocument
74
     * @param int $index
75
     * @return AttributeHandler
76
     */
77
    abstract protected function getAttributeHandler(\DOMAttr $attribute, AbstractDomDocumentHandler $domDocument, $index = -1);
78
    /**
79
     * @param string $name
80
     * @return NodeHandler
81
     */
82 84
    public function getNodeByName($name)
83
    {
84 84
        return $this->domDocument->getElementsByTagName($name)->length > 0 ? $this->getNodeHandler($this->domDocument->getElementsByTagName($name)->item(0), $this) : null;
85
    }
86
    /**
87
     * @param string $name
88
     * @return ElementHandler
89
     */
90 52
    public function getElementByName($name)
91
    {
92 52
        $node = $this->getNodeByName($name);
93 52
        if ($node instanceof AbstractNodeHandler && $node->getNode() instanceof \DOMElement) {
94 48
            return $this->getElementHandler($node->getNode(), $this);
95
        }
96 4
        return null;
97
    }
98
    /**
99
     * @param string $name
100
     * @param string $checkInstance
101
     * @return NodeHandler[]
102
     */
103 96
    public function getNodesByName($name, $checkInstance = null)
104
    {
105 96
        $nodes = array();
106 96
        if ($this->domDocument->getElementsByTagName($name)->length > 0) {
107 96
            foreach ($this->domDocument->getElementsByTagName($name) as $node) {
108 96
                if ($checkInstance === null || $node instanceof $checkInstance) {
109 96
                    $nodes[] = $this->getHandler($node, count($nodes));
110 72
                }
111 72
            }
112 72
        }
113 96
        return $nodes;
114
    }
115
    /**
116
     * @param string $name
117
     * @return ElementHandler[]
118
     */
119 92
    public function getElementsByName($name)
120
    {
121 92
        return $this->getNodesByName($name, 'DOMElement');
122
    }
123
    /**
124
     * @param string $name
125
     * @param array $attributes
126
     * @param \DOMNode $node
127
     * @return ElementHandler[]
128
     */
129 88
    public function getElementsByNameAndAttributes($name, array $attributes, \DOMNode $node = null)
130
    {
131 88
        $matchingElements = $this->getElementsByName($name);
132 88
        if ((!empty($attributes) || $node instanceof \DOMNode) && !empty($matchingElements)) {
133 88
            $nodes = $this->searchTagsByXpath($name, $attributes, $node);
134 88
            if (!empty($nodes)) {
135 88
                $matchingElements = $this->getElementsHandlers($nodes);
136 66
            }
137 66
        }
138 88
        return $matchingElements;
139
    }
140
    /**
141
     * @param \DOMNodeList $nodeList
142
     * @return ElementHandler[]
143
     */
144 92
    public function getElementsHandlers(\DOMNodeList $nodeList)
145
    {
146 92
        $nodes = array();
147 92
        if (!empty($nodeList)) {
148 92
            $index = 0;
149 92
            foreach ($nodeList as $node) {
150 92
                if ($node instanceof \DOMElement) {
151 92
                    $nodes[] = $this->getElementHandler($node, $this, $index);
152 92
                    $index++;
153 69
                }
154 69
            }
155 69
        }
156 92
        return $nodes;
157
    }
158
    /**
159
     * @param string $name
160
     * @param array $attributes
161
     * @param \DOMNode $node
162
     * @return \DOMNodeList
163
     */
164 88
    public function searchTagsByXpath($name, array $attributes, \DOMNode $node = null)
165
    {
166 88
        $xpath = new \DOMXPath($this->domDocument);
167 88
        $xQuery = sprintf("%s//*[local-name()='%s']", $node instanceof \DOMNode ? '.' : '', $name);
168 88
        foreach ($attributes as $attributeName => $attributeValue) {
169 88
            if (strpos($attributeValue, '*') !== false) {
170 4
                $xQuery .= sprintf("[contains(@%s, '%s')]", $attributeName, str_replace('*', '', $attributeValue));
171 3
            } else {
172 88
                $xQuery .= sprintf("[@%s='%s']", $attributeName, $attributeValue);
173
            }
174 66
        }
175 88
        return $xpath->query($xQuery, $node);
176
    }
177
    /**
178
     * @param string $name
179
     * @param array $attributes
180
     * @return null|ElementHandler
181
     */
182 80
    public function getElementByNameAndAttributes($name, array $attributes)
183
    {
184 80
        $elements = $this->getElementsByNameAndAttributes($name, $attributes);
185 80
        return empty($elements) ? null : array_shift($elements);
186
    }
187
}
188