diff --git a/src/wp-includes/block-supports/block-visibility.php b/src/wp-includes/block-supports/block-visibility.php new file mode 100644 index 0000000000000..53f8d02f8f593 --- /dev/null +++ b/src/wp-includes/block-supports/block-visibility.php @@ -0,0 +1,33 @@ +get_registered( $block['blockName'] ); + + if ( ! $block_type || ! block_has_support( $block_type, 'blockVisibility', true ) ) { + return $block_content; + } + + if ( isset( $block['attrs']['metadata']['blockVisibility'] ) && false === $block['attrs']['metadata']['blockVisibility'] ) { + return ''; + } + + return $block_content; +} + +add_filter( 'render_block', 'wp_render_block_visibility_support', 10, 2 ); diff --git a/src/wp-settings.php b/src/wp-settings.php index 9a175e71f0fa9..9e310f13b612c 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -391,6 +391,7 @@ require ABSPATH . WPINC . '/block-supports/background.php'; require ABSPATH . WPINC . '/block-supports/block-style-variations.php'; require ABSPATH . WPINC . '/block-supports/aria-label.php'; +require ABSPATH . WPINC . '/block-supports/block-visibility.php'; require ABSPATH . WPINC . '/style-engine.php'; require ABSPATH . WPINC . '/style-engine/class-wp-style-engine.php'; require ABSPATH . WPINC . '/style-engine/class-wp-style-engine-css-declarations.php'; diff --git a/tests/phpunit/tests/block-supports/block-visibility.php b/tests/phpunit/tests/block-supports/block-visibility.php new file mode 100644 index 0000000000000..61590d68a0c26 --- /dev/null +++ b/tests/phpunit/tests/block-supports/block-visibility.php @@ -0,0 +1,110 @@ +test_block_name = null; + } + + public function tear_down() { + unregister_block_type( $this->test_block_name ); + $this->test_block_name = null; + parent::tear_down(); + } + + /** + * Registers a new block for testing block visibility support. + * + * @param string $block_name Name for the test block. + * @param array $supports Array defining block support configuration. + * + * @return WP_Block_Type The block type for the newly registered test block. + */ + private function register_visibility_block_with_support( $block_name, $supports = array() ) { + $this->test_block_name = $block_name; + register_block_type( + $this->test_block_name, + array( + 'api_version' => 3, + 'attributes' => array( + 'metadata' => array( + 'type' => 'object', + ), + ), + 'supports' => $supports, + ) + ); + $registry = WP_Block_Type_Registry::get_instance(); + + return $registry->get_registered( $this->test_block_name ); + } + + /** + * Tests that block visibility support renders empty string when block is hidden + * and blockVisibility support is opted in. + * + * @ticket 64061 + */ + public function test_block_visibility_support_hides_block_when_visibility_false() { + $block_type = $this->register_visibility_block_with_support( + 'test/visibility-block', + array( 'blockVisibility' => true ) + ); + + $block_content = '

This is a test block.

'; + $block = array( + 'blockName' => 'test/visibility-block', + 'attrs' => array( + 'metadata' => array( + 'blockVisibility' => false, + ), + ), + ); + + $result = wp_render_block_visibility_support( $block_content, $block ); + + $this->assertSame( '', $result, 'Block content should be empty when blockVisibility is false and support is opted in.' ); + } + + /** + * Tests that block visibility support renders block normally when visibility is false + * but blockVisibility support is not opted in. + * + * @ticket 64061 + */ + public function test_block_visibility_support_shows_block_when_support_not_opted_in() { + $block_type = $this->register_visibility_block_with_support( + 'test/visibility-block', + array( 'blockVisibility' => false ) + ); + + $block_content = '

This is a test block.

'; + $block = array( + 'blockName' => 'test/visibility-block', + 'attrs' => array( + 'metadata' => array( + 'blockVisibility' => false, + ), + ), + ); + + $result = wp_render_block_visibility_support( $block_content, $block ); + + $this->assertSame( $block_content, $result, 'Block content should remain unchanged when blockVisibility support is not opted in.' ); + } +}