From 361333e7e20743642dd50faf8488d42b968b8741 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Wed, 24 Apr 2019 05:40:01 +0000 Subject: [PATCH] Remove the `core/more` block delimiters when splitting post_content on the `` tag. Fixes: - Parsing of blocks in the second half of post_content. - Outputting malformed HTML when `the_content( null, true )` or `` is used. Props lukecarbis, garrett-eclipse, birgire. Fixes #46471. git-svn-id: https://develop.svn.wordpress.org/trunk@45261 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/post-template.php | 6 + tests/phpunit/tests/post/output.php | 179 ++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) diff --git a/src/wp-includes/post-template.php b/src/wp-includes/post-template.php index 3765e9873c..dd9e22d920 100644 --- a/src/wp-includes/post-template.php +++ b/src/wp-includes/post-template.php @@ -314,7 +314,13 @@ function get_the_content( $more_link_text = null, $strip_teaser = false, $post = $page_no = $elements['page']; $content = $elements['pages'][ $page_no - 1 ]; if ( preg_match( '//', $content, $matches ) ) { + if ( has_block( 'more', $content ) ) { + // Remove the core/more block delimiters. They will be left over after $content is split up. + $content = preg_replace( '//', '', $content ); + } + $content = explode( $matches[0], $content, 2 ); + if ( ! empty( $matches[1] ) && ! empty( $more_link_text ) ) { $more_link_text = strip_tags( wp_kses_no_null( trim( $matches[1] ) ) ); } diff --git a/tests/phpunit/tests/post/output.php b/tests/phpunit/tests/post/output.php index b6c402ba89..02be7ffa6e 100644 --- a/tests/phpunit/tests/post/output.php +++ b/tests/phpunit/tests/post/output.php @@ -175,4 +175,183 @@ EOF; kses_remove_filters(); } + + /** + * Ensure the_content handles a More block on a singular page. + * + * @ticket 46471 + * + * @group blocks + */ + public function test_the_content_should_handle_more_block_on_singular() { + $post_content = << +

Teaser part.

+ + + + + + + +

Second block.

+ +EOF; + + $post_id = self::factory()->post->create( compact( 'post_content' ) ); + + $expected_without_teaser = << +

Second block.

+EOF; + + $expected_with_teaser = <<Teaser part.

+ +

Second block.

+EOF; + + $this->go_to( get_permalink( $post_id ) ); + $this->assertTrue( is_singular() ); + $this->assertTrue( have_posts() ); + $this->assertNull( the_post() ); + + // Without the teaser. + $actual = get_echo( 'the_content', array( null, true ) ); + $this->assertSame( strip_ws( $expected_without_teaser ), strip_ws( $actual ) ); + + // With the teaser. + $actual = get_echo( 'the_content', array( null, false ) ); + $this->assertSame( strip_ws( $expected_with_teaser ), strip_ws( $actual ) ); + } + + /** + * Ensure the_content handles a More block when using the noteaser text tag on a singular page. + * + * @ticket 46471 + * + * @group blocks + */ + public function test_the_content_should_handle_more_block_when_noteaser_on_singular() { + $post_content = << +

Teaser part.

+ + + + + + + + +

Second block.

+ +EOF; + + $post_id = self::factory()->post->create( compact( 'post_content' ) ); + + $expected = << + +

Second block.

+EOF; + + $this->go_to( get_permalink( $post_id ) ); + $this->assertTrue( is_singular() ); + $this->assertTrue( have_posts() ); + $this->assertNull( the_post() ); + + $actual = get_echo( 'the_content', array( null, true ) ); + $this->assertSame( strip_ws( $expected ), strip_ws( $actual ) ); + + $actual = get_echo( 'the_content', array( null, false ) ); + $this->assertSame( strip_ws( $expected ), strip_ws( $actual ) ); + } + + /** + * Ensure the_content displays the teaser part with a read more link + * for a More block on a non-singular page. + * + * @ticket 46471 + * + * @group blocks + */ + public function test_the_content_should_handle_more_block_when_non_singular() { + $post_content = << +

Teaser part.

+ + + + + + + +

Second block.

+ +EOF; + + $post_id = self::factory()->post->create( compact( 'post_content' ) ); + + $expected = << +

Second block.

+EOF; + + $this->go_to( home_url() ); + $this->assertFalse( is_singular() ); + $this->assertTrue( have_posts() ); + $this->assertNull( the_post() ); + + foreach ( array( true, false ) as $strip_teaser ) { + $actual = get_echo( 'the_content', array( null, $strip_teaser ) ); + $this->assertContains( 'Teaser part', $actual ); + $this->assertContains( 'Read More', $actual ); + $this->assertNotContains( '', $actual ); + $this->assertNotContains( 'wp:more', $actual ); + $this->assertNotContains( 'wp:paragraph', $actual ); + } + } + + /** + * Ensure the_content displays the teaser part with a read more link for a More block + * when using the noteaser text tag on a non-singular page. + * + * @ticket 46471 + * + * @group blocks + */ + public function test_the_content_should_handle_more_block_when_noteaser_on_non_singular() { + $post_content = << +

Teaser part.

+ + + + + + + + +

Second block.

+ +EOF; + + $post_id = self::factory()->post->create( compact( 'post_content' ) ); + + $this->go_to( home_url() ); + $this->assertFalse( is_singular() ); + $this->assertTrue( have_posts() ); + $this->assertNull( the_post() ); + + foreach ( array( true, false ) as $strip_teaser ) { + $actual = get_echo( 'the_content', array( null, $strip_teaser ) ); + $this->assertContains( 'Teaser part', $actual ); + $this->assertContains( '(more…)', $actual ); + $this->assertNotContains( '', $actual ); + $this->assertNotContains( '', $actual ); // We placed the noteaser tag below the more tag. + $this->assertNotContains( 'wp:more', $actual ); + $this->assertNotContains( 'wp:paragraph', $actual ); + } + } }