Skip to content

Commit

Permalink
HTML API: Return subclass from ::create_fragment
Browse files Browse the repository at this point in the history
When the `WP_HTML_Processor` was introduced with its `::create_fragment()`
static creator method, that method has been returning a `new self(...)`.
Unfortunately, this means that subclasses cannot use that method since it
will return the `WP_HTML_Processor` instead of the subclass.

With this patch, the static creator method returns `new static(...)` to preserve
the intended behavior. A new test asserts this behavior for future changes.

Developed in #6729
Discussed in https://core.trac.wordpress.org/ticket/61374

Props dmsnell, jonsurrell.
Follow-up to [56274].
Fixes #61374.


git-svn-id: https://develop.svn.wordpress.org/trunk@58363 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
dmsnell committed Jun 8, 2024
1 parent 1ea82dc commit 0cad031
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/wp-includes/html-api/class-wp-html-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,18 +276,19 @@ class WP_HTML_Processor extends WP_HTML_Tag_Processor {
* - The only supported document encoding is `UTF-8`, which is the default value.
*
* @since 6.4.0
* @since 6.6.0 Returns `static` instead of `self` so it can create subclass instances.
*
* @param string $html Input HTML fragment to process.
* @param string $context Context element for the fragment, must be default of `<body>`.
* @param string $encoding Text encoding of the document; must be default of 'UTF-8'.
* @return WP_HTML_Processor|null The created processor if successful, otherwise null.
* @return static|null The created processor if successful, otherwise null.
*/
public static function create_fragment( $html, $context = '<body>', $encoding = 'UTF-8' ) {
if ( '<body>' !== $context || 'UTF-8' !== $encoding ) {
return null;
}

$processor = new self( $html, self::CONSTRUCTOR_UNLOCK_CODE );
$processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE );
$processor->state->context_node = array( 'BODY', array() );
$processor->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;

Expand Down
19 changes: 19 additions & 0 deletions tests/phpunit/tests/html-api/wpHtmlProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -517,4 +517,23 @@ public static function data_html_with_target_element_and_depth_of_next_node_in_b
'Funky comment' => array( '<div><p>What <br class="target"><//wp:post-author></p></div>', 5 ),
);
}

/**
* Ensures that subclasses can be created from ::create_fragment method.
*
* @ticket 61374
*/
public function test_subclass_create_fragment_creates_subclass() {
$processor = WP_HTML_Processor::create_fragment( '' );
$this->assertInstanceOf( WP_HTML_Processor::class, $processor, '::create_fragment did not return class instance.' );

$subclass_instance = new class('') extends WP_HTML_Processor {
public function __construct( $html ) {
parent::__construct( $html, parent::CONSTRUCTOR_UNLOCK_CODE );
}
};

$subclass_processor = call_user_func( array( get_class( $subclass_instance ), 'create_fragment' ), '' );
$this->assertInstanceOf( get_class( $subclass_instance ), $subclass_processor, '::create_fragment did not return subclass instance.' );
}
}

0 comments on commit 0cad031

Please sign in to comment.