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
     * @return static
51
     */
52 62
    protected function resolve($nodes)
53
    {
54 62
        if ($nodes instanceof static) {
55 21
            return $nodes;
56
        }
57
58 62
        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
     * @return static
69
     */
70 19
    protected function targetResolve($selector)
71
    {
72 19
        if (is_string($selector)) {
73 16
            return $this->resolve($this->doc)->find($selector);
74
        }
75
76 8
        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
     * @return static
87
     */
88 17
    protected function contentResolve($content)
89
    {
90 17
        if (is_string($content)) {
91 12
            return $this->htmlResolve($content);
92
        }
93
94 15
        return $this->resolve($content);
95
    }
96
97
    /**
98
     * Resolve the html content to static instance.
99
     *
100
     * @param string $html
101
     *
102
     * @return static
103
     */
104 14
    protected function htmlResolve(string $html)
105
    {
106 14
        $frag = $this->doc->createDocumentFragment();
107 14
        $frag->appendXML($html);
108
109 14
        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
     * @return static
120
     */
121 4
    protected function relationResolve(string $relation, ?string $until = null)
122
    {
123 4
        $untilNodes = !is_null($until)
124 4
            ? $this->targetResolve($until)->nodes
125 1
            : [];
126
127 4
        $nodes = [];
128 4
        foreach ($this->nodes as $node) {
129 4
            while ($node = Helper::getRelationNode($node, $relation)) {
130 4
                if (in_array($node, $untilNodes, true)) {
131 4
                    break;
132
                }
133
134 4
                if (!in_array($node, $nodes, true)) {
135 4
                    $nodes[] = $node;
136
                }
137
            }
138
        }
139
140 4
        return $this->resolve($nodes);
141
    }
142
143
    /**
144
     * Resolve the xpath to static instance.
145
     *
146
     * @param string $xpath
147
     *
148
     * @return static
149
     */
150 31
    protected function xpathResolve(string $xpath)
151
    {
152 31
        $nodes = [];
153 31
        foreach ($this->nodes as $node) {
154 30
            $nodes = array_merge($nodes, $this->xpathQuery($xpath, $node));
155
        }
156
157 31
        $nodes = Helper::strictArrayUnique($nodes);
158
159 31
        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
     * @return DOMNode[]
169
     */
170 35
    protected function xpathQuery(
171
        string $xpath,
172
        ?DOMNode $node = null
173
    ): array {
174 35
        return Helper::xpathQuery($xpath, $this->doc, $node);
175
    }
176
}
177