Make WordPress Core

Changeset 56560


Ignore:
Timestamp:
09/12/2023 07:18:34 PM (3 years 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.