diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 31f1b224692a7..838cd84a19921 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -1248,8 +1248,25 @@ function apply_block_hooks_to_content_from_post_object( $content, $post = null, $content ); + /* + * We need to avoid inserting any blocks hooked into the `before` and `after` positions + * of the temporary wrapper block that we create to wrap the content. + * See https://core.trac.wordpress.org/ticket/63287 for more details. + */ + $suppress_blocks_from_insertion_before_and_after_wrapper_block = static function ( $hooked_block_types, $relative_position, $anchor_block_type ) use ( $wrapper_block_type ) { + if ( + $wrapper_block_type === $anchor_block_type && + in_array( $relative_position, array( 'before', 'after' ), true ) + ) { + return array(); + } + return $hooked_block_types; + }; + // Apply Block Hooks. + add_filter( 'hooked_block_types', $suppress_blocks_from_insertion_before_and_after_wrapper_block, PHP_INT_MAX, 3 ); $content = apply_block_hooks_to_content( $content, $post, $callback ); + remove_filter( 'hooked_block_types', $suppress_blocks_from_insertion_before_and_after_wrapper_block, PHP_INT_MAX ); // Finally, we need to remove the temporary wrapper block. $content = remove_serialized_parent_block( $content ); diff --git a/tests/phpunit/tests/blocks/applyBlockHooksToContent.php b/tests/phpunit/tests/blocks/applyBlockHooksToContent.php index 22e3c6e8dffb5..150560dbaba24 100644 --- a/tests/phpunit/tests/blocks/applyBlockHooksToContent.php +++ b/tests/phpunit/tests/blocks/applyBlockHooksToContent.php @@ -17,13 +17,14 @@ class Tests_Blocks_ApplyBlockHooksToContent extends WP_UnitTestCase { * Set up. * * @ticket 61902. + * @ticket 63287. */ public static function wpSetUpBeforeClass() { register_block_type( 'tests/hooked-block', array( 'block_hooks' => array( - 'tests/anchor-block' => 'after', + 'core/post-content' => 'after', ), ) ); @@ -79,23 +80,25 @@ public function test_apply_block_hooks_to_content_sets_theme_attribute_on_templa /** * @ticket 61902 + * @ticket 63287 */ public function test_apply_block_hooks_to_content_inserts_hooked_block() { $context = new WP_Block_Template(); - $context->content = ''; + $context->content = ''; $actual = apply_block_hooks_to_content( $context->content, $context, 'insert_hooked_blocks' ); $this->assertSame( - '', + '', $actual ); } /** * @ticket 61074 + * @ticket 63287 */ public function test_apply_block_hooks_to_content_with_context_set_to_null() { - $content = ''; + $content = ''; /* * apply_block_hooks_to_content() will fall back to the global $post object (via get_post()) @@ -106,7 +109,7 @@ public function test_apply_block_hooks_to_content_with_context_set_to_null() { $actual = apply_block_hooks_to_content( $content, null, 'insert_hooked_blocks' ); $this->assertSame( - '', + '', $actual ); } diff --git a/tests/phpunit/tests/blocks/applyBlockHooksToContentFromPostObject.php b/tests/phpunit/tests/blocks/applyBlockHooksToContentFromPostObject.php index df9d560ac9139..5ff9f7323e0f3 100644 --- a/tests/phpunit/tests/blocks/applyBlockHooksToContentFromPostObject.php +++ b/tests/phpunit/tests/blocks/applyBlockHooksToContentFromPostObject.php @@ -88,6 +88,17 @@ public static function wpSetUpBeforeClass() { ), ) ); + + register_block_type( + 'tests/hooked-block-after-post-content', + array( + 'block_hooks' => array( + 'core/post-content' => 'after', + ), + ) + ); + + register_block_type( 'tests/dynamically-hooked-block-before-post-content' ); } /** @@ -100,6 +111,8 @@ public static function wpTearDownAfterClass() { $registry->unregister( 'tests/hooked-block' ); $registry->unregister( 'tests/hooked-block-first-child' ); + $registry->unregister( 'tests/hooked-block-after-post-content' ); + $registry->unregister( 'tests/dynamically-hooked-block-before-post-content' ); } /** @@ -130,6 +143,33 @@ public function test_apply_block_hooks_to_content_from_post_object_respects_igno $this->assertSame( $expected, $actual ); } + /** + * @ticket 63287 + */ + public function test_apply_block_hooks_to_content_from_post_object_does_not_insert_hooked_block_before_container_block() { + $filter = function ( $hooked_block_types, $relative_position, $anchor_block_type ) { + if ( 'core/post-content' === $anchor_block_type && 'before' === $relative_position ) { + $hooked_block_types[] = 'tests/dynamically-hooked-block-before-post-content'; + } + + return $hooked_block_types; + }; + + $expected = '' . + self::$post->post_content . + ''; + + add_filter( 'hooked_block_types', $filter, 10, 3 ); + $actual = apply_block_hooks_to_content_from_post_object( + self::$post->post_content, + self::$post, + 'insert_hooked_blocks' + ); + remove_filter( 'hooked_block_types', $filter, 10 ); + + $this->assertSame( $expected, $actual ); + } + /** * @ticket 62716 */