diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 81207da795..edd30478af 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -897,7 +897,7 @@ function insert_hooked_blocks( &$parsed_anchor_block, $relative_position, $hooke * * @since 6.5.0 * - * @param array $parsed_hooked_block The parsed block array for the given hooked block type. + * @param array|null $parsed_hooked_block The parsed block array for the given hooked block type, or null to suppress the block. * @param string $hooked_block_type The hooked block type name. * @param string $relative_position The relative position of the hooked block. * @param array $parsed_anchor_block The anchor block, in parsed block array format. @@ -913,7 +913,7 @@ function insert_hooked_blocks( &$parsed_anchor_block, $relative_position, $hooke * * @since 6.5.0 * - * @param array $parsed_hooked_block The parsed block array for the given hooked block type. + * @param array|null $parsed_hooked_block The parsed block array for the given hooked block type, or null to suppress the block. * @param string $hooked_block_type The hooked block type name. * @param string $relative_position The relative position of the hooked block. * @param array $parsed_anchor_block The anchor block, in parsed block array format. @@ -922,6 +922,10 @@ function insert_hooked_blocks( &$parsed_anchor_block, $relative_position, $hooke */ $parsed_hooked_block = apply_filters( "hooked_block_{$hooked_block_type}", $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block, $context ); + if ( null === $parsed_hooked_block ) { + continue; + } + // It's possible that the filter returned a block of a different type, so we explicitly // look for the original `$hooked_block_type` in the `ignoredHookedBlocks` metadata. if ( @@ -962,6 +966,25 @@ function set_ignored_hooked_blocks_metadata( &$parsed_anchor_block, $relative_po return ''; } + foreach ( $hooked_block_types as $index => $hooked_block_type ) { + $parsed_hooked_block = array( + 'blockName' => $hooked_block_type, + 'attrs' => array(), + 'innerBlocks' => array(), + 'innerContent' => array(), + ); + + /** This filter is documented in wp-includes/blocks.php */ + $parsed_hooked_block = apply_filters( 'hooked_block', $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block, $context ); + + /** This filter is documented in wp-includes/blocks.php */ + $parsed_hooked_block = apply_filters( "hooked_block_{$hooked_block_type}", $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block, $context ); + + if ( null === $parsed_hooked_block ) { + unset( $hooked_block_types[ $index ] ); + } + } + $previously_ignored_hooked_blocks = isset( $parsed_anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ) ? $parsed_anchor_block['attrs']['metadata']['ignoredHookedBlocks'] : array(); diff --git a/tests/phpunit/tests/blocks/insertHookedBlocks.php b/tests/phpunit/tests/blocks/insertHookedBlocks.php index d4f5d14502..cf99b213e5 100644 --- a/tests/phpunit/tests/blocks/insertHookedBlocks.php +++ b/tests/phpunit/tests/blocks/insertHookedBlocks.php @@ -180,4 +180,42 @@ class Tests_Blocks_InsertHookedBlocks extends WP_UnitTestCase { "Markup wasn't generated correctly for hooked block wrapped in Group block by filter." ); } + + /** + * @ticket 60580 + * + * @covers ::insert_hooked_blocks + */ + public function test_insert_hooked_blocks_filter_can_suppress_hooked_block() { + $anchor_block = array( + 'blockName' => self::ANCHOR_BLOCK_TYPE, + 'attrs' => array( + 'layout' => array( + 'type' => 'flex', + ), + ), + 'innerContent' => array(), + ); + + $filter = function ( $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block ) { + // Is the hooked block adjacent to the anchor block? + if ( 'before' !== $relative_position && 'after' !== $relative_position ) { + return $parsed_hooked_block; + } + + if ( + isset( $parsed_anchor_block['attrs']['layout']['type'] ) && + 'flex' === $parsed_anchor_block['attrs']['layout']['type'] + ) { + return null; + } + + return $parsed_hooked_block; + }; + add_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter, 10, 4 ); + $actual = insert_hooked_blocks( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); + remove_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter ); + + $this->assertSame( '', $actual, "No markup should've been generated for hooked block suppressed by filter." ); + } } diff --git a/tests/phpunit/tests/blocks/setIgnoredHookedBlocksMetadata.php b/tests/phpunit/tests/blocks/setIgnoredHookedBlocksMetadata.php index f9972eea7f..d5e9c4e23f 100644 --- a/tests/phpunit/tests/blocks/setIgnoredHookedBlocksMetadata.php +++ b/tests/phpunit/tests/blocks/setIgnoredHookedBlocksMetadata.php @@ -144,4 +144,36 @@ class Tests_Blocks_SetIgnoredHookedBlocksMetadata extends WP_UnitTestCase { $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ); } + + /** + * @ticket 60580 + * + * @covers ::set_ignored_hooked_blocks_metadata + */ + public function test_set_ignored_hooked_blocks_metadata_for_block_suppressed_by_filter() { + $anchor_block = array( + 'blockName' => 'tests/anchor-block', + 'attrs' => array(), + ); + + $hooked_blocks = array( + 'tests/anchor-block' => array( + 'after' => array( 'tests/hooked-block', 'tests/hooked-block-suppressed-by-filter' ), + ), + ); + + $filter = function ( $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block ) { + if ( 'tests/anchor-block' === $parsed_anchor_block['blockName'] && 'after' === $relative_position ) { + return null; + } + + return $parsed_hooked_block; + }; + + add_filter( 'hooked_block_tests/hooked-block-suppressed-by-filter', $filter, 10, 4 ); + set_ignored_hooked_blocks_metadata( $anchor_block, 'after', $hooked_blocks, null ); + remove_filter( 'hooked_block_tests/hooked-block-suppressed-by-filter', $filter ); + + $this->assertSame( array( 'tests/hooked-block' ), $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ); + } }