Completed
Branch scrutinizer (607e7a)
by Thomas
02:04
created

HtmlQuery::setCss()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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