HtmlQuery   A
last analyzed

Complexity

Total Complexity 39

Size/Duplication

Total Lines 386
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 82
c 2
b 1
f 0
dl 0
loc 386
ccs 97
cts 97
cp 1
rs 9.28
wmc 39

23 Methods

Rating   Name   Duplication   Size   Complexity  
A html() 0 7 2
A setCss() 0 4 1
A text() 0 7 2
A getCss() 0 4 1
A validateNodes() 0 22 4
A setHtml() 0 9 2
A __construct() 0 4 1
A hasClass() 0 5 1
A setVal() 0 4 1
A removeClass() 0 4 1
A setText() 0 4 1
A toggleClass() 0 4 1
A addClass() 0 4 1
A removeCss() 0 4 1
A outerHtml() 0 4 1
A css() 0 15 5
A getText() 0 4 1
A remove() 0 11 2
A convertNodes() 0 11 5
A val() 0 7 2
A empty() 0 4 1
A getVal() 0 4 1
A getHtml() 0 4 1
1
<?php
2
3
namespace Sulao\HtmlQuery;
4
5
use DOMDocument;
6
use DOMNode;
7
use DOMNodeList;
8
use Traversable;
9
10
/**
11
 * Class HtmlQuery
12
 *
13
 * @package Sulao\HtmlQuery
14
 */
