| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * HTML API: WP_HTML_Open_Elements class 4 * 5 * @package WordPress 6 * @subpackage HTML-API 7 * @since 6.4.0 8 */ 9 10 /** 11 * Core class used by the HTML processor during HTML parsing 12 * for managing the stack of open elements. 13 * 14 * This class is designed for internal use by the HTML processor. 15 * 16 * > Initially, the stack of open elements is empty. The stack grows 17 * > downwards; the topmost node on the stack is the first one added 18 * > to the stack, and the bottommost node of the stack is the most 19 * > recently added node in the stack (notwithstanding when the stack 20 * > is manipulated in a random access fashion as part of the handling 21 * > for misnested tags). 22 * 23 * @since 6.4.0 24 * 25 * @access private 26 * @ignore 27 * 28 * @see https://html.spec.whatwg.org/#stack-of-open-elements 29 * @see WP_HTML_Processor 30 */ 31 class WP_HTML_Open_Elements { 32 /** 33 * Holds the stack of open element references. 34 * 35 * @since 6.4.0 36 * 37 * @var WP_HTML_Token[] 38 */ 39 public $stack = array(); 40 41 /** 42 * Whether a P element is in button scope currently. 43 * 44 * This class optimizes scope lookup by pre-calculating 45 * this value when elements are added and removed to the 46 * stack of open elements which might change its value. 47 * This avoids frequent iteration over the stack. 48 * 49 * @since 6.4.0 50 * 51 * @var bool 52 */ 53 private $has_p_in_button_scope = false; 54 55 /** 56 * A function that will be called when an item is popped off the stack of open elements. 57 * 58 * The function will be called with the popped item as its argument. 59 * 60 * @since 6.6.0 61 * 62 * @var Closure|null 63 */ 64 private $pop_handler = null; 65 66 /** 67 * A function that will be called when an item is pushed onto the stack of open elements. 68 * 69 * The function will be called with the pushed item as its argument. 70 * 71 * @since 6.6.0 72 * 73 * @var Closure|null 74 */ 75 private $push_handler = null; 76 77 /** 78 * Sets a pop handler that will be called when an item is popped off the stack of 79 * open elements. 80 * 81 * The function will be called with the popped item as its argument. 82 * 83 * @since 6.6.0 84 * 85 * @param Closure $handler The handler function. 86 */ 87 public function set_pop_handler( Closure $handler ): void { 88 $this->pop_handler = $handler; 89 } 90 91 /** 92 * Sets a push handler that will be called when an item is pushed onto the stack of 93 * open elements. 94 * 95 * The function will be called with the pushed item as its argument. 96 * 97 * @since 6.6.0 98 * 99 * @param Closure $handler The handler function. 100 */ 101 public function set_push_handler( Closure $handler ): void { 102 $this->push_handler = $handler; 103 } 104 105 /** 106 * Returns the node at the nth position on the stack 107 * of open elements, or `null` if no such position exists. 108 * 109 * Note that this uses a 1-based index, which represents the 110 * "nth item" on the stack, counting from the top, where the 111 * top-most element is the 1st, the second is the 2nd, etc... 112 * 113 * @since 6.7.0 114 * 115 * @param int $nth Retrieve the nth item on the stack, with 1 being 116 * the top element, 2 being the second, etc... 117 * @return WP_HTML_Token|null The node on the stack at the given location, 118 * or `null` if the location isn't on the stack. 119 */ 120 public function at( int $nth ): ?WP_HTML_Token { 121 foreach ( $this->walk_down() as $item ) { 122 if ( 0 === --$nth ) { 123 return $item; 124 } 125 } 126 127 return null; 128 } 129 130 /** 131 * Reports if a node of a given name is in the stack of open elements. 132 * 133 * @since 6.7.0 134 * 135 * @param string $node_name Name of node for which to check. 136 * @return bool Whether a node of the given name is in the stack of open elements. 137 */ 138 public function contains( string $node_name ): bool { 139 foreach ( $this->walk_up() as $item ) { 140 if ( $node_name === $item->node_name ) { 141 return true; 142 } 143 } 144 145 return false; 146 } 147 148 /** 149 * Reports if a specific node is in the stack of open elements. 150 * 151 * @since 6.4.0 152 * 153 * @param WP_HTML_Token $token Look for this node in the stack. 154 * @return bool Whether the referenced node is in the stack of open elements. 155 */ 156 public function contains_node( WP_HTML_Token $token ): bool { 157 foreach ( $this->walk_up() as $item ) { 158 if ( $token === $item ) { 159 return true; 160 } 161 } 162 163 return false; 164 } 165 166 /** 167 * Returns how many nodes are currently in the stack of open elements. 168 * 169 * @since 6.4.0 170 * 171 * @return int How many nodes are in the stack of open elements. 172 */ 173 public function count(): int { 174 return count( $this->stack ); 175 } 176 177 /** 178 * Returns the node at the end of the stack of open elements, 179 * if one exists. If the stack is empty, returns null. 180 * 181 * @since 6.4.0 182 * 183 * @return WP_HTML_Token|null Last node in the stack of open elements, if one exists, otherwise null. 184 */ 185 public function current_node(): ?WP_HTML_Token { 186 $current_node = end( $this->stack ); 187 188 return $current_node ? $current_node : null; 189 } 190 191 /** 192 * Indicates if the current node is of a given type or name. 193 * 194 * It's possible to pass either a node type or a node name to this function. 195 * In the case there is no current element it will always return `false`. 196 * 197 * Example: 198 * 199 * // Is the current node a text node? 200 * $stack->current_node_is( '#text' ); 201 * 202 * // Is the current node a DIV element? 203 * $stack->current_node_is( 'DIV' ); 204 * 205 * // Is the current node any element/tag? 206 * $stack->current_node_is( '#tag' ); 207 * 208 * @see WP_HTML_Tag_Processor::get_token_type 209 * @see WP_HTML_Tag_Processor::get_token_name 210 * 211 * @since 6.7.0 212 * 213 * @access private 214 * 215 * @param string $identity Check if the current node has this name or type (depending on what is provided). 216 * @return bool Whether there is a current element that matches the given identity, whether a token name or type. 217 */ 218 public function current_node_is( string $identity ): bool { 219 $current_node = end( $this->stack ); 220 if ( false === $current_node ) { 221 return false; 222 } 223 224 $current_node_name = $current_node->node_name; 225 226 return ( 227 $current_node_name === $identity || 228 ( '#doctype' === $identity && 'html' === $current_node_name ) || 229 ( '#tag' === $identity && ctype_upper( $current_node_name ) ) 230 ); 231 } 232 233 /** 234 * Returns whether an element is in a specific scope. 235 * 236 * @since 6.4.0 237 * 238 * @see https://html.spec.whatwg.org/#has-an-element-in-the-specific-scope 239 * 240 * @param string $tag_name Name of tag check. 241 * @param string[] $termination_list List of elements that terminate the search. 242 * @return bool Whether the element was found in a specific scope. 243 */ 244 public function has_element_in_specific_scope( string $tag_name, $termination_list ): bool { 245 foreach ( $this->walk_up() as $node ) { 246 $namespaced_name = 'html' === $node->namespace 247 ? $node->node_name 248 : "{$node->namespace} {$node->node_name}"; 249 250 if ( $namespaced_name === $tag_name ) { 251 return true; 252 } 253 254 if ( 255 '(internal: H1 through H6 - do not use)' === $tag_name && 256 in_array( $namespaced_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) 257 ) { 258 return true; 259 } 260 261 if ( in_array( $namespaced_name, $termination_list, true ) ) { 262 return false; 263 } 264 } 265 266 return false; 267 } 268 269 /** 270 * Returns whether a particular element is in scope. 271 * 272 * > The stack of open elements is said to have a particular element in 273 * > scope when it has that element in the specific scope consisting of 274 * > the following element types: 275 * > 276 * > - applet 277 * > - caption 278 * > - html 279 * > - table 280 * > - td 281 * > - th 282 * > - marquee 283 * > - object 284 * > - template 285 * > - MathML mi 286 * > - MathML mo 287 * > - MathML mn 288 * > - MathML ms 289 * > - MathML mtext 290 * > - MathML annotation-xml 291 * > - SVG foreignObject 292 * > - SVG desc 293 * > - SVG title 294 * 295 * @since 6.4.0 296 * @since 6.7.0 Full support. 297 * 298 * @see https://html.spec.whatwg.org/#has-an-element-in-scope 299 * 300 * @param string $tag_name Name of tag to check. 301 * @return bool Whether given element is in scope. 302 */ 303 public function has_element_in_scope( string $tag_name ): bool { 304 return $this->has_element_in_specific_scope( 305 $tag_name, 306 array( 307 'APPLET', 308 'CAPTION', 309 'HTML', 310 'TABLE', 311 'TD', 312 'TH', 313 'MARQUEE', 314 'OBJECT', 315 'TEMPLATE', 316 317 'math MI', 318 'math MO', 319 'math MN', 320 'math MS', 321 'math MTEXT', 322 'math ANNOTATION-XML', 323 324 'svg FOREIGNOBJECT', 325 'svg DESC', 326 'svg TITLE', 327 ) 328 ); 329 } 330 331 /** 332 * Returns whether a particular element is in list item scope. 333 * 334 * > The stack of open elements is said to have a particular element 335 * > in list item scope when it has that element in the specific scope 336 * > consisting of the following element types: 337 * > 338 * > - All the element types listed above for the has an element in scope algorithm. 339 * > - ol in the HTML namespace 340 * > - ul in the HTML namespace 341 * 342 * @since 6.4.0 343 * @since 6.5.0 Implemented: no longer throws on every invocation. 344 * @since 6.7.0 Supports all required HTML elements. 345 * 346 * @see https://html.spec.whatwg.org/#has-an-element-in-list-item-scope 347 * 348 * @param string $tag_name Name of tag to check. 349 * @return bool Whether given element is in scope. 350 */ 351 public function has_element_in_list_item_scope( string $tag_name ): bool { 352 return $this->has_element_in_specific_scope( 353 $tag_name, 354 array( 355 'APPLET', 356 'BUTTON', 357 'CAPTION', 358 'HTML', 359 'TABLE', 360 'TD', 361 'TH', 362 'MARQUEE', 363 'OBJECT', 364 'OL', 365 'TEMPLATE', 366 'UL', 367 368 'math MI', 369 'math MO', 370 'math MN', 371 'math MS', 372 'math MTEXT', 373 'math ANNOTATION-XML', 374 375 'svg FOREIGNOBJECT', 376 'svg DESC', 377 'svg TITLE', 378 ) 379 ); 380 } 381 382 /** 383 * Returns whether a particular element is in button scope. 384 * 385 * > The stack of open elements is said to have a particular element 386 * > in button scope when it has that element in the specific scope 387 * > consisting of the following element types: 388 * > 389 * > - All the element types listed above for the has an element in scope algorithm. 390 * > - button in the HTML namespace 391 * 392 * @since 6.4.0 393 * @since 6.7.0 Supports all required HTML elements. 394 * 395 * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope 396 * 397 * @param string $tag_name Name of tag to check. 398 * @return bool Whether given element is in scope. 399 */ 400 public function has_element_in_button_scope( string $tag_name ): bool { 401 return $this->has_element_in_specific_scope( 402 $tag_name, 403 array( 404 'APPLET', 405 'BUTTON', 406 'CAPTION', 407 'HTML', 408 'TABLE', 409 'TD', 410 'TH', 411 'MARQUEE', 412 'OBJECT', 413 'TEMPLATE', 414 415 'math MI', 416 'math MO', 417 'math MN', 418 'math MS', 419 'math MTEXT', 420 'math ANNOTATION-XML', 421 422 'svg FOREIGNOBJECT', 423 'svg DESC', 424 'svg TITLE', 425 ) 426 ); 427 } 428 429 /** 430 * Returns whether a particular element is in table scope. 431 * 432 * > The stack of open elements is said to have a particular element 433 * > in table scope when it has that element in the specific scope 434 * > consisting of the following element types: 435 * > 436 * > - html in the HTML namespace 437 * > - table in the HTML namespace 438 * > - template in the HTML namespace 439 * 440 * @since 6.4.0 441 * @since 6.7.0 Full implementation. 442 * 443 * @see https://html.spec.whatwg.org/#has-an-element-in-table-scope 444 * 445 * @param string $tag_name Name of tag to check. 446 * @return bool Whether given element is in scope. 447 */ 448 public function has_element_in_table_scope( string $tag_name ): bool { 449 return $this->has_element_in_specific_scope( 450 $tag_name, 451 array( 452 'HTML', 453 'TABLE', 454 'TEMPLATE', 455 ) 456 ); 457 } 458 459 /** 460 * Returns whether a particular element is in select scope. 461 * 462 * This test differs from the others like it, in that its rules are inverted. 463 * Instead of arriving at a match when one of any tag in a termination group 464 * is reached, this one terminates if any other tag is reached. 465 * 466 * > The stack of open elements is said to have a particular element in select scope when it has 467 * > that element in the specific scope consisting of all element types except the following: 468 * > - optgroup in the HTML namespace 469 * > - option in the HTML namespace 470 * 471 * @since 6.4.0 Stub implementation (throws). 472 * @since 6.7.0 Full implementation. 473 * 474 * @see https://html.spec.whatwg.org/#has-an-element-in-select-scope 475 * 476 * @param string $tag_name Name of tag to check. 477 * @return bool Whether the given element is in SELECT scope. 478 */ 479 public function has_element_in_select_scope( string $tag_name ): bool { 480 foreach ( $this->walk_up() as $node ) { 481 if ( $node->node_name === $tag_name ) { 482 return true; 483 } 484 485 if ( 486 'OPTION' !== $node->node_name && 487 'OPTGROUP' !== $node->node_name 488 ) { 489 return false; 490 } 491 } 492 493 return false; 494 } 495 496 /** 497 * Returns whether a P is in BUTTON scope. 498 * 499 * @since 6.4.0 500 * 501 * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope 502 * 503 * @return bool Whether a P is in BUTTON scope. 504 */ 505 public function has_p_in_button_scope(): bool { 506 return $this->has_p_in_button_scope; 507 } 508 509 /** 510 * Pops a node off of the stack of open elements. 511 * 512 * @since 6.4.0 513 * 514 * @see https://html.spec.whatwg.org/#stack-of-open-elements 515 * 516 * @return bool Whether a node was popped off of the stack. 517 */ 518 public function pop(): bool { 519 $item = array_pop( $this->stack ); 520 if ( null === $item ) { 521 return false; 522 } 523 524 $this->after_element_pop( $item ); 525 return true; 526 } 527 528 /** 529 * Pops nodes off of the stack of open elements until an HTML tag with the given name has been popped. 530 * 531 * @since 6.4.0 532 * 533 * @see WP_HTML_Open_Elements::pop 534 * 535 * @param string $html_tag_name Name of tag that needs to be popped off of the stack of open elements. 536 * @return bool Whether a tag of the given name was found and popped off of the stack of open elements. 537 */ 538 public function pop_until( string $html_tag_name ): bool { 539 foreach ( $this->walk_up() as $item ) { 540 $this->pop(); 541 542 if ( 'html' !== $item->namespace ) { 543 continue; 544 } 545 546 if ( 547 '(internal: H1 through H6 - do not use)' === $html_tag_name && 548 in_array( $item->node_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) 549 ) { 550 return true; 551 } 552 553 if ( $html_tag_name === $item->node_name ) { 554 return true; 555 } 556 } 557 558 return false; 559 } 560 561 /** 562 * Pushes a node onto the stack of open elements. 563 * 564 * @since 6.4.0 565 * 566 * @see https://html.spec.whatwg.org/#stack-of-open-elements 567 * 568 * @param WP_HTML_Token $stack_item Item to add onto stack. 569 */ 570 public function push( WP_HTML_Token $stack_item ): void { 571 $this->stack[] = $stack_item; 572 $this->after_element_push( $stack_item ); 573 } 574 575 /** 576 * Removes a specific node from the stack of open elements. 577 * 578 * @since 6.4.0 579 * 580 * @param WP_HTML_Token $token The node to remove from the stack of open elements. 581 * @return bool Whether the node was found and removed from the stack of open elements. 582 */ 583 public function remove_node( WP_HTML_Token $token ): bool { 584 foreach ( $this->walk_up() as $position_from_end => $item ) { 585 if ( $token->bookmark_name !== $item->bookmark_name ) { 586 continue; 587 } 588 589 $position_from_start = $this->count() - $position_from_end - 1; 590 array_splice( $this->stack, $position_from_start, 1 ); 591 $this->after_element_pop( $item ); 592 return true; 593 } 594 595 return false; 596 } 597 598 599 /** 600 * Steps through the stack of open elements, starting with the top element 601 * (added first) and walking downwards to the one added last. 602 * 603 * This generator function is designed to be used inside a "foreach" loop. 604 * 605 * Example: 606 * 607 * $html = '<em><strong><a>We are here'; 608 * foreach ( $stack->walk_down() as $node ) { 609 * echo "{$node->node_name} -> "; 610 * } 611 * > EM -> STRONG -> A -> 612 * 613 * To start with the most-recently added element and walk towards the top, 614 * see WP_HTML_Open_Elements::walk_up(). 615 * 616 * @since 6.4.0 617 */ 618 public function walk_down() { 619 $count = count( $this->stack ); 620 621 for ( $i = 0; $i < $count; $i++ ) { 622 yield $this->stack[ $i ]; 623 } 624 } 625 626 /** 627 * Steps through the stack of open elements, starting with the bottom element 628 * (added last) and walking upwards to the one added first. 629 * 630 * This generator function is designed to be used inside a "foreach" loop. 631 * 632 * Example: 633 * 634 * $html = '<em><strong><a>We are here'; 635 * foreach ( $stack->walk_up() as $node ) { 636 * echo "{$node->node_name} -> "; 637 * } 638 * > A -> STRONG -> EM -> 639 * 640 * To start with the first added element and walk towards the bottom, 641 * see WP_HTML_Open_Elements::walk_down(). 642 * 643 * @since 6.4.0 644 * @since 6.5.0 Accepts $above_this_node to start traversal above a given node, if it exists. 645 * 646 * @param WP_HTML_Token|null $above_this_node Optional. Start traversing above this node, 647 * if provided and if the node exists. 648 */ 649 public function walk_up( ?WP_HTML_Token $above_this_node = null ) { 650 $has_found_node = null === $above_this_node; 651 652 for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) { 653 $node = $this->stack[ $i ]; 654 655 if ( ! $has_found_node ) { 656 $has_found_node = $node === $above_this_node; 657 continue; 658 } 659 660 yield $node; 661 } 662 } 663 664 /* 665 * Internal helpers. 666 */ 667 668 /** 669 * Updates internal flags after adding an element. 670 * 671 * Certain conditions (such as "has_p_in_button_scope") are maintained here as 672 * flags that are only modified when adding and removing elements. This allows 673 * the HTML Processor to quickly check for these conditions instead of iterating 674 * over the open stack elements upon each new tag it encounters. These flags, 675 * however, need to be maintained as items are added and removed from the stack. 676 * 677 * @since 6.4.0 678 * 679 * @param WP_HTML_Token $item Element that was added to the stack of open elements. 680 */ 681 public function after_element_push( WP_HTML_Token $item ): void { 682 $namespaced_name = 'html' === $item->namespace 683 ? $item->node_name 684 : "{$item->namespace} {$item->node_name}"; 685 686 /* 687 * When adding support for new elements, expand this switch to trap 688 * cases where the precalculated value needs to change. 689 */ 690 switch ( $namespaced_name ) { 691 case 'APPLET': 692 case 'BUTTON': 693 case 'CAPTION': 694 case 'HTML': 695 case 'TABLE': 696 case 'TD': 697 case 'TH': 698 case 'MARQUEE': 699 case 'OBJECT': 700 case 'TEMPLATE': 701 case 'math MI': 702 case 'math MO': 703 case 'math MN': 704 case 'math MS': 705 case 'math MTEXT': 706 case 'math ANNOTATION-XML': 707 case 'svg FOREIGNOBJECT': 708 case 'svg DESC': 709 case 'svg TITLE': 710 $this->has_p_in_button_scope = false; 711 break; 712 713 case 'P': 714 $this->has_p_in_button_scope = true; 715 break; 716 } 717 718 if ( null !== $this->push_handler ) { 719 call_user_func( $this->push_handler, $item ); 720 } 721 } 722 723 /** 724 * Updates internal flags after removing an element. 725 * 726 * Certain conditions (such as "has_p_in_button_scope") are maintained here as 727 * flags that are only modified when adding and removing elements. This allows 728 * the HTML Processor to quickly check for these conditions instead of iterating 729 * over the open stack elements upon each new tag it encounters. These flags, 730 * however, need to be maintained as items are added and removed from the stack. 731 * 732 * @since 6.4.0 733 * 734 * @param WP_HTML_Token $item Element that was removed from the stack of open elements. 735 */ 736 public function after_element_pop( WP_HTML_Token $item ): void { 737 /* 738 * When adding support for new elements, expand this switch to trap 739 * cases where the precalculated value needs to change. 740 */ 741 $namespaced_name = 'html' === $item->namespace 742 ? $item->node_name 743 : "{$item->namespace} {$item->node_name}"; 744 745 switch ( $namespaced_name ) { 746 case 'APPLET': 747 case 'BUTTON': 748 case 'CAPTION': 749 case 'HTML': 750 case 'P': 751 case 'TABLE': 752 case 'TD': 753 case 'TH': 754 case 'MARQUEE': 755 case 'OBJECT': 756 case 'TEMPLATE': 757 case 'math MI': 758 case 'math MO': 759 case 'math MN': 760 case 'math MS': 761 case 'math MTEXT': 762 case 'math ANNOTATION-XML': 763 case 'svg FOREIGNOBJECT': 764 case 'svg DESC': 765 case 'svg TITLE': 766 $this->has_p_in_button_scope = $this->has_element_in_button_scope( 'P' ); 767 break; 768 } 769 770 if ( null !== $this->pop_handler ) { 771 call_user_func( $this->pop_handler, $item ); 772 } 773 } 774 775 /** 776 * Clear the stack back to a table context. 777 * 778 * > When the steps above require the UA to clear the stack back to a table context, it means 779 * > that the UA must, while the current node is not a table, template, or html element, pop 780 * > elements from the stack of open elements. 781 * 782 * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-context 783 * 784 * @since 6.7.0 785 */ 786 public function clear_to_table_context(): void { 787 foreach ( $this->walk_up() as $item ) { 788 if ( 789 'TABLE' === $item->node_name || 790 'TEMPLATE' === $item->node_name || 791 'HTML' === $item->node_name 792 ) { 793 break; 794 } 795 $this->pop(); 796 } 797 } 798 799 /** 800 * Clear the stack back to a table body context. 801 * 802 * > When the steps above require the UA to clear the stack back to a table body context, it 803 * > means that the UA must, while the current node is not a tbody, tfoot, thead, template, or 804 * > html element, pop elements from the stack of open elements. 805 * 806 * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-body-context 807 * 808 * @since 6.7.0 809 */ 810 public function clear_to_table_body_context(): void { 811 foreach ( $this->walk_up() as $item ) { 812 if ( 813 'TBODY' === $item->node_name || 814 'TFOOT' === $item->node_name || 815 'THEAD' === $item->node_name || 816 'TEMPLATE' === $item->node_name || 817 'HTML' === $item->node_name 818 ) { 819 break; 820 } 821 $this->pop(); 822 } 823 } 824 825 /** 826 * Clear the stack back to a table row context. 827 * 828 * > When the steps above require the UA to clear the stack back to a table row context, it 829 * > means that the UA must, while the current node is not a tr, template, or html element, pop 830 * > elements from the stack of open elements. 831 * 832 * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-row-context 833 * 834 * @since 6.7.0 835 */ 836 public function clear_to_table_row_context(): void { 837 foreach ( $this->walk_up() as $item ) { 838 if ( 839 'TR' === $item->node_name || 840 'TEMPLATE' === $item->node_name || 841 'HTML' === $item->node_name 842 ) { 843 break; 844 } 845 $this->pop(); 846 } 847 } 848 849 /** 850 * Wakeup magic method. 851 * 852 * @since 6.6.0 853 */ 854 public function __wakeup() { 855 throw new \LogicException( __CLASS__ . ' should never be unserialized' ); 856 } 857 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Sat Jun 27 08:20:12 2026 | Cross-referenced by PHPXref |