Make WordPress Core


Ignore:
Timestamp:
10/28/2015 05:40:04 AM (11 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.