Make WordPress Core

Changeset 53149


Ignore:
Timestamp:
04/12/2022 05:16:46 AM (18 months ago)
Author:
peterwilsoncc
Message:

Media: Run the wp_content_img_tag filter once per image.

Prevent multiple identical img tags in a block of content causing the wp_content_img_tag filter to fire multiple times for that image.

Follow up to [53028].

Props superpoincare, flixos90, pbearne, peterwilsoncc.
Fixes #55510.
See #55347.

Location:
trunk
Files:
2 edited

Legend:

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

    r53028 r53149  
    18581858                $content = str_replace( $match[0], $filtered_image, $content );
    18591859            }
     1860
     1861            /*
     1862             * Unset image lookup to not run the same logic again unnecessarily if the same image tag is used more than
     1863             * once in the same blob of content.
     1864             */
     1865            unset( $images[ $match[0] ] );
    18601866        }
    18611867
     
    18721878                $content = str_replace( $match[0], $filtered_iframe, $content );
    18731879            }
     1880
     1881            /*
     1882             * Unset iframe lookup to not run the same logic again unnecessarily if the same iframe tag is used more
     1883             * than once in the same blob of content.
     1884             */
     1885            unset( $iframes[ $match[0] ] );
    18741886        }
    18751887    }
  • trunk/tests/phpunit/tests/media.php

    r53028 r53149  
    23052305        $this->assertSame( 1, $filter->get_call_count() );
    23062306    }
     2307
     2308    /**
     2309     * @ticket 55510
     2310     * @covers ::wp_filter_content_tags
     2311     */
     2312    public function test_wp_filter_content_tags_handles_duplicate_img_and_iframe_tags_once() {
     2313        $img     = get_image_tag( self::$large_id, '', '', '', 'large' );
     2314        $iframe  = '<iframe src="https://www.example.com" width="640" height="360"></iframe>';
     2315        $content = "$img\n$img\n$iframe\n$iframe";
     2316
     2317        // Record how often one of the available img and iframe filters is run.
     2318        // Both images and iframes support lazy-loading, so that's why this is used here.
     2319        $img_filter = new MockAction();
     2320        add_filter( 'wp_img_tag_add_loading_attr', array( &$img_filter, 'filter' ) );
     2321        $iframe_filter = new MockAction();
     2322        add_filter( 'wp_iframe_tag_add_loading_attr', array( &$iframe_filter, 'filter' ) );
     2323
     2324        // Ensure the img and iframe filters only ran once because the content is a single duplicated img tag and a
     2325        // single duplicate iframe tag.
     2326        wp_filter_content_tags( $content );
     2327        $this->assertSame( 1, $img_filter->get_call_count() );
     2328        $this->assertSame( 1, $iframe_filter->get_call_count() );
     2329    }
     2330
     2331    /**
     2332     * @ticket 55510
     2333     * @covers ::wp_filter_content_tags
     2334     */
     2335    public function test_wp_filter_content_tags_filter_with_identical_image_tags_custom_attributes() {
     2336        $img     = get_image_tag( self::$large_id, '', '', '', 'large' );
     2337        $img     = str_replace( '<img ', '<img srcset="custom" sizes="custom" loading="custom" ', $img );
     2338        $content = "$img\n$img";
     2339
     2340        add_filter(
     2341            'wp_content_img_tag',
     2342            function( $filtered_image ) {
     2343                return "<span>$filtered_image</span>";
     2344            }
     2345        );
     2346
     2347        // Ensure there is no duplicate <span> wrapping the image.
     2348        $this->assertStringNotContainsString( '<span><span><img ', wp_filter_content_tags( $content ) );
     2349    }
     2350
     2351    /**
     2352     * @ticket 55510
     2353     * @covers ::wp_filter_content_tags
     2354     */
     2355    public function test_wp_filter_content_tags_filter_with_identical_image_tags_disabled_core_filters() {
     2356        $img     = get_image_tag( self::$large_id, '', '', '', 'large' );
     2357        $content = "$img\n$img";
     2358
     2359        add_filter( 'wp_img_tag_add_loading_attr', '__return_false' );
     2360        add_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' );
     2361        add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' );
     2362
     2363        add_filter(
     2364            'wp_content_img_tag',
     2365            function( $filtered_image ) {
     2366                return "<span>$filtered_image</span>";
     2367            }
     2368        );
     2369
     2370        // Ensure the output has both instances of the image wrapped with a single <span>.
     2371        $this->assertSame( "<span>$img</span>\n<span>$img</span>", wp_filter_content_tags( $content ) );
     2372    }
     2373
    23072374    /**
    23082375     * @ticket 33641
Note: See TracChangeset for help on using the changeset viewer.