diff --git a/lib/register.php b/lib/register.php index 5e8cdbd00d238..1795c1036fb1f 100644 --- a/lib/register.php +++ b/lib/register.php @@ -365,7 +365,7 @@ function has_blocks( $post = null ) { * @see gutenberg_parse_blocks() * * @since 0.5.0 - * @deprecated 3.6.0 Use has_block() + * @deprecated 3.6.0 Use has_blocks() * * @param object $post Post. * @return bool Whether the post has blocks. @@ -384,7 +384,7 @@ function gutenberg_post_has_blocks( $post ) { * @see gutenberg_parse_blocks() * * @since 1.6.0 - * @deprecated 3.6.0 Use has_block() + * @deprecated 3.6.0 Use has_blocks() * * @param string $content Content to test. * @return bool Whether the content contains blocks. @@ -394,6 +394,33 @@ function gutenberg_content_has_blocks( $content ) { return has_blocks( $content ); } +/** + * Determine whether a $post or a string contains a specific block type. + * This test optimizes for performance rather than strict accuracy, detecting + * the block type exists but not validating its structure. + * For strict accuracy, you should use the block parser on post content. + * + * @since 3.6.0 + * + * @param string $block_type Full Block type to look for. + * @param int|string|WP_Post|null $post Optional. Post content, post ID, or post object. Defaults to global $post. + * @return bool Whether the post content contains the specified block. + */ +function has_block( $block_type, $post = null ) { + if ( ! has_blocks( $post ) ) { + return false; + } + + if ( ! is_string( $post ) ) { + $wp_post = get_post( $post ); + if ( $wp_post instanceof WP_Post ) { + $post = $wp_post->post_content; + } + } + + return false !== strpos( $post, '\n

Tester

\n", + ) ); + + self::$post_without_blocks = self::factory()->post->create( array( + 'post_title' => 'Example', + 'post_content' => 'Tester', + ) ); + } + function test_set_props() { $name = 'core/dummy'; $args = array( @@ -112,6 +156,75 @@ function test_prepare_attributes() { ), $prepared_attributes ); } + function test_has_block_with_mixed_content() { + $mixed_post_content = 'before' . + '' . + '' . + ' +

testing the test

+ ' . + 'between' . + '' . + '' . + 'after'; + + $this->assertTrue( has_block( 'core/dummy', $mixed_post_content ) ); + + $this->assertTrue( has_block( 'core/dummy_atts', $mixed_post_content ) ); + + $this->assertTrue( has_block( 'core/dummy-child', $mixed_post_content ) ); + + $this->assertTrue( has_block( 'core/self-close-dummy', $mixed_post_content ) ); + + $this->assertTrue( has_block( 'custom/dummy', $mixed_post_content ) ); + + // checking for a partial block name should fail. + $this->assertFalse( has_block( 'core/dumm', $mixed_post_content ) ); + + // checking for a wrong namespace should fail. + $this->assertFalse( has_block( 'custom/dummy_atts', $mixed_post_content ) ); + + // checking for namespace only should not work. Or maybe ... ? + $this->assertFalse( has_block( 'core', $mixed_post_content ) ); + } + + function test_has_block_with_invalid_content() { + // some content with invalid HMTL comments and a single valid block. + $invalid_content = 'before' . + '' . + '' . + '' . + '' . + 'after'; + + $this->assertFalse( has_block( 'core/text', self::$post_without_blocks ) ); + + $this->assertFalse( has_block( 'core/weird-space', $invalid_content ) ); + + $this->assertFalse( has_block( 'core/untrimmed-left', $invalid_content ) ); + + $this->assertFalse( has_block( 'core/untrimmed-right', $invalid_content ) ); + + $this->assertTrue( has_block( 'core/dummy', $invalid_content ) ); + } + + function test_post_has_block() { + // should fail for a non-existent block `custom/dummy`. + $this->assertFalse( has_block( 'custom/dummy', self::$post_with_blocks ) ); + + // this functions should not work without the second param until the $post global is set. + $this->assertFalse( has_block( 'core/text' ) ); + $this->assertFalse( has_block( 'core/dummy' ) ); + + global $post; + $post = get_post( self::$post_with_blocks ); + + // check if the function correctly detects content from the $post global. + $this->assertTrue( has_block( 'core/text' ) ); + // even if it detects a proper $post global it should still be false for a missing block. + $this->assertFalse( has_block( 'core/dummy' ) ); + } + function render_dummy_block( $attributes ) { return json_encode( $attributes ); }