Make WordPress Core


Ignore:
Timestamp:
05/23/2023 06:23:59 PM (22 months ago)
Author:
flixos90
Message:

Media: Fix lazy-loading bug by avoiding to modify content images when creating an excerpt.

The wp_filter_content_tags() function, which modifies image tags for example to optimize performance, is hooked into the the_content filter by default. When rendering an excerpt for a post that doesn't have a manually provided excerpt, the post content is used to generate the excerpt, handled by the wp_trim_excerpt() function.

Prior to this changeset, this led to wp_filter_content_tags() being called on the content when generating the excerpt, which is wasteful as all tags are stripped from the excerpt, and it furthermore could result in a lazy-loading bug when the post content contained images, as those images were being counted even though they would never be rendered as part of the excerpt.

This changeset fixes the bug and slightly improves performance for generating an excerpt by temporarily unhooking the wp_filter_content_tags() function from the the_content filter when using it to generate the excerpt.

Props costdev, flixos90, joemcgill, mukesh27, salvoaranzulla, spacedmonkey, thekt12, westonruter.
Fixes #56588.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/formatting/wpTrimExcerpt.php

    r53562 r55850  
    9393        $this->assertSame( 'Post content', wp_trim_excerpt( false, $post ) );
    9494    }
     95
     96    /**
     97     * Tests that `wp_trim_excerpt()` unhooks `wp_filter_content_tags()` from 'the_content' filter.
     98     *
     99     * @ticket 56588
     100     */
     101    public function test_wp_trim_excerpt_unhooks_wp_filter_content_tags() {
     102        $post = self::factory()->post->create();
     103
     104        /*
     105         * Record that during 'the_content' filter run by wp_trim_excerpt() the
     106         * wp_filter_content_tags() callback is not used.
     107         */
     108        $has_filter = true;
     109        add_filter(
     110            'the_content',
     111            static function( $content ) use ( &$has_filter ) {
     112                $has_filter = has_filter( 'the_content', 'wp_filter_content_tags' );
     113                return $content;
     114            }
     115        );
     116
     117        wp_trim_excerpt( '', $post );
     118
     119        $this->assertFalse( $has_filter, 'wp_filter_content_tags() was not unhooked in wp_trim_excerpt()' );
     120    }
     121
     122    /**
     123     * Tests that `wp_trim_excerpt()` doesn't permanently unhook `wp_filter_content_tags()` from 'the_content' filter.
     124     *
     125     * @ticket 56588
     126     */
     127    public function test_wp_trim_excerpt_should_not_permanently_unhook_wp_filter_content_tags() {
     128        $post = self::factory()->post->create();
     129
     130        wp_trim_excerpt( '', $post );
     131
     132        $this->assertSame( 10, has_filter( 'the_content', 'wp_filter_content_tags' ), 'wp_filter_content_tags() was not restored in wp_trim_excerpt()' );
     133    }
     134
     135    /**
     136     * Tests that `wp_trim_excerpt()` doesn't restore `wp_filter_content_tags()` if it was previously unhooked.
     137     *
     138     * @ticket 56588
     139     */
     140    public function test_wp_trim_excerpt_does_not_restore_wp_filter_content_tags_if_previously_unhooked() {
     141        $post = self::factory()->post->create();
     142
     143        // Remove wp_filter_content_tags() from 'the_content' filter generally.
     144        remove_filter( 'the_content', 'wp_filter_content_tags' );
     145
     146        wp_trim_excerpt( '', $post );
     147
     148        // Assert that the filter callback was not restored after running 'the_content'.
     149        $this->assertFalse( has_filter( 'the_content', 'wp_filter_content_tags' ) );
     150    }
    95151}
Note: See TracChangeset for help on using the changeset viewer.