Make WordPress Core

Changeset 56560


Ignore:
Timestamp:
09/12/2023 07:18:34 PM (9 months ago)
Author:
flixos90
Message:

Posts, Post Types: Avoid unnecessarily parsing blocks twice in wp_trim_excerpt().

All blocks relevant for the excerpt are already being parsed in excerpt_remove_blocks(). Therefore running do_blocks() on the post content only to create the excerpt is unnecessary and wasteful from a performance perspective.

Props thekt12, spacedmonkey, mukesh27, joemcgill.
Fixes #58682.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/blocks.php

    r56559 r56560  
    957957 */
    958958function excerpt_remove_blocks( $content ) {
     959    if ( ! has_blocks( $content ) ) {
     960        return $content;
     961    }
     962
    959963    $allowed_inner_blocks = array(
    960964        // Classic blocks have their blockName set to null.
  • trunk/src/wp-includes/formatting.php

    r56559 r56560  
    39813981         * is wasteful and can lead to bugs in the image counting logic.
    39823982         */
    3983         $filter_removed = remove_filter( 'the_content', 'wp_filter_content_tags' );
     3983        $filter_image_removed = remove_filter( 'the_content', 'wp_filter_content_tags' );
     3984
     3985        /*
     3986         * Temporarily unhook do_blocks() since excerpt_remove_blocks( $text )
     3987         * handels block rendering needed for excerpt.
     3988         */
     3989        $filter_block_removed = remove_filter( 'the_content', 'do_blocks', 9 );
    39843990
    39853991        /** This filter is documented in wp-includes/post-template.php */
     
    39873993        $text = str_replace( ']]>', ']]>', $text );
    39883994
    3989         /**
     3995        // Restore the original filter if removed.
     3996        if ( $filter_block_removed ) {
     3997            add_filter( 'the_content', 'do_blocks', 9 );
     3998        }
     3999
     4000        /*
    39904001         * Only restore the filter callback if it was removed above. The logic
    39914002         * to unhook and restore only applies on the default priority of 10,
    39924003         * which is generally used for the filter callback in WordPress core.
    39934004         */
    3994         if ( $filter_removed ) {
     4005        if ( $filter_image_removed ) {
    39954006            add_filter( 'the_content', 'wp_filter_content_tags' );
    39964007        }
  • trunk/tests/phpunit/tests/formatting/wpTrimExcerpt.php

    r56559 r56560  
    149149        $this->assertFalse( has_filter( 'the_content', 'wp_filter_content_tags' ) );
    150150    }
     151
     152    /**
     153     * Tests that `wp_trim_excerpt()` does process valid blocks.
     154     *
     155     * @ticket 58682
     156     *
     157     * @covers ::wp_trim_excerpt
     158     */
     159    public function test_wp_trim_excerpt_check_if_block_renders() {
     160        $post = self::factory()->post->create(
     161            array(
     162                'post_content' => '<!-- wp:paragraph --> <p>A test paragraph</p> <!-- /wp:paragraph -->',
     163            )
     164        );
     165
     166        $output_text = wp_trim_excerpt( '', $post );
     167
     168        $this->assertSame( 'A test paragraph', $output_text, 'wp_trim_excerpt() did not process paragraph block.' );
     169    }
     170
     171    /**
     172     * Tests that `wp_trim_excerpt()` unhooks `do_blocks()` from 'the_content' filter.
     173     *
     174     * @ticket 58682
     175     *
     176     * @covers ::wp_trim_excerpt
     177     */
     178    public function test_wp_trim_excerpt_unhooks_do_blocks() {
     179        $post = self::factory()->post->create();
     180
     181        /*
     182         * Record that during 'the_content' filter run by wp_trim_excerpt() the
     183         * do_blocks() callback is not used.
     184         */
     185        $has_filter = true;
     186        add_filter(
     187            'the_content',
     188            static function( $content ) use ( &$has_filter ) {
     189                $has_filter = has_filter( 'the_content', 'do_blocks' );
     190                return $content;
     191            }
     192        );
     193
     194        wp_trim_excerpt( '', $post );
     195
     196        $this->assertFalse( $has_filter, 'do_blocks() was not unhooked in wp_trim_excerpt()' );
     197    }
     198
     199    /**
     200     * Tests that `wp_trim_excerpt()` doesn't permanently unhook `do_blocks()` from 'the_content' filter.
     201     *
     202     * @ticket 58682
     203     *
     204     * @covers ::wp_trim_excerpt
     205     */
     206    public function test_wp_trim_excerpt_should_not_permanently_unhook_do_blocks() {
     207        $post = self::factory()->post->create();
     208
     209        wp_trim_excerpt( '', $post );
     210
     211        $this->assertSame( 9, has_filter( 'the_content', 'do_blocks' ), 'do_blocks() was not restored in wp_trim_excerpt()' );
     212    }
     213
     214    /**
     215     * Tests that `wp_trim_excerpt()` doesn't restore `do_blocks()` if it was previously unhooked.
     216     *
     217     * @ticket 58682
     218     *
     219     * @covers ::wp_trim_excerpt
     220     */
     221    public function test_wp_trim_excerpt_does_not_restore_do_blocks_if_previously_unhooked() {
     222        $post = self::factory()->post->create();
     223
     224        // Remove do_blocks() from 'the_content' filter generally.
     225        remove_filter( 'the_content', 'do_blocks', 9 );
     226
     227        wp_trim_excerpt( '', $post );
     228
     229        // Assert that the filter callback was not restored after running 'the_content'.
     230        $this->assertFalse( has_filter( 'the_content', 'do_blocks' ) );
     231    }
    151232}
Note: See TracChangeset for help on using the changeset viewer.