15
class HtmlQuery extends HtmlQueryNode
16
{
17
    const VERSION = '1.0.1';
18
19
    /**
20
     * @var DOMDocument
21
     */
22
    protected $doc;
23
24
    /**
25
     * @var DOMNode[]
26
     */
27
    protected $nodes;
28
29
    /**
30
     * HtmlQuery constructor.
31
     *
32
     * @param DOMDocument                   $doc
33
     * @param DOMNode|DOMNode[]|DOMNodeList $nodes
34
     *
35 82
     * @throws Exception
36
     */
37 82
    public function __construct(DOMDocument $doc, $nodes)
38 82
    {
39 82
        $this->doc = $doc;
40
        $this->nodes = $this->validateNodes($nodes);
41
    }
42
43
    /**
44
     * Get the outer HTML contents of the first matched node.
45
     *
46 29
     * @return string|null
47
     */
48
    public function outerHtml()
49 29
    {
50 29
        return $this->mapFirst(function (HtmlNode $node) {
51
            return $node->outerHtml();
52
        });
53
    }
54
55
    /**
56
     * Get the inner HTML contents of the first matched node or
57
     * set the inner HTML contents of every matched node.
58
     *
59
     * @param string|null $html
60
     *
61 26
     * @return string|null|static
62
     */
63 26
    public function html(?string $html = null)
64 2
    {
65
        if (!is_null($html)) {
66
            return $this->setHtml($html);
67 26
        }
68
69
        return $this->getHtml();
70
    }
71
72
    /**
73
     * Get the inner HTML contents of the first matched node.
74
     *
75 26
     * @return string|null
76
     */
77
    public function getHtml()
78 26
    {
79 26
        return $this->mapFirst(function (HtmlNode $node) {
80
            return $node->getHtml();
81
        });
82
    }
83
84
    /**
85
     * Set the inner HTML contents of every matched node.
86
     *
87
     * @param string $html
88
     *
89 2
     * @return static
90
     */
91 2
    public function setHtml(string $html)
92
    {
93 2
        $this->empty();
94 2
95
        if ($html !== '') {
96
            $this->append($html);
97 2
        }
98
99
        return $this;
100
    }
101
102
    /**
103
     * Get the combined text contents of the first matched node, including
104
     * it's descendants, or set the text contents of every matched node.
105
     *
106
     * @param string|null $text
107
     *
108 5
     * @return string|null|static
109
     */
110 5
    public function text(?string $text = null)
111 2
    {
112
        if (!is_null($text)) {
113
            return $this->setText($text);
114 4
        }
115
116
        return $this->getText();
117
    }
118
119
    /**
120
     * Get the combined text contents of the first matched node,
121
     * including it's descendants.
122
     *
123 4
     * @return string|null
124
     */
125
    public function getText()
126 4
    {
127 4
        return $this->mapFirst(function (HtmlNode $node) {
128
            return $node->getText();
129
        });
130
    }
131
132
    /**
133
     * set the text contents of every matched node.
134
     *
135
     * @param string $text
136
     *
137 2
     * @return static
138
     */
139
    public function setText(string $text)
140 2
    {
141 2
        return $this->each(function (HtmlNode $node) use ($text) {
142
            $node->setText($text);
143
        });
144
    }
145
146
    /**
147
     * Remove all child nodes of all matched nodes from the DOM.
148
     *
149 3
     * @return static
150
     */
151
    public function empty()
152 3
    {
153 3
        return $this->each(function (HtmlNode $node) {
154
            $node->empty();
155
        });
156
    }
157
158
    /**
159
     * Remove the matched nodes from the DOM.
160
     * optionally filtered by a selector.
161
     *
162
     * @param string|null $selector
163
     *
164 2
     * @return static
165
     */
166 2
    public function remove(?string $selector = null)
167 1
    {
168
        if (!is_null($selector)) {
169
            $this->filter($selector)->remove();
170 2
        } else {
171 2
            $this->each(function (HtmlNode $node) {
172
                $node->remove();
173
            });
174 2
        }
175
176
        return $this;
177
    }
178
179
    /**
180
     * Get the current value of the first matched node
181
     * or set the value of every matched node.
182
     *
183
     * @param string|null $value
184
     *
185 1
     * @return string|null|static
186
     */
187 1
    public function val(?string $value = null)
188 1
    {
189
        if (is_null($value)) {
190
            return $this->getVal();
191 1
        }
192
193
        return $this->setVal($value);
194
    }
195
196
    /**
197
     * Get the current value of the first matched node
198
     *
199 1
     * @return string|null
200
     */
201
    public function getVal()
202 1
    {
203 1
        return $this->mapFirst(function (HtmlElement $node) {
204
            return $node->getVal();
205
        });
206
    }
207
208
    /**
209
     * Set the value of every matched node.
210
     *
211
     * @param string $value
212
     *
213 1
     * @return static
214
     */
215
    public function setVal(string $value)
216 1
    {
217 1
        return $this->each(function (HtmlElement $node) use ($value) {
218
            $node->setVal($value);
219
        });
220
    }
221
222
    /**
223
     * Adds the specified class(es) to each node in the matched nodes.
224
     *
225
     * @param string $className
226
     *
227 4
     * @return static
228
     */
229
    public function addClass(string $className)
230 4
    {
231 4
        return $this->each(function (HtmlElement $node) use ($className) {
232
            $node->addClass($className);
233
        });
234
    }
235
236
    /**
237
     * Determine whether any of the matched nodes are assigned the given class.
238
     *
239
     * @param string $className
240
     *
241 2
     * @return bool
242
     */
243 2
    public function hasClass(string $className)
244
    {
245 2
        return $this->mapAnyTrue(
246 2
            function (HtmlElement $node) use ($className) {
247
                return $node->hasClass($className);
248
            }
249
        );
250
    }
251
252
    /**
253
     * Remove a single class, multiple classes, or all classes
254
     * from each matched node.
255
     *
256
     * @param string|null $className
257
     *
258 2
     * @return static
259
     */
260
    public function removeClass(?string $className = null)
261 2
    {
262 2
        return $this->each(function (HtmlElement $node) use ($className) {
263
            $node->removeClass($className);
264
        });
265
    }
266
267
    /**
268
     * Add or remove class(es) from each matched node, depending on
269
     * either the class's presence or the value of the state argument.
270
     *
271
     * @param string $className
272
     * @param bool|null   $state
273
     *
274 1
     * @return static
275
     */
276
    public function toggleClass(string $className, ?bool $state = null)
277 1
    {
278 1
        return $this->each(function (HtmlElement $node) use ($className, $state) {
279
            $node->toggleClass($className, $state);
280
        });
281
    }
282
283
    /**
284
     * Get the value of a computed style property for the first matched node
285
     * or set one or more CSS properties for every matched node.
286
     *
287
     * @param string|array $name
288
     * @param string|null  $value
289
     *
290 1
     * @return static|string|null
291
     */
292 1
    public function css($name, $value = null)
293 1
    {
294
        if (is_null($value) && !is_array($name)) {
295
            return $this->getCss($name);
296 1
        }
297 1
298 1
        if (is_array($name)) {
299
            foreach ($name as $key => $val) {
300
                $this->setCss($key, $val);
301 1
            }
302
        } else {
303
            $this->setCss($name, $value);
304 1
        }
305
306
        return $this;
307
    }
308
309
    /**
310
     * Get the value of a computed style property for the first matched node
311
     *
312
     * @param string $name
313
     *
314 1
     * @return string|null
315
     */
316
    public function getCss(string $name)
317 1
    {
318 1
        return $this->mapFirst(function (HtmlElement $node) use ($name) {
319
            return $node->getCss($name);
320
        });
321
    }
322
323
    /**
324
     * Set or Remove one CSS property for every matched node.
325
     *
326
     * @param string      $name
327
     * @param string|null $value
328
     *
329 1
     * @return static
330
     */
331
    public function setCss(string $name, ?string $value)
332 1
    {
333 1
        return $this->each(function (HtmlElement $node) use ($name, $value) {
334
            $node->setCss($name, $value);
335
        });
336
    }
337
338
    /**
339
     * Remove one CSS property for every matched node.
340
     *
341
     * @param string $name
342
     *
343 1
     * @return static
344
     */
345
    public function removeCss(string $name)
346 1
    {
347 1
        return $this->each(function (HtmlElement $node) use ($name) {
348
            $node->removeCss($name);
349
        });
350
    }
351
352
    /**
353
     * Validate the nodes
354
     *
355
     * @param DOMNode|DOMNode[]|DOMNodeList|static $nodes
356
     *
357 82
     * @return DOMNode[]
358
     */
359 82
    protected function validateNodes($nodes)
360
    {
361
        $nodes = $this->convertNodes($nodes);
362 80
363 2
        array_map(function ($node) {
364
            if (!($node instanceof DOMNode)) {
365 2
                throw new Exception(
366
                    'Expect an instance of DOMNode, '
367
                        . gettype($node) . ' given.'
368
                );
369 80
            }
370
371 80
            $document = $node->ownerDocument ?: $node;
372 1
373 1
            if ($document !== $this->doc) {
374
                throw new Exception(
375
                    'The DOMNode does not belong to the DOMDocument.'
376 82
                );
377
            }
378 82
        }, $nodes);
379
380
        return $nodes;
381
    }
382
383
    /**
384
     * Convert nodes to array
385
     *
386
     * @param DOMNode|DOMNode[]|DOMNodeList|static $nodes
387
     *
388 82
     * @return array
389
     */
390 82
    protected function convertNodes($nodes): array
391 21
    {
392 80
        if (empty($nodes)) {
393 1
            $nodes = [];
394 80
        } elseif ($nodes instanceof Traversable) {
395 57
            $nodes = iterator_to_array($nodes);
396
        } elseif ($nodes instanceof DOMNode || !is_array($nodes)) {
397
            $nodes = [$nodes];
398 82
        }
399
400
        return Helper::strictArrayUnique($nodes);
401
    }
402
}
403