Resolver   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 31
c 1
b 0
f 0
dl 0
loc 161
ccs 36
cts 36
cp 1
rs 10
wmc 16

7 Methods

Rating   Name   Duplication   Size   Complexity  
A resolve() 0 7 2
A relationResolve() 0 20 6
A xpathQuery() 0 5 1
A contentResolve() 0 7 2
A targetResolve() 0 7 2
A htmlResolve() 0 6 1
A xpathResolve() 0 10 2
1
<?php
2
3
namespace Sulao\HtmlQuery;
4
5
use DOMDocument;
6
use DOMNode;
7
use DOMNodeList;
8
9
/**
10
 * Trait Selector
11
 *
12
 * @package Sulao\HtmlQuery
13
 */
14
trait Resolver
15
{
16
    /**
17
     * @var DOMDocument
18
     */
19
    protected $doc;
20
21
    /**
22
     * @var DOMNode[]
23
     */
24
    protected $nodes;
25
26
    /**
27
     * Selector constructor.
28
     *
29
     * @param DOMDocument                          $doc
30
     * @param DOMNode|DOMNode[]|DOMNodeList|static $nodes
31
     *
32
     * @return static
33
     */
34
    abstract public function __construct(DOMDocument $doc, $nodes);
35
36
    /**
37
     * Get the descendants of each matched node, filtered by a selector.
38
     *
39
     * @param string|DOMNode|DOMNode[]|DOMNodeList|static $selector
40
     *
41
     * @return static
42
     */
43
    abstract public function find($selector);
44
45
    /**
46
     * Resolve DOMNode(s) to a static instance.
47
     *
48
     * @param DOMNode|DOMNode[]|DOMNodeList|static $nodes
49
     *
50 62
     * @return static
51
     */
52 62
    protected function resolve($nodes)
53 21
    {
54
        if ($nodes instanceof static) {
55
            return $nodes;
56 62
        }
57
58
        return new static($this->doc, $nodes);
59
    }
60
61
    /**
62
     * If the parameter is a css selector, get the descendants
63
     * of dom document filtered by the css selector.
64
     * If the parameter is selection, resolve that selection to static object.
65
     *
66
     * @param string|DOMNode|DOMNode[]|DOMNodeList|static $selector
67
     *
68 19
     * @return static
69
     */
70 19
    protected function targetResolve($selector)
71 16
    {
72
        if (is_string($selector)) {
73
            return $this->resolve($this->doc)->find($selector);
74 8
        }
75
76
        return $this->resolve($selector);
77
    }
78
79
    /**
80
     * If the parameter is string, consider it as raw html,
81
     * then create document fragment for it.
82
     * If the parameter is selection, resolve that selection to static instance.
83
     *
84
     * @param string|DOMNode|DOMNode[]|DOMNodeList|static $content
85
     *
86 17
     * @return static
87
     */
88 17
    protected function contentResolve($content)
89 12
    {
90
        if (is_string($content)) {
91
            return $this->htmlResolve($content);
92 15
        }
93
94
        return $this->resolve($content);
95
    }
96
97
    /**
98
     * Resolve the html content to static instance.
99
     *
100
     * @param string $html
101
     *
102 14
     * @return static
103
     */
104 14
    protected function htmlResolve(string $html)
105 14
    {
106
        $frag = $this->doc->createDocumentFragment();
107 14
        $frag->appendXML($html);
108
109
        return $this->resolve($frag);
110
    }
111
112
    /**
113
     * Resolve the nodes under the relation to static instance.
114
     * up to but not including the node matched by the $until selector.
115
     *
116
     * @param string $relation
117
     * @param string|DOMNode|DOMNode[]|DOMNodeList|static $until
118
     *
119 4
     * @return static
120
     */
121 4
    protected function relationResolve(string $relation, ?string $until = null)
122 4
    {
123 4
        $untilNodes = !is_null($until)
124
            ? $this->targetResolve($until)->nodes
125 4
            : [];
126 4
127 4
        $nodes = [];
128 4
        foreach ($this->nodes as $node) {
129 4
            while ($node = Helper::getRelationNode($node, $relation)) {
130
                if (in_array($node, $untilNodes, true)) {
131
                    break;
132 4
                }
133 4
134
                if (!in_array($node, $nodes, true)) {
135
                    $nodes[] = $node;
136
                }
137
            }
138 4
        }
139
140
        return $this->resolve($nodes);
141
    }
142
143
    /**
144
     * Resolve the xpath to static instance.
145
     *
146
     * @param string $xpath
147
     *
148 31
     * @return static
149
     */
150 31
    protected function xpathResolve(string $xpath)
151 31
    {
152 30
        $nodes = [];
153
        foreach ($this->nodes as $node) {
154
            $nodes = array_merge($nodes, $this->xpathQuery($xpath, $node));
155 31
        }
156
157 31
        $nodes = Helper::strictArrayUnique($nodes);
158
159
        return $this->resolve($nodes);
160
    }
161
162
    /**
163
     * Query xpath to an array of DOMNode
164
     *
165
     * @param string       $xpath
166
     * @param DOMNode|null $node
167
     *
168 35
     * @return DOMNode[]
169
     */
170
    protected function xpathQuery(
171
        string $xpath,
172 35
        ?DOMNode $node = null
173
    ): array {
174
        return Helper::xpathQuery($xpath, $this->doc, $node);
175
    }
176
}
177