Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Query often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Query, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
29 | class Query extends Nodes { |
||
30 | |||
31 | /** |
||
32 | * @var Nodes\Builder |
||
33 | */ |
||
34 | private $_builder; |
||
35 | |||
36 | /** |
||
37 | * Virtual properties, validate existence |
||
38 | * |
||
39 | * @param string $name |
||
40 | * @return bool |
||
41 | */ |
||
42 | 4 | public function __isset(string $name): bool { |
|
51 | |||
52 | /** |
||
53 | * Virtual properties, read property |
||
54 | * |
||
55 | * @param string $name |
||
56 | * @throws \UnexpectedValueException |
||
57 | * @return mixed |
||
58 | * @throws \LogicException |
||
59 | */ |
||
60 | 57 | public function __get(string $name) { |
|
77 | |||
78 | /** |
||
79 | * Block changing the readonly dynamic property |
||
80 | * |
||
81 | * @param string $name |
||
82 | * @param mixed $value |
||
83 | * @throws \InvalidArgumentException |
||
84 | * @throws \BadMethodCallException |
||
85 | */ |
||
86 | 5 | public function __set(string $name, $value) { |
|
104 | |||
105 | /** |
||
106 | * Throws an exception if somebody tries to unset one |
||
107 | * of the dynamic properties |
||
108 | * |
||
109 | * @param string $name |
||
110 | * @throws \BadMethodCallException |
||
111 | */ |
||
112 | 4 | public function __unset(string $name) { |
|
128 | // @codeCoverageIgnoreEnd |
||
129 | |||
130 | /****************** |
||
131 | * Internal |
||
132 | *****************/ |
||
133 | |||
134 | /** |
||
135 | * Returns the item from the internal array if |
||
136 | * if the index exists and is an DOMElement |
||
137 | * |
||
138 | * @param array|\Traversable |
||
139 | * @return NULL|\DOMElement |
||
140 | */ |
||
141 | 4 | private function getFirstElement() { |
|
149 | |||
150 | /** |
||
151 | * Wrap $content around a set of elements |
||
152 | * |
||
153 | * @param array $elements |
||
154 | * @param string|array|\DOMNode|\Traversable|callable $content |
||
155 | * @return array |
||
156 | * @throws \FluentDOM\Exceptions\LoadingError\EmptyResult |
||
157 | * @throws \InvalidArgumentException |
||
158 | */ |
||
159 | 8 | private function wrapNodes(array $elements, $content): array { |
|
193 | |||
194 | /********************* |
||
195 | * Core |
||
196 | ********************/ |
||
197 | |||
198 | /** |
||
199 | * @param \DOMNode $node |
||
200 | * @return Nodes\Modifier |
||
201 | */ |
||
202 | 32 | private function modify(\DOMNode $node): Nodes\Modifier { |
|
205 | |||
206 | /** |
||
207 | * @return Nodes\Builder |
||
208 | */ |
||
209 | 57 | private function build(): Nodes\Builder { |
|
215 | |||
216 | /** |
||
217 | * Use a handler callback to apply a content argument to each node $targetNodes. The content |
||
218 | * argument can be an easy setter function |
||
219 | * |
||
220 | * @param array|\DOMNodeList $targetNodes |
||
221 | * @param string|array|\DOMNode|\DOMNodeList|\Traversable|callable $content |
||
222 | * @param callable $handler |
||
223 | * @return array |
||
224 | * @throws \FluentDOM\Exceptions\LoadingError\EmptyResult |
||
225 | * @throws \InvalidArgumentException |
||
226 | */ |
||
227 | 21 | private function apply($targetNodes, $content, callable $handler): array { |
|
251 | |||
252 | /** |
||
253 | * Apply the content to the target nodes using the handler callback |
||
254 | * and push them into a spawned Query object. |
||
255 | * |
||
256 | * @param array|\DOMNodeList $targetNodes |
||
257 | * @param string|array|\DOMNode|\DOMNodeList|\Traversable|callable $content |
||
258 | * @param callable $handler |
||
259 | * @param bool $remove Call remove() on $this, remove the current selection from the DOM |
||
260 | * @return Query |
||
261 | */ |
||
262 | 19 | private function applyToSpawn($targetNodes, $content, callable $handler, bool $remove = FALSE): Query { |
|
271 | |||
272 | /** |
||
273 | * Apply the handler the $handler to nodes defined by selector, using |
||
274 | * the currently selected nodes as context. |
||
275 | * |
||
276 | * @param string|array|\DOMNode|\Traversable $selector |
||
277 | * @param callable $handler |
||
278 | * @param bool $remove Call remove() on $this, remove the current selection from the DOM |
||
279 | * @return Query |
||
280 | */ |
||
281 | 4 | private function applyToSelector($selector, callable $handler, bool $remove = FALSE): Query { |
|
289 | |||
290 | /********************* |
||
291 | * Traversing |
||
292 | ********************/ |
||
293 | |||
294 | /** |
||
295 | * Adds more elements, matched by the given expression, to the set of matched elements. |
||
296 | * |
||
297 | * @example add.php Usage Examples: FluentDOM::add() |
||
298 | * @param string|\Traversable|array $selector selector |
||
299 | * @param array|\Traversable $context |
||
300 | * @return Query |
||
301 | * @throws \FluentDOM\Exceptions\LoadingError\EmptyResult |
||
302 | * @throws \OutOfBoundsException |
||
303 | * @throws \InvalidArgumentException |
||
304 | */ |
||
305 | 7 | public function add($selector, $context = NULL) { |
|
320 | |||
321 | /** |
||
322 | * Add the previous selection to the current selection. |
||
323 | * |
||
324 | * @return Query |
||
325 | * @throws \OutOfBoundsException |
||
326 | * @throws \InvalidArgumentException |
||
327 | */ |
||
328 | 1 | public function addBack(): Query { |
|
331 | |||
332 | /** |
||
333 | * Get a set of elements containing of the unique immediate |
||
334 | * child nodes including only elements (not text nodes) of each |
||
335 | * of the matched set of elements. |
||
336 | * |
||
337 | * @example children.php Usage Examples: FluentDOM\Query::children() |
||
338 | * @param string $selector selector |
||
339 | * @return Query|Nodes |
||
340 | * @throws \OutOfBoundsException |
||
341 | * @throws \LogicException |
||
342 | * @throws \InvalidArgumentException |
||
343 | */ |
||
344 | 2 | public function children($selector = NULL): Query { |
|
347 | |||
348 | /** |
||
349 | * Get a set of elements containing the closest parent element that matches the specified |
||
350 | * selector, the starting element included. |
||
351 | * |
||
352 | * @example closest.php Usage Example: FluentDOM\Query::closest() |
||
353 | * @param string $selector selector |
||
354 | * @param array|\Traversable $context |
||
355 | * @return Query|Nodes |
||
356 | * @throws \OutOfBoundsException |
||
357 | * @throws \LogicException |
||
358 | * @throws \InvalidArgumentException |
||
359 | */ |
||
360 | 4 | public function closest($selector, $context = NULL): Query { |
|
369 | |||
370 | /** |
||
371 | * Get a set of elements containing all of the unique immediate |
||
372 | * child nodes including elements and text nodes of each of the matched set of elements. |
||
373 | * |
||
374 | * @return Query|Nodes |
||
375 | * @throws \OutOfBoundsException |
||
376 | * @throws \LogicException |
||
377 | * @throws \InvalidArgumentException |
||
378 | */ |
||
379 | 1 | public function contents(): Query { |
|
387 | |||
388 | /** |
||
389 | * Reduce the set of matched elements to a single element. |
||
390 | * |
||
391 | * @example eq.php Usage Example: FluentDOM\Query::eq() |
||
392 | * @param int $position Element index (start with 0) |
||
393 | * @return Query |
||
394 | * @throws \OutOfBoundsException |
||
395 | * @throws \InvalidArgumentException |
||
396 | */ |
||
397 | 2 | public function eq(int $position): Query { |
|
407 | |||
408 | /** |
||
409 | * Removes all elements from the set of matched elements that do not match |
||
410 | * the specified expression(s). |
||
411 | * |
||
412 | * @example filter-expr.php Usage Example: FluentDOM\Query::filter() with selector |
||
413 | * @example filter-fn.php Usage Example: FluentDOM\Query::filter() with Closure |
||
414 | * @param string|callable $selector selector or callback function |
||
415 | * @return Query |
||
416 | * @throws \OutOfBoundsException |
||
417 | * @throws \InvalidArgumentException |
||
418 | */ |
||
419 | 2 | public function filter($selector): Query { |
|
429 | |||
430 | /** |
||
431 | * Get a set of elements containing only the first of the currently selected elements. |
||
432 | * |
||
433 | * @return Query |
||
434 | * @throws \OutOfBoundsException |
||
435 | * @throws \InvalidArgumentException |
||
436 | */ |
||
437 | 1 | public function first(): Query { |
|
440 | |||
441 | /** |
||
442 | * Retrieve the matched DOM elements in an array. A negative position will be counted from the end. |
||
443 | * |
||
444 | * @param int|NULL optional offset of a single element to get. |
||
445 | * @return array|\DOMNode|NULL |
||
446 | */ |
||
447 | 4 | public function get(int $position = NULL) { |
|
459 | |||
460 | /** |
||
461 | * Reduce the set of matched elements to those that have |
||
462 | * a descendant that matches the selector or DOM element. |
||
463 | * |
||
464 | * @param string|\DOMNode $selector selector or DOMNode |
||
465 | * @return Query |
||
466 | * @throws \OutOfBoundsException |
||
467 | * @throws \InvalidArgumentException |
||
468 | */ |
||
469 | 2 | public function has($selector): Query { |
|
486 | |||
487 | /** |
||
488 | * Checks the current selection against an expression and returns TRUE, |
||
489 | * if at least one element of the selection fits the given expression. |
||
490 | * |
||
491 | * @example is.php Usage Example: FluentDOM\Query::is() |
||
492 | * @param string $selector selector |
||
493 | * @return bool |
||
494 | */ |
||
495 | 2 | public function is(string $selector): bool { |
|
503 | |||
504 | /** |
||
505 | * Get a set of elements containing only the last of the currently selected elements. |
||
506 | * |
||
507 | * @return Query |
||
508 | * @throws \OutOfBoundsException |
||
509 | * @throws \InvalidArgumentException |
||
510 | */ |
||
511 | 1 | public function last(): Query { |
|
514 | |||
515 | /** |
||
516 | * Translate a set of elements in the FluentDOM\Query object into |
||
517 | * another set of values in an array (which may, or may not contain elements). |
||
518 | * |
||
519 | * If the callback function returns an array each element of the array will be added to the |
||
520 | * result array. All other variable types are put directly into the result array. |
||
521 | * |
||
522 | * @example map.php Usage Example: FluentDOM\Query::map() |
||
523 | * @param callable $function |
||
524 | * @return array |
||
525 | */ |
||
526 | 2 | public function map(callable $function): array { |
|
545 | |||
546 | /** |
||
547 | * Removes elements matching the specified expression from the set of matched elements. |
||
548 | * |
||
549 | * @example not.php Usage Example: FluentDOM\Query::not() |
||
550 | * @param string|callback $selector selector or callback function |
||
551 | * @return Query |
||
552 | * @throws \OutOfBoundsException |
||
553 | * @throws \InvalidArgumentException |
||
554 | */ |
||
555 | 2 | public function not($selector): Query { |
|
563 | |||
564 | /** |
||
565 | * Get a set of elements containing the unique next siblings of each of the |
||
566 | * given set of elements. |
||
567 | * |
||
568 | * @example next.php Usage Example: FluentDOM\Query::next() |
||
569 | * @param string $selector |
||
570 | * @return Query|Nodes |
||
571 | * @throws \OutOfBoundsException |
||
572 | * @throws \LogicException |
||
573 | * @throws \InvalidArgumentException |
||
574 | */ |
||
575 | 1 | public function next($selector = NULL): Query { |
|
585 | |||
586 | /** |
||
587 | * Find all sibling elements after the current element. |
||
588 | * |
||
589 | * @example nextAll.php Usage Example: FluentDOM\Query::nextAll() |
||
590 | * @param string $selector selector |
||
591 | * @return Query|Nodes |
||
592 | * @throws \OutOfBoundsException |
||
593 | * @throws \LogicException |
||
594 | * @throws \InvalidArgumentException |
||
595 | */ |
||
596 | 1 | public function nextAll($selector = NULL): Query { |
|
602 | |||
603 | /** |
||
604 | * Get all following siblings of each element up to but |
||
605 | * not including the element matched by the selector. |
||
606 | * |
||
607 | * @param string $selector selector |
||
608 | * @param string $filter selector |
||
609 | * @return Query|Nodes |
||
610 | * @throws \OutOfBoundsException |
||
611 | * @throws \LogicException |
||
612 | * @throws \InvalidArgumentException |
||
613 | */ |
||
614 | 1 | public function nextUntil($selector = NULL, $filter = NULL): Query { |
|
621 | |||
622 | /** |
||
623 | * Get a set of elements containing the unique parents of the matched set of elements. |
||
624 | * |
||
625 | * @example parent.php Usage Example: FluentDOM\Query::parent() |
||
626 | * @return Query|Nodes |
||
627 | * @throws \OutOfBoundsException |
||
628 | * @throws \LogicException |
||
629 | * @throws \InvalidArgumentException |
||
630 | */ |
||
631 | 1 | public function parent(): Query { |
|
634 | |||
635 | /** |
||
636 | * Get the ancestors of each element in the current set of matched elements, |
||
637 | * optionally filtered by a selector. |
||
638 | * |
||
639 | * @example parents.php Usage Example: FluentDOM\Query::parents() |
||
640 | * @param string $selector selector |
||
641 | * @return Query|Nodes |
||
642 | * @throws \LogicException |
||
643 | * @throws \OutOfBoundsException |
||
644 | * @throws \InvalidArgumentException |
||
645 | */ |
||
646 | 1 | public function parents($selector = NULL): Query { |
|
649 | |||
650 | /** |
||
651 | * Get the ancestors of each element in the current set of matched elements, |
||
652 | * up to but not including the element matched by the selector. |
||
653 | * |
||
654 | * @param string $stopAt selector |
||
655 | * @param string $filter selector |
||
656 | * @return Query|Nodes |
||
657 | * @throws \OutOfBoundsException |
||
658 | * @throws \LogicException |
||
659 | * @throws \InvalidArgumentException |
||
660 | */ |
||
661 | 1 | public function parentsUntil($stopAt = NULL, $filter = NULL): Query { |
|
664 | |||
665 | /** |
||
666 | * Get a set of elements containing the unique previous siblings of each of the |
||
667 | * matched set of elements. |
||
668 | * |
||
669 | * @example prev.php Usage Example: FluentDOM\Query::prev() |
||
670 | * @param string $selector selector |
||
671 | * @return Query|Nodes |
||
672 | * @throws \OutOfBoundsException |
||
673 | * @throws \LogicException |
||
674 | * @throws \InvalidArgumentException |
||
675 | */ |
||
676 | 2 | public function prev($selector = NULL): Query { |
|
686 | |||
687 | /** |
||
688 | * Find all sibling elements in front of the current element. |
||
689 | * |
||
690 | * @example prevAll.php Usage Example: FluentDOM\Query::prevAll() |
||
691 | * @param string $selector selector |
||
692 | * @return Query|Nodes |
||
693 | * @throws \OutOfBoundsException |
||
694 | * @throws \LogicException |
||
695 | * @throws \InvalidArgumentException |
||
696 | */ |
||
697 | 1 | public function prevAll($selector = NULL): Query { |
|
705 | |||
706 | /** |
||
707 | * Get all preceding siblings of each element up to but not including |
||
708 | * the element matched by the selector. |
||
709 | * |
||
710 | * @param string $selector selector |
||
711 | * @param string $filter selector |
||
712 | * @return Query|Nodes |
||
713 | * @throws \OutOfBoundsException |
||
714 | * @throws \LogicException |
||
715 | * @throws \InvalidArgumentException |
||
716 | */ |
||
717 | 1 | public function prevUntil($selector = NULL, $filter = NULL): Query { |
|
725 | |||
726 | |||
727 | /** |
||
728 | * Reverse the order of the matched elements. |
||
729 | * |
||
730 | * @return Query |
||
731 | * @throws \OutOfBoundsException |
||
732 | * @throws \InvalidArgumentException |
||
733 | */ |
||
734 | 1 | public function reverse(): Query { |
|
737 | |||
738 | /** |
||
739 | * Get a set of elements containing all of the unique siblings of each of the |
||
740 | * matched set of elements. |
||
741 | * |
||
742 | * @example siblings.php Usage Example: FluentDOM\Query::siblings() |
||
743 | * @param string $selector selector |
||
744 | * @return Query|Nodes |
||
745 | * @throws \OutOfBoundsException |
||
746 | * @throws \LogicException |
||
747 | * @throws \InvalidArgumentException |
||
748 | */ |
||
749 | 1 | public function siblings($selector = NULL): Query { |
|
760 | |||
761 | /** |
||
762 | * Selects a subset of the matched elements. |
||
763 | * |
||
764 | * @example slice.php Usage Example: FluentDOM\Query::slice() |
||
765 | * @param int $start |
||
766 | * @param int $end |
||
767 | * @return Query |
||
768 | * @throws \OutOfBoundsException |
||
769 | * @throws \InvalidArgumentException |
||
770 | */ |
||
771 | 4 | public function slice(int $start, int $end = NULL): Query { |
|
784 | |||
785 | /********************* |
||
786 | * Manipulation |
||
787 | ********************/ |
||
788 | |||
789 | /** |
||
790 | * Insert content after each of the matched elements. |
||
791 | * |
||
792 | * @example after.php Usage Example: FluentDOM\Query::after() |
||
793 | * @param string|array|\DOMNode|\DOMNodeList|\Traversable|callable $content |
||
794 | * @return Query |
||
795 | */ |
||
796 | 2 | public function after($content): Query { |
|
805 | |||
806 | /** |
||
807 | * Append content to the inside of every matched element. |
||
808 | * |
||
809 | * @example append.php Usage Example: FluentDOM\Query::append() |
||
810 | * @param string|array|\DOMNode|\Traversable|callable $content DOMNode or DOMNodeList or xml fragment string |
||
811 | * @return Query |
||
812 | * @throws \InvalidArgumentException |
||
813 | * @throws \FluentDOM\Exceptions\LoadingError\EmptyResult |
||
814 | * @throws \LogicException |
||
815 | */ |
||
816 | 14 | public function append($content): Query { |
|
836 | |||
837 | /** |
||
838 | * Append all of the matched elements to another, specified, set of elements. |
||
839 | * Returns all of the inserted elements. |
||
840 | * |
||
841 | * @example appendTo.php Usage Example: FluentDOM\Query::appendTo() |
||
842 | * @param string|array|\DOMNode|\DOMNodeList|Query $selector |
||
843 | * @return Query |
||
844 | */ |
||
845 | 2 | public function appendTo($selector): Query { |
|
854 | |||
855 | /** |
||
856 | * Insert content before each of the matched elements. |
||
857 | * |
||
858 | * @example before.php Usage Example: FluentDOM\Query::before() |
||
859 | * @param string|array|\DOMNode|\Traversable|callable $content |
||
860 | * @return Query |
||
861 | */ |
||
862 | 2 | public function before($content): Query { |
|
871 | |||
872 | /** |
||
873 | * Clone matched DOM Elements and select the clones. |
||
874 | * |
||
875 | * @example clone.php Usage Example: FluentDOM\Query:clone() |
||
876 | * @return Query |
||
877 | * @throws \OutOfBoundsException |
||
878 | * @throws \InvalidArgumentException |
||
879 | */ |
||
880 | public function clone(): Query { |
||
888 | |||
889 | /** |
||
890 | * Remove all child nodes from the set of matched elements. |
||
891 | * |
||
892 | * @example empty.php Usage Example: FluentDOM\Query:empty() |
||
893 | * @return Query |
||
894 | * @throws \InvalidArgumentException |
||
895 | */ |
||
896 | public function empty(): Query { |
||
905 | |||
906 | /** |
||
907 | * Insert all of the matched elements after another, specified, set of elements. |
||
908 | * |
||
909 | * @example insertAfter.php Usage Example: FluentDOM\Query::insertAfter() |
||
910 | * @param string|array|\DOMNode|\Traversable $selector |
||
911 | * @return Query |
||
912 | * @throws \InvalidArgumentException |
||
913 | */ |
||
914 | 1 | public function insertAfter($selector): Query { |
|
924 | |||
925 | /** |
||
926 | * Insert all of the matched elements before another, specified, set of elements. |
||
927 | * |
||
928 | * @example insertBefore.php Usage Example: FluentDOM\Query::insertBefore() |
||
929 | * @param string|array|\DOMNode|\Traversable $selector |
||
930 | * @return Query |
||
931 | */ |
||
932 | 1 | public function insertBefore($selector): Query { |
|
941 | |||
942 | /** |
||
943 | * Prepend content to the inside of every matched element. |
||
944 | * |
||
945 | * @example prepend.php Usage Example: FluentDOM\Query::prepend() |
||
946 | * @param string|array|\DOMNode|\Traversable $content |
||
947 | * @return Query |
||
948 | */ |
||
949 | 3 | public function prepend($content): Query { |
|
958 | |||
959 | /** |
||
960 | * Prepend all of the matched elements to another, specified, set of elements. |
||
961 | * Returns all of the inserted elements. |
||
962 | * |
||
963 | * @example prependTo.php Usage Example: FluentDOM\Query::prependTo() |
||
964 | * @param string|array|\DOMNode|\DOMNodeList|Query $selector |
||
965 | * @return Query list of all new elements |
||
966 | */ |
||
967 | 1 | public function prependTo($selector): Query { |
|
976 | |||
977 | /** |
||
978 | * Replaces the elements matched by the specified selector with the matched elements. |
||
979 | * |
||
980 | * @example replaceAll.php Usage Example: FluentDOM\Query::replaceAll() |
||
981 | * @param string|array|\DOMNode|\Traversable $selector |
||
982 | * @return Query |
||
983 | * @throws \InvalidArgumentException |
||
984 | */ |
||
985 | 3 | public function replaceAll($selector): Query { |
|
998 | |||
999 | /** |
||
1000 | * Replaces all matched elements with the specified HTML or DOM elements. |
||
1001 | * This returns the element that was just replaced, |
||
1002 | * which has been removed from the DOM. |
||
1003 | * |
||
1004 | * @example replaceWith.php Usage Example: FluentDOM\Query::replaceWith() |
||
1005 | * @param string|array|\DOMNode|\Traversable|callable $content |
||
1006 | * @return Query |
||
1007 | * @throws \InvalidArgumentException |
||
1008 | * @throws \FluentDOM\Exceptions\LoadingError\EmptyResult |
||
1009 | */ |
||
1010 | 2 | public function replaceWith($content): Query { |
|
1021 | |||
1022 | /** |
||
1023 | * Removes all matched elements from the DOM. |
||
1024 | * |
||
1025 | * @example remove.php Usage Example: FluentDOM\Query::remove() |
||
1026 | * @param string $selector selector |
||
1027 | * @return Query removed elements |
||
1028 | * @throws \OutOfBoundsException |
||
1029 | * @throws \InvalidArgumentException |
||
1030 | */ |
||
1031 | 11 | public function remove(string $selector = NULL): Query { |
|
1042 | |||
1043 | /** |
||
1044 | * Get the combined text contents of all matched elements or |
||
1045 | * set the text contents of all matched elements. |
||
1046 | * |
||
1047 | * @example text.php Usage Example: FluentDOM\Query::text() |
||
1048 | * @param string|callable $text |
||
1049 | * @return string|Query |
||
1050 | * @throws \InvalidArgumentException |
||
1051 | */ |
||
1052 | 3 | public function text($text = NULL) { |
|
1066 | |||
1067 | /** |
||
1068 | * Wrap each matched element with the specified content. |
||
1069 | * |
||
1070 | * If $content contains several elements the first one is used |
||
1071 | * |
||
1072 | * @example wrap.php Usage Example: FluentDOM\Query::wrap() |
||
1073 | * @param string|array|\DOMNode|\Traversable|callable $content |
||
1074 | * @return Query |
||
1075 | */ |
||
1076 | 6 | public function wrap($content): Query { |
|
1079 | |||
1080 | /** |
||
1081 | * Wrap al matched elements with the specified content |
||
1082 | * |
||
1083 | * If the matched elements are not siblings, wrap each group of siblings. |
||
1084 | * |
||
1085 | * @example wrapAll.php Usage Example: FluentDOM::wrapAll() |
||
1086 | * @param string|array|\DOMNode|\Traversable $content |
||
1087 | * @return Query |
||
1088 | * @throws \FluentDOM\Exceptions\LoadingError\EmptyResult |
||
1089 | * @throws \OutOfBoundsException |
||
1090 | * @throws \InvalidArgumentException |
||
1091 | */ |
||
1092 | 2 | public function wrapAll($content): Query { |
|
1103 | |||
1104 | /** |
||
1105 | * group selected elements by previous node - ignore whitespace text nodes |
||
1106 | * |
||
1107 | * @return array|bool |
||
1108 | */ |
||
1109 | 2 | private function getGroupedNodes() { |
|
1126 | |||
1127 | /** |
||
1128 | * Wrap grouped nodes |
||
1129 | * |
||
1130 | * @param array $groups |
||
1131 | * @param \DOMElement $template |
||
1132 | * @return array |
||
1133 | */ |
||
1134 | 2 | private function wrapGroupedNodes(array $groups, \DOMElement $template): array { |
|
1159 | |||
1160 | /** |
||
1161 | * Wrap the inner child contents of each matched element |
||
1162 | * (including text nodes) with an XML structure. |
||
1163 | * |
||
1164 | * @example wrapInner.php Usage Example: FluentDOM\Query::wrapInner() |
||
1165 | * @param string|array|\DOMNode|\Traversable $content |
||
1166 | * @return Query |
||
1167 | */ |
||
1168 | 2 | public function wrapInner($content): Query { |
|
1179 | |||
1180 | /** |
||
1181 | * Get xml contents of the first matched element or set the |
||
1182 | * xml contents of all selected element nodes. |
||
1183 | * |
||
1184 | * @example xml.php Usage Example: FluentDOM::xml() |
||
1185 | * @param string|callable|NULL $xml XML fragment |
||
1186 | * @return string|$this |
||
1187 | * @throws \InvalidArgumentException |
||
1188 | * @throws \FluentDOM\Exceptions\InvalidFragmentLoader |
||
1189 | * @throws \UnexpectedValueException |
||
1190 | * @throws \LogicException |
||
1191 | */ |
||
1192 | 7 | public function xml($xml = NULL) { |
|
1206 | |||
1207 | /** |
||
1208 | * Get the first matched node as XML or replace each |
||
1209 | * matched nodes with the provided fragment. |
||
1210 | * |
||
1211 | * @param string|callable|NULL $xml |
||
1212 | * @return string|$this |
||
1213 | * @throws \LogicException |
||
1214 | * @throws \UnexpectedValueException |
||
1215 | * @throws \InvalidArgumentException |
||
1216 | * @throws \FluentDOM\Exceptions\InvalidFragmentLoader |
||
1217 | */ |
||
1218 | 7 | View Code Duplication | public function outerXml($xml = NULL) { |
1229 | |||
1230 | /** |
||
1231 | * Get the first matched node as HTML or replace each |
||
1232 | * matched nodes with the provided fragment. |
||
1233 | * |
||
1234 | * @param string|callable|NULL $html |
||
1235 | * @return string|$this |
||
1236 | * @throws \LogicException |
||
1237 | * @throws \UnexpectedValueException |
||
1238 | * @throws \InvalidArgumentException |
||
1239 | * @throws \FluentDOM\Exceptions\InvalidFragmentLoader |
||
1240 | */ |
||
1241 | 7 | View Code Duplication | public function outerHtml($html = NULL) { |
1252 | |||
1253 | /** |
||
1254 | * Get html contents of the first matched element or set the |
||
1255 | * html contents of all selected element nodes. |
||
1256 | * |
||
1257 | * @param string|callable|NULL $html |
||
1258 | * @return string|$this |
||
1259 | * @throws \LogicException |
||
1260 | * @throws \UnexpectedValueException |
||
1261 | * @throws \InvalidArgumentException |
||
1262 | * @throws \FluentDOM\Exceptions\InvalidFragmentLoader |
||
1263 | */ |
||
1264 | 4 | public function html($html = NULL) { |
|
1282 | |||
1283 | /** |
||
1284 | * @param string|callable|NULL $content |
||
1285 | * @param callable $export |
||
1286 | * @param callable $import |
||
1287 | * @param callable $insert |
||
1288 | * @return string|$this |
||
1289 | * @throws \InvalidArgumentException |
||
1290 | */ |
||
1291 | 25 | private function content($content, callable $export, callable $import, callable $insert) { |
|
1312 | |||
1313 | /** |
||
1314 | * @param string|callable|NULL $content |
||
1315 | * @param callable $export |
||
1316 | * @param callable $import |
||
1317 | * @return $this|string |
||
1318 | * @throws \InvalidArgumentException |
||
1319 | */ |
||
1320 | 14 | private function outerContent($content, callable $export, callable $import) { |
|
1330 | |||
1331 | /**************************** |
||
1332 | * Manipulation - Attributes |
||
1333 | ***************************/ |
||
1334 | |||
1335 | /** |
||
1336 | * @param string|array|NULL $names |
||
1337 | * @throws \InvalidArgumentException |
||
1338 | * @return array|NULL |
||
1339 | */ |
||
1340 | 8 | private function getNamesList($names) { |
|
1352 | |||
1353 | /** |
||
1354 | * @param string|array|\Traversable $name |
||
1355 | * @param string|float|int|NULL|callable $value |
||
1356 | * @return array|\Traversable |
||
1357 | * @throws \InvalidArgumentException |
||
1358 | */ |
||
1359 | 20 | private function getSetterValues($name, $value) { |
|
1368 | |||
1369 | /** |
||
1370 | * Access a property on the first matched element or set the attribute(s) of all matched elements |
||
1371 | * |
||
1372 | * @example attr.php Usage Example: FluentDOM\Query::attr() Read an attribute value. |
||
1373 | * @param string|array $attribute attribute name or attribute list |
||
1374 | * @param array ...$arguments |
||
1375 | * @return $this|string attribute value or $this |
||
1376 | * @throws \InvalidArgumentException |
||
1377 | */ |
||
1378 | 18 | public function attr($attribute, ...$arguments) { |
|
1408 | |||
1409 | /** |
||
1410 | * Returns TRUE if the specified attribute is present on at least one of |
||
1411 | * the set of matched elements. |
||
1412 | * |
||
1413 | * @param string $name |
||
1414 | * @return bool |
||
1415 | */ |
||
1416 | 3 | public function hasAttr($name) { |
|
1424 | |||
1425 | /** |
||
1426 | * Remove an attribute from each of the matched elements. If $name is NULL or *, |
||
1427 | * all attributes will be deleted. |
||
1428 | * |
||
1429 | * @example removeAttr.php Usage Example: FluentDOM\Query::removeAttr() |
||
1430 | * @param string|array $name |
||
1431 | * @throws \InvalidArgumentException |
||
1432 | * @return $this|Query |
||
1433 | */ |
||
1434 | 4 | public function removeAttr($name): Query { |
|
1450 | |||
1451 | /************************* |
||
1452 | * Manipulation - Classes |
||
1453 | ************************/ |
||
1454 | |||
1455 | /** |
||
1456 | * Adds the specified class(es) to each of the set of matched elements. |
||
1457 | * |
||
1458 | * @param string|callable $class |
||
1459 | * @return Query |
||
1460 | */ |
||
1461 | 1 | public function addClass($class) { |
|
1464 | |||
1465 | /** |
||
1466 | * Returns TRUE if the specified class is present on at least one of the set of matched elements. |
||
1467 | * |
||
1468 | * @param string $class |
||
1469 | * @return bool |
||
1470 | */ |
||
1471 | 2 | public function hasClass(string $class): bool { |
|
1482 | |||
1483 | /** |
||
1484 | * Removes all or the specified class(es) from the set of matched elements. |
||
1485 | * |
||
1486 | * @param string|callable $class |
||
1487 | * @return $this|Query |
||
1488 | * @throws \InvalidArgumentException |
||
1489 | */ |
||
1490 | 2 | public function removeClass($class = ''): Query { |
|
1493 | |||
1494 | /** |
||
1495 | * Adds the specified classes if the switch is TRUE, |
||
1496 | * removes the specified classes if the switch is FALSE, |
||
1497 | * toggles the specified classes if the switch is NULL. |
||
1498 | * |
||
1499 | * @example toggleClass.php Usage Example: FluentDOM\Query::toggleClass() |
||
1500 | * @param string|callable $class |
||
1501 | * @param NULL|bool $switch toggle if NULL, add if TRUE, remove if FALSE |
||
1502 | * @return $this|Query |
||
1503 | * @throws \InvalidArgumentException |
||
1504 | */ |
||
1505 | 6 | public function toggleClass($class, bool $switch = NULL): Query { |
|
1533 | |||
1534 | /** |
||
1535 | * Change a class string |
||
1536 | * |
||
1537 | * Adds the specified classes if the switch is TRUE, |
||
1538 | * removes the specified classes if the switch is FALSE, |
||
1539 | * toggles the specified classes if the switch is NULL. |
||
1540 | * |
||
1541 | * @param string $current |
||
1542 | * @param string $toggle |
||
1543 | * @param bool|NULL $switch |
||
1544 | * @return FALSE|string |
||
1545 | */ |
||
1546 | 5 | private function changeClassString(string $current, string $toggle, bool $switch = NULL) { |
|
1570 | |||
1571 | /************************************* |
||
1572 | * Manipulation - CSS Style Attribute |
||
1573 | ************************************/ |
||
1574 | |||
1575 | /** |
||
1576 | * get or set CSS values in style attributes |
||
1577 | * |
||
1578 | * @param string|array $property |
||
1579 | * @param array ...$arguments |
||
1580 | * @throws \InvalidArgumentException |
||
1581 | * @return string|NULL|$this |
||
1582 | */ |
||
1583 | 16 | public function css($property, ...$arguments) { |
|
1611 | |||
1612 | /********************************* |
||
1613 | * Manipulation - Data Attributes |
||
1614 | ********************************/ |
||
1615 | |||
1616 | /** |
||
1617 | * Read a data attribute from the first node or set data attributes on all selected nodes. |
||
1618 | * |
||
1619 | * @example data.php Usage Example: FluentDOM\Query::data() |
||
1620 | * @param string|array $name data attribute identifier or array of data attributes to set |
||
1621 | * @param [mixed] ...$arguments |
||
1622 | * @return mixed |
||
1623 | * @throws \InvalidArgumentException |
||
1624 | */ |
||
1625 | 5 | public function data($name, ...$arguments) { |
|
1644 | |||
1645 | /** |
||
1646 | * Remove an data - attribute from each of the matched elements. If $name is NULL or *, |
||
1647 | * all data attributes will be deleted. |
||
1648 | * |
||
1649 | * @example removeData.php Usage Example: FluentDOM\Query::removeData() |
||
1650 | * @param string|array|NULL $name |
||
1651 | * @throws \InvalidArgumentException |
||
1652 | * @return Query |
||
1653 | */ |
||
1654 | 4 | public function removeData($name = NULL): Query { |
|
1673 | |||
1674 | /** |
||
1675 | * Validate if the element has an data attributes attached. If it is called without an |
||
1676 | * actual $element parameter, it will check the first matched node. |
||
1677 | * |
||
1678 | * @param \DOMElement|NULL $element |
||
1679 | * @return bool |
||
1680 | */ |
||
1681 | 5 | public function hasData(\DOMElement $element = NULL): bool { |
|
1688 | } |
||
1689 | } |