diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 591a7971cafb0..431e2b015332c 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -757,6 +757,38 @@ function get_hooked_blocks() { return $hooked_blocks; } +/** + * Conditionally returns the markup for a given hooked block type. + * + * Accepts two arguments: A reference to an anchor block, and the name of a hooked block type. + * If the anchor block has already been processed, and the given hooked block type is in the list + * of ignored hooked blocks, an empty string is returned. + * + * This function is meant for internal use only. + * + * @since 6.5.0 + * @access private + * + * @param array $anchor_block The anchor block. Passed by reference. + * @param string $hooked_block_type The name of the hooked block type. + * @return string The markup for the given hooked block type, or an empty string if the block is ignored. + */ +function get_hooked_block_markup( &$anchor_block, $hooked_block_type ) { + if ( ! isset( $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ) ) { + $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] = array(); + } + + if ( in_array( $hooked_block_type, $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ) ) { + return ''; + } + + // The following is only needed for the REST API endpoint. + // However, its presence does not affect the frontend. + $anchor_block['attrs']['metadata']['ignoredHookedBlocks'][] = $hooked_block_type; + + return get_comment_delimited_block_content( $hooked_block_type, array(), '' ); +} + /** * Returns a function that injects the theme attribute into, and hooked blocks before, a given block. * @@ -813,7 +845,7 @@ function make_before_block_visitor( $hooked_blocks, $context ) { */ $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); foreach ( $hooked_block_types as $hooked_block_type ) { - $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' ); + $markup .= get_hooked_block_markup( $parent_block, $hooked_block_type ); } } @@ -826,7 +858,7 @@ function make_before_block_visitor( $hooked_blocks, $context ) { /** This filter is documented in wp-includes/blocks.php */ $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); foreach ( $hooked_block_types as $hooked_block_type ) { - $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' ); + $markup .= get_hooked_block_markup( $block, $hooked_block_type ); } return $markup; @@ -874,7 +906,7 @@ function make_after_block_visitor( $hooked_blocks, $context ) { /** This filter is documented in wp-includes/blocks.php */ $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); foreach ( $hooked_block_types as $hooked_block_type ) { - $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' ); + $markup .= get_hooked_block_markup( $block, $hooked_block_type ); } if ( $parent_block && ! $next ) { @@ -888,7 +920,7 @@ function make_after_block_visitor( $hooked_blocks, $context ) { /** This filter is documented in wp-includes/blocks.php */ $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); foreach ( $hooked_block_types as $hooked_block_type ) { - $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' ); + $markup .= get_hooked_block_markup( $parent_block, $hooked_block_type ); } } diff --git a/tests/phpunit/tests/blocks/getHookedBlockMarkup.php b/tests/phpunit/tests/blocks/getHookedBlockMarkup.php new file mode 100644 index 0000000000000..918ad97031e2e --- /dev/null +++ b/tests/phpunit/tests/blocks/getHookedBlockMarkup.php @@ -0,0 +1,68 @@ + 'tests/anchor-block', + ); + + $actual = get_hooked_block_markup( $anchor_block, 'tests/hooked-block' ); + $this->assertSame( array( 'tests/hooked-block' ), $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ); + $this->assertSame( '', $actual ); + } + + /** + * @ticket 59646 + * + * @covers ::get_hooked_block_markup + */ + public function test_get_hooked_block_markup_if_block_is_already_hooked() { + $anchor_block = array( + 'blockName' => 'tests/anchor-block', + 'attrs' => array( + 'metadata' => array( + 'ignoredHookedBlocks' => array( 'tests/hooked-block' ), + ), + ), + ); + + $actual = get_hooked_block_markup( $anchor_block, 'tests/hooked-block' ); + $this->assertSame( array( 'tests/hooked-block' ), $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ); + $this->assertSame( '', $actual ); + } + + /** + * @ticket 59646 + * + * @covers ::get_hooked_block_markup + */ + public function test_get_hooked_block_markup_adds_to_ignored_hooked_blocks() { + $anchor_block = array( + 'blockName' => 'tests/anchor-block', + 'attrs' => array( + 'metadata' => array( + 'ignoredHookedBlocks' => array( 'tests/hooked-block' ), + ), + ), + ); + + $actual = get_hooked_block_markup( $anchor_block, 'tests/other-hooked-block' ); + $this->assertSame( array( 'tests/hooked-block', 'tests/other-hooked-block' ), $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ); + $this->assertSame( '', $actual ); + } +} diff --git a/tests/phpunit/tests/blocks/getHookedBlocks.php b/tests/phpunit/tests/blocks/getHookedBlocks.php index 4052e2a36fe36..66a9e00efea69 100644 --- a/tests/phpunit/tests/blocks/getHookedBlocks.php +++ b/tests/phpunit/tests/blocks/getHookedBlocks.php @@ -149,7 +149,7 @@ public function test_loading_template_with_hooked_blocks() { $template->content ); $this->assertStringContainsString( - '' + '' . '', $template->content ); @@ -176,7 +176,7 @@ public function test_loading_template_part_with_hooked_blocks() { $this->assertStringContainsString( '' - . '', + . '', $template->content ); $this->assertStringNotContainsString( @@ -215,7 +215,7 @@ public function test_loading_pattern_with_hooked_blocks() { $pattern['content'] ); $this->assertStringContainsString( - '' + '' . '
' . '', str_replace( array( "\n", "\t" ), '', $pattern['content'] ) diff --git a/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php b/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php index 01050a2c5f2ad..1cc0f472bcdab 100644 --- a/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php +++ b/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php @@ -381,14 +381,12 @@ public function test_get_all_registered_includes_hooked_blocks() { $pattern_three['name'] = 'test/three'; $pattern_three['content'] .= ''; - $expected = array( - $pattern_one, - $pattern_two, - $pattern_three, - ); - $registered = $this->registry->get_all_registered(); - $this->assertSame( $expected, $registered ); + $this->assertCount( 3, $registered ); + $this->assertStringEndsWith( '', $registered[1]['content'] ); + $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $registered[1]['content'] ); + $this->assertStringEndsWith( '', $registered[2]['content'] ); + $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $registered[2]['content'] ); } /** @@ -444,11 +442,9 @@ public function test_get_registered_includes_hooked_blocks() { ); $this->registry->register( 'test/two', $pattern_two ); - $pattern_one['name'] = 'test/one'; - $pattern_one['content'] = '' . $pattern_one['content']; - $pattern = $this->registry->get_registered( 'test/one' ); - $this->assertSame( $pattern_one, $pattern ); + $this->assertStringStartsWith( '', $pattern['content'] ); + $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $pattern['content'] ); } /**