Make WordPress Core


Ignore:
Timestamp:
10/28/2015 05:40:04 AM (9 years ago)
Author:
azaozz
Message:

Responsive images:

  • Introduce wp_calculate_image_srcset() that replaces wp_get_attachment_image_srcset_array() and is used as lower level function for retrieving the srcset data as array.
  • Use the new function when generating srcset and sizes on the front-end. This is faster as no (other) image API functions are used.
  • Change the wp_get_attachment_image_srcset(). Now it is meant for use in templates and is no longer used in core.
  • A few logic fixes and improvements.
  • Some names changed to be (hopefully) more descriptive.
  • Fixed/updated tests.

Props joemcgill, jaspermdegroot, azaozz.
See #34430.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/media.php

    r35355 r35412  
    717717
    718718    /**
     719     * Helper function to get image size array from size "name"
     720     */
     721    function _get_image_size_array_from_name( $size_name ) {
     722        switch ( $size_name ) {
     723            case 'thumbnail':
     724                return array( 150, 150 );
     725            case 'medium':
     726                return array( 300, 225 );
     727            case 'large':
     728                return array( 1024, 768 );
     729            case 'full':
     730                return array( 1600, 1200 ); // actual size of ../data/images/test-image-large.png
     731            default:
     732                return array( 800, 600 ); // soft-resized image
     733        }
     734    }
     735
     736    /**
    719737     * @ticket 33641
    720738     */
    721     function test_wp_get_attachment_image_srcset_array() {
     739    function test_wp_calculate_image_srcset() {
    722740        $year_month = date('Y/m');
    723         $image = wp_get_attachment_metadata( self::$large_id );
     741        $image_meta = wp_get_attachment_metadata( self::$large_id );
    724742
    725743        $expected = array(
    726744            array(
    727                 'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image['sizes']['medium']['file'],
     745                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image_meta['sizes']['medium']['file'],
    728746                'descriptor' => 'w',
    729                 'value'      => $image['sizes']['medium']['width'],
     747                'value'      => $image_meta['sizes']['medium']['width'],
    730748            ),
    731749            array(
    732                 'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image['sizes']['large']['file'],
     750                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image_meta['sizes']['large']['file'],
    733751                'descriptor' => 'w',
    734                 'value'      => $image['sizes']['large']['width'],
     752                'value'      => $image_meta['sizes']['large']['width'],
    735753            ),
    736754            array(
    737                 'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'],
     755                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'],
    738756                'descriptor' => 'w',
    739                 'value'      => $image['width'],
     757                'value'      => $image_meta['width'],
    740758            ),
    741759        );
     
    745763
    746764        foreach ( $sizes as $size ) {
    747             $this->assertSame( $expected, wp_get_attachment_image_srcset_array( self::$large_id, $size ) );
     765            $image_url = wp_get_attachment_image_url( self::$large_id, $size );
     766            $size_array = $this->_get_image_size_array_from_name( $size );
     767            $this->assertSame( $expected, wp_calculate_image_srcset( $image_url, $size_array, $image_meta ) );
    748768        }
    749769    }
     
    752772     * @ticket 33641
    753773     */
    754     function test_wp_get_attachment_image_srcset_array_no_date_uploads() {
     774    function test_wp_calculate_image_srcset_no_date_uploads() {
    755775        // Save the current setting for uploads folders
    756776        $uploads_use_yearmonth_folders = get_option( 'uploads_use_yearmonth_folders' );
     
    763783        $id = self::factory()->attachment->create_upload_object( $filename );
    764784
    765         $image = wp_get_attachment_metadata( $id );
     785        $image_meta = wp_get_attachment_metadata( $id );
    766786
    767787        $expected = array(
    768788            array(
    769                 'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['sizes']['medium']['file'],
     789                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['medium']['file'],
    770790                'descriptor' => 'w',
    771                 'value'      => $image['sizes']['medium']['width'],
     791                'value'      => $image_meta['sizes']['medium']['width'],
    772792            ),
    773793            array(
    774                 'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['sizes']['large']['file'],
     794                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['large']['file'],
    775795                'descriptor' => 'w',
    776                 'value'      => $image['sizes']['large']['width'],
     796                'value'      => $image_meta['sizes']['large']['width'],
    777797            ),
    778798            array(
    779                 'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'],
     799                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'],
    780800                'descriptor' => 'w',
    781                 'value'      => $image['width'],
     801                'value'      => $image_meta['width'],
    782802            ),
    783803        );
     
    787807
    788808        foreach ( $sizes as $size ) {
    789             $this->assertSame( $expected, wp_get_attachment_image_srcset_array( $id, $size ) );
     809            $size_array = $this->_get_image_size_array_from_name( $size );
     810            $image_url = wp_get_attachment_image_url( self::$large_id, $size );
     811            $this->assertSame( $expected, wp_calculate_image_srcset( $image_url, $size_array, $image_meta ) );
    790812        }
    791813
     
    797819     * @ticket 33641
    798820     */
    799     function test_wp_get_attachment_image_srcset_array_with_edits() {
     821    function test_wp_calculate_image_srcset_with_edits() {
    800822        // For this test we're going to mock metadata changes from an edit.
    801823        // Start by getting the attachment metadata.
    802         $meta = wp_get_attachment_metadata( self::$large_id );
     824        $image_meta = wp_get_attachment_metadata( self::$large_id );
     825        $image_url = wp_get_attachment_image_url( self::$large_id );
     826        $size_array = $this->_get_image_size_array_from_name( 'medium' );
    803827
    804828        // Copy hash generation method used in wp_save_image().
     
    806830
    807831        // Replace file paths for full and medium sizes with hashed versions.
    808         $filename_base = basename( $meta['file'], '.png' );
    809         $meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $meta['file'] );
    810         $meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $meta['sizes']['medium']['file'] );
    811 
    812         // Save edited metadata.
    813         wp_update_attachment_metadata( self::$large_id, $meta );
     832        $filename_base = basename( $image_meta['file'], '.png' );
     833        $image_meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['file'] );
     834        $image_meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['medium']['file'] );
     835        $image_meta['sizes']['large']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['large']['file'] );
    814836
    815837        // Calculate a srcset array.
    816         $sizes = wp_get_attachment_image_srcset_array( self::$large_id, 'medium' );
     838        $sizes = wp_calculate_image_srcset( $image_url, $size_array, $image_meta );
    817839
    818840        // Test to confirm all sources in the array include the same edit hash.
     
    825847     * @ticket 33641
    826848     */
    827     function test_wp_get_attachment_image_srcset_array_false() {
    828         $sizes = wp_get_attachment_image_srcset_array( 99999, 'foo' );
     849    function test_wp_calculate_image_srcset_false() {
     850        $sizes = wp_calculate_image_srcset( 'file.png', array( 400, 300 ), array() );
    829851
    830852        // For canola.jpg we should return
     
    835857     * @ticket 33641
    836858     */
    837     function test_wp_get_attachment_image_srcset_array_no_width() {
    838         // Filter image_downsize() output.
    839         add_filter( 'wp_generate_attachment_metadata', array( $this, '_test_wp_get_attachment_image_srcset_array_no_width_filter' ) );
    840 
    841         $old_meta = get_post_meta( self::$large_id, '_wp_attachment_metadata', true );
     859    function test_wp_calculate_image_srcset_no_width() {
    842860        $file = get_attached_file( self::$large_id );
    843 
    844         $data = wp_generate_attachment_metadata( self::$large_id, $file );
    845         wp_update_attachment_metadata( self::$large_id, $data );
    846 
    847         $srcset = wp_get_attachment_image_srcset_array( self::$large_id, 'medium' );
    848 
    849         update_post_meta( self::$large_id, '_wp_attachment_metadata', $old_meta );
     861        $image_url = wp_get_attachment_image_url( self::$large_id, 'medium' );
     862        $image_meta = wp_generate_attachment_metadata( self::$large_id, $file );
     863
     864        $size_array = array(0, 0);
     865
     866        $srcset = wp_calculate_image_srcset( $image_url, $size_array, $image_meta );
    850867
    851868        // The srcset should be false.
     
    854871
    855872    /**
    856      * Helper function to filter image_downsize and return zero values for width and height.
    857      */
    858     public function _test_wp_get_attachment_image_srcset_array_no_width_filter( $meta ) {
    859         remove_filter( 'wp_generate_attachment_metadata', array( $this, __FUNCTION__ ) );
    860 
    861         $meta['sizes']['medium']['width'] = 0;
    862         $meta['sizes']['medium']['height'] = 0;
    863         return $meta;
    864     }
    865 
    866     /**
    867873     * @ticket 33641
    868874     */
    869875    function test_wp_get_attachment_image_srcset() {
    870         $sizes = wp_get_attachment_image_srcset( self::$large_id, 'full-size' );
    871 
    872         $image = wp_get_attachment_metadata( self::$large_id );
     876        $image_meta = wp_get_attachment_metadata( self::$large_id );
     877        $size_array = array( 1600, 1200 ); // full size
     878
     879        $sizes = wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta );
     880
    873881        $year_month = date('Y/m');
    874882
    875883        $expected = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month = date('Y/m') . '/'
    876             . $image['sizes']['medium']['file'] . ' ' . $image['sizes']['medium']['width'] . 'w, ';
     884            . $image_meta['sizes']['medium']['file'] . ' ' . $image_meta['sizes']['medium']['width'] . 'w, ';
    877885        $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month = date('Y/m') . '/'
    878             . $image['sizes']['large']['file'] . ' ' . $image['sizes']['large']['width'] . 'w, ';
    879         $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w';
     886            . $image_meta['sizes']['large']['file'] . ' ' . $image_meta['sizes']['large']['width'] . 'w, ';
     887        $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
    880888
    881889        $this->assertSame( $expected, $sizes );
     
    886894     */
    887895    function test_wp_get_attachment_image_srcset_single_srcset() {
     896        $image_meta = wp_get_attachment_metadata( self::$large_id );
     897        $size_array = array( 150, 150 );
    888898        /*
    889899         * In our tests, thumbnails will only return a single srcset candidate,
    890900         * so we shouldn't return a srcset value in order to avoid unneeded markup.
    891901         */
    892         $sizes = wp_get_attachment_image_srcset( self::$large_id, 'thumbnail' );
     902        $sizes = wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta );
    893903
    894904        $this->assertFalse( $sizes );
     
    900910    function test_wp_get_attachment_image_sizes() {
    901911        // Test sizes against the default WP sizes.
    902         $intermediates = array('thumbnail', 'medium', 'large');
    903 
    904         foreach( $intermediates as $int ) {
    905             $width = get_option( $int . '_size_w' );
     912        $intermediates = array( 'thumbnail', 'medium', 'large' );
     913        $image_meta = wp_get_attachment_metadata( self::$large_id );
     914
     915        foreach( $intermediates as $int_size ) {
     916            $size_array = $this->_get_image_size_array_from_name( $int_size );
     917            list( $width, $height ) = $size_array;
    906918
    907919            $expected = '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
    908             $sizes = wp_get_attachment_image_sizes( self::$large_id, $int );
    909 
    910             $this->assertSame($expected, $sizes);
     920            $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta );
     921
     922            $this->assertSame( $expected, $sizes );
    911923        }
    912924    }
     
    915927     * @ticket 33641
    916928     */
    917     function test_wp_get_attachment_image_sizes_with_width() {
    918         $width = 350;
    919 
    920         $expected = '(max-width: 350px) 100vw, 350px';
    921         $sizes = wp_get_attachment_image_sizes( self::$large_id, 'medium', $width );
    922 
    923         $this->assertSame( $expected, $sizes );
    924     }
    925 
    926     /**
    927      * @ticket 33641
    928      */
    929929    function test_wp_make_content_images_responsive() {
    930         $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, 'medium' ) );
    931         $sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( self::$large_id, 'medium' ) );
     930        $image_meta = wp_get_attachment_metadata( self::$large_id );
     931        $size_array = $this->_get_image_size_array_from_name( 'medium' );
     932
     933        $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta ) );
     934        $sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( $size_array, $image_meta, self::$large_id ) );
    932935
    933936        // Function used to build HTML for the editor.
    934937        $img = get_image_tag( self::$large_id, '', '', '', 'medium' );
    935         $img_no_size = str_replace( 'size-', '', $img );
    936         $img_no_size_id = str_replace( 'wp-image-', 'id-', $img_no_size );
     938        $img_no_size_in_class = str_replace( 'size-', '', $img );
     939        $img_no_width_height = str_replace( ' width="' . $size_array[0] . '"', '', $img );
     940        $img_no_width_height = str_replace( ' height="' . $size_array[1] . '"', '', $img_no_width_height );
     941        $img_no_size_id = str_replace( 'wp-image-', 'id-', $img );
    937942
    938943        // Manually add srcset and sizes to the markup from get_image_tag();
    939         $respimg = preg_replace('|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img);
    940         $respimg_no_size = preg_replace('|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img_no_size);
    941 
    942         $content = '<p>Welcome to WordPress!  This post contains important information.  After you read it, you can make it private to hide it from visitors but still have the information handy for future reference.</p>
    943             <p>First things first:</p>
    944 
     944        $respimg = preg_replace( '|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img );
     945        $respimg_no_size_in_class = preg_replace( '|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img_no_size_in_class );
     946        $respimg_no_width_height = preg_replace( '|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img_no_width_height );
     947
     948        $content = '
     949            <p>Image, standard. Should have srcset and sizes.</p>
    945950            %1$s
    946951
    947             <ul>
    948             <li><a href="http://wordpress.org" title="Subscribe to the WordPress mailing list for Release Notifications">Subscribe to the WordPress mailing list for release notifications</a></li>
    949             </ul>
    950 
     952            <p>Image, no size class. Should have srcset and sizes.</p>
    951953            %2$s
    952954
    953             <p>As a subscriber, you will receive an email every time an update is available (and only then).  This will make it easier to keep your site up to date, and secure from evildoers.<br />
    954             When a new version is released, <a href="http://wordpress.org" title="If you are already logged in, this will take you directly to the Dashboard">log in to the Dashboard</a> and follow the instructions.<br />
    955             Upgrading is a couple of clicks!</p>
    956 
     955            <p>Image, no width and height attributes. Should have srcset and sizes (from matching the file name).</p>
    957956            %3$s
    958957
    959             <p>Then you can start enjoying the WordPress experience:</p>
    960             <ul>
    961             <li>Edit your personal information at <a href="http://wordpress.org" title="Edit settings like your password, your display name and your contact information">Users &#8250; Your Profile</a></li>
    962             <li>Start publishing at <a href="http://wordpress.org" title="Create a new post">Posts &#8250; Add New</a> and at <a href="http://wordpress.org" title="Create a new page">Pages &#8250; Add New</a></li>
    963             <li>Browse and install plugins at <a href="http://wordpress.org" title="Browse and install plugins at the official WordPress repository directly from your Dashboard">Plugins &#8250; Add New</a></li>
    964             <li>Browse and install themes at <a href="http://wordpress.org" title="Browse and install themes at the official WordPress repository directly from your Dashboard">Appearance &#8250; Add New Themes</a></li>
    965             <li>Modify and prettify your website&#8217;s links at <a href="http://wordpress.org" title="For example, select a link structure like: http://example.com/1999/12/post-name">Settings &#8250; Permalinks</a></li>
    966             <li>Import content from another system or WordPress site at <a href="http://wordpress.org" title="WordPress comes with importers for the most common publishing systems">Tools &#8250; Import</a></li>
    967             <li>Find answers to your questions at the <a href="http://wordpress.orgs" title="The official WordPress documentation, maintained by the WordPress community">WordPress Codex</a></li>
    968             </ul>';
    969 
    970         $content_unfiltered = sprintf( $content, $img, $img_no_size, $img_no_size_id );
    971         $content_filtered = sprintf( $content, $respimg, $respimg_no_size, $img_no_size_id );
     958            <p>Image, no attachment ID class. Should NOT have srcset and sizes.</p>
     959            %4$s';
     960
     961        $content_unfiltered = sprintf( $content, $img, $img_no_size_in_class, $img_no_width_height, $img_no_size_id );
     962        $content_filtered = sprintf( $content, $respimg, $respimg_no_size_in_class, $respimg_no_width_height, $img_no_size_id );
    972963
    973964        $this->assertSame( $content_filtered, wp_make_content_images_responsive( $content_unfiltered ) );
Note: See TracChangeset for help on using the changeset viewer.