Completed
Push — master ( 2f5cae...701262 )
by Joschi
03:21
created

DOMIterator::rewind()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/**
4
 * rdfa-lite-microdata
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\RdfaLiteMicrodata
8
 * @subpackage Jkphl\RdfaLiteMicrodata\Application
9
 * @author Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Jkphl\RdfaLiteMicrodata\Application\Parser;
38
39
use Jkphl\RdfaLiteMicrodata\Application\Contract\ElementProcessorInterface;
40
41
/**
42
 * Recursive DOM node iterator
43
 *
44
 * @package Jkphl\RdfaLiteMicrodata
45
 * @subpackage Jkphl\RdfaLiteMicrodata\Application
46
 */
47
class DOMIterator extends \ArrayIterator implements \RecursiveIterator
48
{
49
    /**
50
     * Registered contexts
51
     *
52
     * @var Context[]
53
     */
54
    public $contexts = [];
55
    /**
56
     * Element processor
57
     *
58
     * @var ElementProcessorInterface
59
     */
60
    protected $elementProcessor;
61
    /**
62
     * Initial parser context
63
     *
64
     * @var Context
65
     */
66
    protected $initialContext;
67
    /**
68
     * Element context map
69
     *
70
     * @var array
71
     */
72
    protected $contextMap = [];
73
74
    /**
75
     * Recursive DOM node iterator constructor
76
     *
77
     * @param \DOMNodeList $nodeList Node list
78
     * @param Context $initialContext Initial parser context
79
     * @param ElementProcessorInterface $elementProcessor Element processor
80
     */
81 9
    public function __construct(
82
        \DOMNodeList $nodeList,
83
        Context $initialContext,
84
        ElementProcessorInterface $elementProcessor
85
    ) {
86 9
        $this->elementProcessor = $elementProcessor;
87 9
        $this->initialContext = $initialContext;
88
89 9
        $nodes = [];
90
91
        // Run through and register all nodes
92
        /** @var \DOMNode $node */
93 9
        foreach ($nodeList as $node) {
94 9
            $nodes[spl_object_hash($node)] = $this->registerNode($node);
95 9
        }
96
97 9
        parent::__construct($nodes);
98 9
    }
99
100
    /**
101
     * Register an element node
102
     *
103
     * @param \DOMNode $node Node
104
     * @return \DOMNode Node
105
     */
106 9
    protected function registerNode(\DOMNode $node)
107
    {
108 9
        if ($node->nodeType == XML_ELEMENT_NODE) {
109
            /** @var \DOMElement $node */
110 9
            $localContext = $this->elementProcessor->processElement($node, $this->initialContext);
111
112
            // Register the node context
113 9
            $localContextId = spl_object_hash($localContext);
114 9
            if (empty($this->contexts[$localContextId])) {
115 9
                $this->contexts[$localContextId] = $localContext;
116 9
            }
117
118 9
            $this->contextMap[spl_object_hash($node)] = $localContextId;
119 9
        }
120
121 9
        return $node;
122
    }
123
124
    /**
125
     * Return the recursive iterator
126
     *
127
     * @return \RecursiveIteratorIterator Recursive iterator
128
     */
129 9
    public function getRecursiveIterator()
130
    {
131 9
        return new \RecursiveIteratorIterator($this, \RecursiveIteratorIterator::SELF_FIRST);
132
    }
133
134
    /**
135
     * Return whether the current node has child nodes
136
     *
137
     * This method gets called once per element and prior to the call to current(),
138
     * so this seems like the perfect place for the first processing steps (even
139
     * for elements without children).
140
     *
141
     * @return boolean Current node has child nodes
142
     */
143 9
    public function hasChildren()
144
    {
145 9
        return $this->current()->hasChildNodes();
146
    }
147
148
    /**
149
     * Return a child node iterator
150
     *
151
     * @return DOMIterator Child node iterator
152
     */
153 9
    public function getChildren()
154
    {
155 9
        $element = $this->current();
156 9
        $childContext = $this->elementProcessor->processElementChildren(
157 9
            $element,
158 9
            $this->contexts[$this->contextMap[$this->key()]]
159 9
        );
160 9
        return new static($element->childNodes, $childContext, $this->elementProcessor);
161
    }
162
163
    /**
164
     * Rewind array back to the start
165
     *
166
     * @return void
167
     */
168 9
    public function rewind()
169
    {
170 9
        parent::rewind();
171 9
    }
172
}
173