Make WordPress Core

Changeset 37034


Ignore:
Timestamp:
03/18/2016 07:44:50 PM (10 years ago)
Author:
azaozz
Message:

Responsive Images: the src of the image has to be first in the srcset, because of a bug in iOS8. Update the unit tests to reflect the changes.

Props jaspermdegroot, joemcgill, azaozz.
Fixes #35030.

Location:
trunk
Files:
2 edited

Legend:

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

    r37022 r37034  
    10681068         */
    10691069        foreach ( $image_sizes as $image ) {
     1070                $is_src = false;
    10701071
    10711072                // Check if image meta isn't corrupted.
     
    10761077                // If the file name is part of the `src`, we've confirmed a match.
    10771078                if ( ! $src_matched && false !== strpos( $image_src, $dirname . $image['file'] ) ) {
    1078                         $src_matched = true;
     1079                        $src_matched = $is_src = true;
    10791080                }
    10801081
     
    10881089                 * that file is in the 'src' attribute.
    10891090                 */
    1090                 if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width &&
    1091                         false === strpos( $image_src, $image['file'] ) ) {
    1092 
     1091                if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width && ! $is_src ) {
    10931092                        continue;
    10941093                }
     
    11101109                if ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 ) {
    11111110                        // Add the URL, descriptor, and value to the sources array to be returned.
    1112                         $sources[ $image['width'] ] = array(
     1111                        $source = array(
    11131112                                'url'        => $image_baseurl . $image['file'],
    11141113                                'descriptor' => 'w',
    11151114                                'value'      => $image['width'],
    11161115                        );
     1116
     1117                        // The 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030.
     1118                        if ( $is_src ) {
     1119                                $sources = array( $image['width'] => $source ) + $sources;
     1120                        } else {
     1121                                $sources[ $image['width'] ] = $source;
     1122                        }
    11171123                }
    11181124        }
  • trunk/tests/phpunit/tests/media.php

    r37022 r37034  
    834834         * Helper function to get image size array from size "name"
    835835         */
    836         function _get_image_size_array_from_name( $size_name ) {
    837                 switch ( $size_name ) {
    838                         case 'thumbnail':
    839                                 return array( 150, 150 );
    840                         case 'medium':
    841                                 return array( 300, 225 );
    842                         case 'medium_large':
    843                                 return array( 768, 576 );
    844                         case 'large':
    845                                 return array( 1024, 768 );
    846                         case 'full':
    847                                 return array( 1600, 1200 ); // actual size of ../data/images/test-image-large.png
    848                         default:
    849                                 return array( 800, 600 ); // soft-resized image
    850                 }
     836        function _get_image_size_array_from_meta( $image_meta, $size_name ) {
     837                $array = false;
     838
     839                if ( is_array( $image_meta ) ) {
     840                        if ( 'full' === $size_name && isset( $image_meta['width'] ) && isset( $image_meta['height'] ) ) {
     841                                $array = array( $image_meta['width'], $image_meta['height'] );
     842                        } elseif ( isset( $image_meta['sizes'][ $size_name ]['width'] ) && isset( $image_meta['sizes'][ $size_name ]['height'] ) ) {
     843                                $array = array( $image_meta['sizes'][ $size_name ]['width'], $image_meta['sizes'][ $size_name ]['height'] );
     844                        }
     845                }
     846
     847                return $array;
     848        }
     849
     850        /**
     851         * Helper function to move the src image to the first position in the expected srcset string.
     852         */
     853        function _src_first( $srcset, $src_url, $src_width ) {
     854                $src_string = $src_url . ' ' . $src_width . 'w';
     855                $src_not_first = ', ' . $src_string;
     856
     857                if ( strpos( $srcset, $src_not_first ) ) {
     858                        $srcset = str_replace( $src_not_first, '', $srcset );
     859                        $srcset = $src_string . ', ' . $srcset;
     860                }
     861
     862                return $srcset;
    851863        }
    852864
     
    871883                }
    872884
    873                 $expected = "";
     885                $expected = '';
     886
     887                foreach ( $image_meta['sizes'] as $name => $size ) {
     888                        // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4.
     889                        if ( in_array( $name, $intermediates ) ) {
     890                                $expected .= $uploads_dir_url . $year_month . '/' . $size['file'] . ' ' . $size['width'] . 'w, ';
     891                        }
     892                }
     893
     894                // Add the full size width at the end.
     895                $expected .= $uploads_dir_url . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
     896
     897                foreach ( $intermediates as $int ) {
     898                        $image_url = wp_get_attachment_image_url( self::$large_id, $int );
     899                        $size_array = $this->_get_image_size_array_from_meta( $image_meta, $int );
     900                        $expected_srcset = $this->_src_first( $expected, $image_url, $size_array[0] );
     901                        $this->assertSame( $expected_srcset, wp_calculate_image_srcset( $size_array, $image_url, $image_meta ) );
     902                }
     903        }
     904
     905        /**
     906         * @ticket 33641
     907         */
     908        function test_wp_calculate_image_srcset_no_date_uploads() {
     909                global $_wp_additional_image_sizes;
     910
     911                // Disable date organized uploads
     912                add_filter( 'upload_dir', '_upload_dir_no_subdir' );
     913
     914                // Make an image.
     915                $filename = DIR_TESTDATA . '/images/test-image-large.png';
     916                $id = self::factory()->attachment->create_upload_object( $filename );
     917
     918                $image_meta = wp_get_attachment_metadata( $id );
     919                $uploads_dir_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/';
     920
     921                // Set up test cases for all expected size names.
     922                $intermediates = array( 'medium', 'medium_large', 'large', 'full' );
     923
     924                foreach ( $_wp_additional_image_sizes as $name => $additional_size ) {
     925                        if ( ! $_wp_additional_image_sizes[$name]['crop'] || 0 === $_wp_additional_image_sizes[$name]['height'] ) {
     926                                $intermediates[] = $name;
     927                        }
     928                }
     929
     930                $expected = '';
     931
     932                foreach ( $image_meta['sizes'] as $name => $size ) {
     933                        // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4.
     934                        if ( in_array( $name, $intermediates ) ) {
     935                                $expected .= $uploads_dir_url . $size['file'] . ' ' . $size['width'] . 'w, ';
     936                        }
     937                }
     938
     939                // Add the full size width at the end.
     940                $expected .= $uploads_dir_url . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
     941
     942                foreach ( $intermediates as $int ) {
     943                        $size_array = $this->_get_image_size_array_from_meta( $image_meta, $int );
     944                        $image_url = wp_get_attachment_image_url( $id, $int );
     945                        $expected_srcset = $this->_src_first( $expected, $image_url, $size_array[0] );
     946                        $this->assertSame( $expected_srcset, wp_calculate_image_srcset( $size_array, $image_url, $image_meta ) );
     947                }
     948
     949                // Remove the attachment
     950                wp_delete_attachment( $id );
     951                remove_filter( 'upload_dir', '_upload_dir_no_subdir' );
     952        }
     953
     954        /**
     955         * @ticket 33641
     956         */
     957        function test_wp_calculate_image_srcset_with_edits() {
     958                // For this test we're going to mock metadata changes from an edit.
     959                // Start by getting the attachment metadata.
     960                $image_meta = wp_get_attachment_metadata( self::$large_id );
     961                $image_url = wp_get_attachment_image_url( self::$large_id, 'medium' );
     962                $size_array = $this->_get_image_size_array_from_meta( $image_meta, 'medium' );
     963
     964                // Copy hash generation method used in wp_save_image().
     965                $hash = 'e' . time() . rand(100, 999);
     966
     967                $filename_base = basename( $image_meta['file'], '.png' );
     968
     969                // Add the hash to the image URL
     970                $image_url = str_replace( $filename_base, $filename_base . '-' . $hash, $image_url );
     971
     972                // Replace file paths for full and medium sizes with hashed versions.
     973                $image_meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['file'] );
     974                $image_meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['medium']['file'] );
     975                $image_meta['sizes']['medium_large']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['medium_large']['file'] );
     976                $image_meta['sizes']['large']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['large']['file'] );
     977
     978                // Calculate a srcset array.
     979                $sizes = explode( ', ', wp_calculate_image_srcset( $size_array, $image_url, $image_meta ) );
     980
     981                // Test to confirm all sources in the array include the same edit hash.
     982                foreach ( $sizes as $size ) {
     983                        $this->assertTrue( false !== strpos( $size, $hash ) );
     984                }
     985        }
     986
     987        /**
     988         * @ticket 35106
     989         */
     990        function test_wp_calculate_image_srcset_with_absolute_path_in_meta() {
     991                global $_wp_additional_image_sizes;
     992
     993                $year_month = date('Y/m');
     994                $image_meta = wp_get_attachment_metadata( self::$large_id );
     995                $uploads_dir_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/';
     996
     997                // Set up test cases for all expected size names.
     998                $intermediates = array( 'medium', 'medium_large', 'large', 'full' );
     999
     1000                // Add any soft crop intermediate sizes.
     1001                foreach ( $_wp_additional_image_sizes as $name => $additional_size ) {
     1002                        if ( ! $_wp_additional_image_sizes[$name]['crop'] || 0 === $_wp_additional_image_sizes[$name]['height'] ) {
     1003                                $intermediates[] = $name;
     1004                        }
     1005                }
     1006
     1007                $expected = '';
    8741008
    8751009                foreach( $image_meta['sizes'] as $name => $size ) {
     
    8831017                $expected .= $uploads_dir_url . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
    8841018
     1019                // Prepend an absolute path to simulate a pre-2.7 upload
     1020                $image_meta['file'] = 'H:\home\wordpress\trunk/wp-content/uploads/' . $image_meta['file'];
     1021
    8851022                foreach ( $intermediates as $int ) {
    8861023                        $image_url = wp_get_attachment_image_url( self::$large_id, $int );
    887                         $size_array = $this->_get_image_size_array_from_name( $int );
    888                         $this->assertSame( $expected, wp_calculate_image_srcset( $size_array, $image_url, $image_meta ) );
    889                 }
    890         }
    891 
    892         /**
    893          * @ticket 33641
    894          */
    895         function test_wp_calculate_image_srcset_no_date_uploads() {
    896                 global $_wp_additional_image_sizes;
    897 
    898                 // Disable date organized uploads
    899                 add_filter( 'upload_dir', '_upload_dir_no_subdir' );
    900 
    901                 // Make an image.
    902                 $filename = DIR_TESTDATA . '/images/test-image-large.png';
    903                 $id = self::factory()->attachment->create_upload_object( $filename );
    904 
    905                 $image_meta = wp_get_attachment_metadata( $id );
    906                 $uploads_dir_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/';
    907 
    908                 // Set up test cases for all expected size names.
    909                 $intermediates = array( 'medium', 'medium_large', 'large', 'full' );
    910 
    911                 foreach ( $_wp_additional_image_sizes as $name => $additional_size ) {
    912                         if ( ! $_wp_additional_image_sizes[$name]['crop'] || 0 === $_wp_additional_image_sizes[$name]['height'] ) {
    913                                 $intermediates[] = $name;
    914                         }
    915                 }
    916 
    917                 $expected = "";
    918 
    919                 foreach( $image_meta['sizes'] as $name => $size ) {
    920                         // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4.
    921                         if ( in_array( $name, $intermediates ) ) {
    922                                 $expected .= $uploads_dir_url . $size['file'] . ' ' . $size['width'] . 'w, ';
    923                         }
    924                 }
    925 
    926                 // Add the full size width at the end.
    927                 $expected .= $uploads_dir_url . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
    928 
    929                 foreach ( $intermediates as $int ) {
    930                         $size_array = $this->_get_image_size_array_from_name( $int );
    931                         $image_url = wp_get_attachment_image_url( $id, $int );
    932                         $this->assertSame( $expected, wp_calculate_image_srcset( $size_array, $image_url, $image_meta ) );
    933                 }
    934 
    935                 // Remove the attachment
    936                 wp_delete_attachment( $id );
    937                 remove_filter( 'upload_dir', '_upload_dir_no_subdir' );
    938         }
    939 
    940         /**
    941          * @ticket 33641
    942          */
    943         function test_wp_calculate_image_srcset_with_edits() {
    944                 // For this test we're going to mock metadata changes from an edit.
    945                 // Start by getting the attachment metadata.
    946                 $image_meta = wp_get_attachment_metadata( self::$large_id );
    947                 $image_url = wp_get_attachment_image_url( self::$large_id, 'medium' );
    948                 $size_array = $this->_get_image_size_array_from_name( 'medium' );
    949 
    950                 // Copy hash generation method used in wp_save_image().
    951                 $hash = 'e' . time() . rand(100, 999);
    952 
    953                 $filename_base = basename( $image_meta['file'], '.png' );
    954 
    955                 // Add the hash to the image URL
    956                 $image_url = str_replace( $filename_base, $filename_base . '-' . $hash, $image_url );
    957 
    958                 // Replace file paths for full and medium sizes with hashed versions.
    959                 $image_meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['file'] );
    960                 $image_meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['medium']['file'] );
    961                 $image_meta['sizes']['medium_large']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['medium_large']['file'] );
    962                 $image_meta['sizes']['large']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['large']['file'] );
    963 
    964                 // Calculate a srcset array.
    965                 $sizes = explode( ', ', wp_calculate_image_srcset( $size_array, $image_url, $image_meta ) );
    966 
    967                 // Test to confirm all sources in the array include the same edit hash.
    968                 foreach ( $sizes as $size ) {
    969                         $this->assertTrue( false !== strpos( $size, $hash ) );
    970                 }
    971         }
    972 
    973         /**
    974          * @ticket 35106
    975          */
    976         function test_wp_calculate_image_srcset_with_absolute_path_in_meta() {
    977                 global $_wp_additional_image_sizes;
    978 
    979                 $year_month = date('Y/m');
    980                 $image_meta = wp_get_attachment_metadata( self::$large_id );
    981                 $uploads_dir_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/';
    982 
    983                 // Set up test cases for all expected size names.
    984                 $intermediates = array( 'medium', 'medium_large', 'large', 'full' );
    985 
    986                 // Add any soft crop intermediate sizes.
    987                 foreach ( $_wp_additional_image_sizes as $name => $additional_size ) {
    988                         if ( ! $_wp_additional_image_sizes[$name]['crop'] || 0 === $_wp_additional_image_sizes[$name]['height'] ) {
    989                                 $intermediates[] = $name;
    990                         }
    991                 }
    992 
    993                 $expected = '';
    994 
    995                 foreach( $image_meta['sizes'] as $name => $size ) {
    996                         // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4.
    997                         if ( in_array( $name, $intermediates ) ) {
    998                                 $expected .= $uploads_dir_url . $year_month . '/' . $size['file'] . ' ' . $size['width'] . 'w, ';
    999                         }
    1000                 }
    1001 
    1002                 // Add the full size width at the end.
    1003                 $expected .= $uploads_dir_url . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
    1004 
    1005                 // Prepend an absolute path to simulate a pre-2.7 upload
    1006                 $image_meta['file'] = 'H:\home\wordpress\trunk/wp-content/uploads/' . $image_meta['file'];
    1007 
    1008                 foreach ( $intermediates as $int ) {
    1009                         $image_url = wp_get_attachment_image_url( self::$large_id, $int );
    1010                         $size_array = $this->_get_image_size_array_from_name( $int );
    1011                         $this->assertSame( $expected, wp_calculate_image_srcset( $size_array, $image_url, $image_meta ) );
    1012                 }
     1024                        $size_array = $this->_get_image_size_array_from_meta( $image_meta, $int );
     1025                        $expected_srcset = $this->_src_first( $expected, $image_url, $size_array[0] );
     1026                        $this->assertSame( $expected_srcset, wp_calculate_image_srcset( $size_array, $image_url, $image_meta ) );
     1027                }
    10131028        }
    10141029
     
    11241139                );
    11251140
    1126                 $expected_srcset = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/2015/12/test-300x150.png 300w, http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/2015/12/test-768x384.png 768w, http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/2015/12/test-1024x512.png 1024w, http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/2015/12/test.png 2000w';
     1141                $expected_srcset = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/2015/12/test.png 2000w, http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/2015/12/test-300x150.png 300w, http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/2015/12/test-768x384.png 768w, http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/2015/12/test-1024x512.png 1024w';
    11271142
    11281143                $this->assertSame( $expected_srcset, wp_calculate_image_srcset( $size_array, $image_src, $image_meta ) );
     
    12271242                $expected = "";
    12281243
    1229                 foreach( $image_meta['sizes'] as $name => $size ) {
     1244                foreach ( $image_meta['sizes'] as $name => $size ) {
    12301245                        // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4.
    12311246                        if ( in_array( $name, $intermediates ) ) {
     
    12361251                $expected .= $uploads_dir . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
    12371252
    1238                 $this->assertSame( $expected, $srcset );
     1253                $expected_srcset = $this->_src_first( $expected, $uploads_dir . $image_meta['file'], $size_array[0] );
     1254
     1255                $this->assertSame( $expected_srcset, $srcset );
    12391256        }
    12401257
     
    12741291         */
    12751292        function test_wp_get_attachment_image_sizes() {
    1276                 // Test sizes against the default WP sizes.
    1277                 $intermediates = array('thumbnail', 'medium', 'medium_large', 'large');
     1293                // Test sizes against the default WP sizes.
     1294                $intermediates = array('thumbnail', 'medium', 'medium_large', 'large');
    12781295
    12791296                // Make sure themes aren't filtering the sizes array.
    12801297                remove_all_filters( 'wp_calculate_image_sizes' );
    12811298
    1282                 foreach( $intermediates as $int_size ) {
    1283                         $image = wp_get_attachment_image_src( self::$large_id, $int_size );
     1299                foreach( $intermediates as $int_size ) {
     1300                        $image = wp_get_attachment_image_src( self::$large_id, $int_size );
    12841301
    12851302                        $expected = '(max-width: ' . $image[1] . 'px) 100vw, ' . $image[1] . 'px';
     
    12951312        function test_wp_calculate_image_sizes() {
    12961313                // Test sizes against the default WP sizes.
    1297                 $intermediates = array('thumbnail', 'medium', 'medium_large', 'large');
    1298                 $image_meta = wp_get_attachment_metadata( self::$large_id );
     1314                $intermediates = array( 'thumbnail', 'medium', 'medium_large', 'large' );
     1315                $image_meta = wp_get_attachment_metadata( self::$large_id );
    12991316
    13001317                // Make sure themes aren't filtering the sizes array.
    13011318                remove_all_filters( 'wp_calculate_image_sizes' );
    13021319
    1303                 foreach( $intermediates as $int_size ) {
    1304                         $size_array = $this->_get_image_size_array_from_name( $int_size );
    1305                         $image_src = $image_meta['sizes'][$int_size]['file'];
     1320                foreach ( $intermediates as $int_size ) {
     1321                        $size_array = $this->_get_image_size_array_from_meta( $image_meta, $int_size );
     1322                        $image_src = $image_meta['sizes'][ $int_size ]['file'];
    13061323                        list( $width, $height ) = $size_array;
    13071324
     
    13181335        function test_wp_make_content_images_responsive() {
    13191336                $image_meta = wp_get_attachment_metadata( self::$large_id );
    1320                 $size_array = $this->_get_image_size_array_from_name( 'medium' );
     1337                $size_array = $this->_get_image_size_array_from_meta( $image_meta, 'medium' );
    13211338
    13221339                $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta ) );
     
    14511468        function test_wp_make_content_images_responsive_schemes() {
    14521469                $image_meta = wp_get_attachment_metadata( self::$large_id );
    1453                 $size_array = $this->_get_image_size_array_from_name( 'medium' );
     1470                $size_array = $this->_get_image_size_array_from_meta( $image_meta, 'medium' );
    14541471
    14551472                $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta ) );
     
    14811498
    14821499                $this->assertSame( $expected, $actual );
    1483 }
     1500        }
    14841501
    14851502        /**
     
    15181535                $_SERVER['HTTPS'] = 'on';
    15191536
    1520                 $expected = 'https://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test-300x150.jpg 300w, https://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test-1024x512.jpg 1024w, https://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg 1200w';
     1537                $expected = 'https://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test-1024x512.jpg 1024w, https://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test-300x150.jpg 300w, https://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg 1200w';
    15211538                $actual   = wp_calculate_image_srcset( $size_array, $image_url, $image_meta );
    15221539
Note: See TracChangeset for help on using the changeset viewer.