Make WordPress Core

Ticket #34430: 34430.3.diff

File 34430.3.diff, 30.1 KB (added by azaozz, 8 years ago)
  • src/wp-includes/media.php

     
    813813
    814814                // Generate srcset and sizes if not already present.
    815815                if ( empty( $attr['srcset'] ) ) {
    816                         $srcset = wp_get_attachment_image_srcset( $attachment_id, $size );
    817                         $sizes  = wp_get_attachment_image_sizes( $attachment_id, $size, $width );
     816                        $image_meta = wp_get_attachment_metadata( $attachment_id );
     817                        $size_array = array( absint( $width ), absint( $height ) );
     818                        $srcset = wp_get_attachment_image_srcset( $size_array, $image_meta, $attachment_id );
    818819
    819                         if ( $srcset && $sizes ) {
     820                        if ( $srcset ) {
    820821                                $attr['srcset'] = $srcset;
    821822
    822                                 if ( empty( $attr['sizes'] ) ) {
     823                                if ( empty( $attr['sizes'] ) && ( $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id ) ) ) {
    823824                                        $attr['sizes'] = $sizes;
    824825                                }
    825826                        }
     
    864865}
    865866
    866867/**
     868 * Private, do not use
     869 */
     870function _wp_upload_dir_baseurl() {
     871        static $baseurl = null;
     872
     873        if ( ! $baseurl ) {
     874                $uploads_dir = wp_upload_dir();
     875                $baseurl = $uploads_dir['baseurl'];
     876        }
     877
     878        return $baseurl;
     879}
     880
     881// TODO: needed??
     882/**
     883 * Private, do not use
     884 */
     885function _wp_get_image_size_from_meta( $size, $image_meta ) {
     886        if ( $size === 'full' ) {
     887                return array(
     888                        absint( $image_meta['width'] ),
     889                        absint( $image_meta['height'] ),
     890                );
     891        } elseif ( ! empty( $image_meta['sizes'][$size] ) ) {
     892                return array(
     893                        absint( $image_meta['sizes'][$size]['width'] ),
     894                        absint( $image_meta['sizes'][$size]['height'] ),
     895                );
     896        }
     897
     898        return false;
     899}
     900
     901/**
    867902 * Retrieves an array of URLs and pixel widths representing sizes of an image.
    868903 *
    869904 * The purpose is to populate a source set when creating responsive image markup.
     
    870905 *
    871906 * @since 4.4.0
    872907 *
    873  * @param int          $attachment_id Image attachment ID.
    874  * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    875  *                                    values in pixels (in that order). Default 'medium'.
     908 * @param array $size_array    Array of width and height values in pixels (in that order).
     909 * @param array $image_meta    The image meta data.
     910 * @param int   $attachment_id Optional. Image attachment ID. Used only for the filter.
     911 *
    876912 * @return array|bool $sources {
    877913 *     Array image candidate values containing a URL, descriptor type, and
    878914 *     descriptor value. False if none exist.
     
    886922 * }
    887923 *
    888924 */
    889 function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' ) {
    890         // Get the intermediate size.
    891         $image = image_get_intermediate_size( $attachment_id, $size );
    892 
    893         // Get the post meta.
    894         $img_meta = wp_get_attachment_metadata( $attachment_id );
    895         if ( ! is_array( $img_meta ) ) {
     925function wp_get_attachment_image_srcset_array( $size_array, $image_meta, $attachment_id = 0 ) {
     926        if ( empty( $image_meta['sizes'] ) ) {
    896927                return false;
    897928        }
    898929
    899         // Extract the height and width from the intermediate or the full size.
    900         $img_width  = ( $image ) ? $image['width']  : $img_meta['width'];
    901         $img_height = ( $image ) ? $image['height'] : $img_meta['height'];
     930        $img_sizes = $image_meta['sizes'];
    902931
    903         // Bail early if the width isn't greater than zero.
    904         if ( ! $img_width > 0 ) {
     932        // Get the height and width for the image.
     933        $img_width = (int) $size_array[0];
     934        $img_height = (int) $size_array[1];
     935
     936        // Bail early if error/no width.
     937        if ( $img_width < 1 ) {
    905938                return false;
    906939        }
    907940
    908         // Use the URL from the intermediate size or build the url from the metadata.
    909         if ( ! empty( $image['url'] ) ) {
    910                 $img_url = $image['url'];
    911         } else {
    912                 $uploads_dir = wp_upload_dir();
    913                 $img_file = ( $image ) ? path_join( dirname( $img_meta['file'] ) , $image['file'] ) : $img_meta['file'];
    914                 $img_url = $uploads_dir['baseurl'] . '/' . $img_file;
    915         }
    916 
    917         $img_sizes = $img_meta['sizes'];
    918 
    919941        // Add full size to the img_sizes array.
    920942        $img_sizes['full'] = array(
    921                 'width'  => $img_meta['width'],
    922                 'height' => $img_meta['height'],
    923                 'file'   => wp_basename( $img_meta['file'] )
     943                'width'  => $image_meta['width'],
     944                'height' => $image_meta['height'],
     945                'file'   => wp_basename( $image_meta['file'] ),
    924946        );
    925947
     948        $img_baseurl = _wp_upload_dir_baseurl();
     949        $dirname = dirname( $image_meta['file'] );
     950
     951        if ( $dirname !== '.' ) {
     952                $img_baseurl = path_join( $img_baseurl, $dirname );
     953        }
     954
    926955        // Calculate the image aspect ratio.
    927956        $img_ratio = $img_height / $img_width;
    928957
     
    931960         * contain a unique hash. Look for that hash and use it later to filter
    932961         * out images that are leftovers from previous versions.
    933962         */
    934         $img_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash );
     963        $img_edited = preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash );
    935964
    936965        /**
    937966         * Filter the maximum width included in a srcset attribute.
     
    938967         *
    939968         * @since 4.4.0
    940969         *
    941          * @param array|string $size Size of image, either array or string.
     970         * @param array|string $size_array Size of image, either array or string.
    942971         */
    943         $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size );
     972        $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size_array );
    944973
    945         /*
    946          * Set up arrays to hold url candidates and matched image sources so
    947          * we can avoid duplicates without looping through the full sources array
    948          */
    949         $candidates = $sources = array();
     974        // Array to hold url candidates.
     975        $sources = array();
    950976
    951977        /*
    952          * Loop through available images and only use images that are resized
     978         * Loop through available images. Only use images that are resized
    953979         * versions of the same rendition.
    954980         */
    955981        foreach ( $img_sizes as $img ) {
    956982
    957                 // Filter out images that are leftovers from previous renditions.
     983                // Filter out images that are from previous renditions.
    958984                if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) {
    959985                        continue;
    960986                }
     
    964990                        continue;
    965991                }
    966992
    967                 $candidate_url = path_join( dirname( $img_url ), $img['file'] );
     993                $candidate_url = path_join( $img_baseurl, $img['file'] );
    968994
    969995                // Calculate the new image ratio.
    970996                if ( $img['width'] ) {
     
    9741000                }
    9751001
    9761002                // If the new ratio differs by less than 0.01, use it.
    977                 if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! in_array( $candidate_url, $candidates ) ) {
    978                         // Add the URL to our list of candidates.
    979                         $candidates[] = $candidate_url;
    980 
     1003                if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) {
    9811004                        // Add the url, descriptor, and value to the sources array to be returned.
    982                         $sources[] = array(
     1005                        $sources[ $candidate_url ] = array(
    9831006                                'url'        => $candidate_url,
    9841007                                'descriptor' => 'w',
    9851008                                'value'      => $img['width'],
     
    9921015         *
    9931016         * @since 4.4.0
    9941017         *
    995          * @param array        $sources       An array of image urls and widths.
    996          * @param int          $attachment_id Attachment ID for image.
    997          * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    998          *                                    values in pixels (in that order). Default 'medium'.
     1018         * @param array $sources       An array of image urls and widths.
     1019         * @param array $size_array    Image size. Array of width and height values in pixels (in that order).
     1020         * @param array $image_meta    The image meta data.
     1021         * @param int   $attachment_id Attachment ID for image.
    9991022         */
    1000         return apply_filters( 'wp_get_attachment_image_srcset_array', $sources, $attachment_id, $size );
     1023        return apply_filters( 'wp_get_attachment_image_srcset_array', array_values( $sources ), $size_array, $image_meta, $attachment_id );
    10011024}
    10021025
    10031026/**
     
    10051028 *
    10061029 * @since 4.4.0
    10071030 *
    1008  * @param int          $attachment_id Image attachment ID.
    1009  * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    1010  *                                    values in pixels (in that order). Default 'medium'.
    1011  * @return string|bool A 'srcset' value string or false.
     1031 * @param  int   $image_meta The image meta data.
     1032 * @param  array $size_array Image size. An array of width and height values in pixels (in that order).
     1033 * @return string|bool       A 'srcset' value string or false.
    10121034 */
    1013 function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium' ) {
    1014         $srcset_array = wp_get_attachment_image_srcset_array( $attachment_id, $size );
     1035function wp_get_attachment_image_srcset( $size_array, $image_meta, $attachment_id = 0 ) {
     1036        $srcset_array = wp_get_attachment_image_srcset_array( $size_array, $image_meta, $attachment_id );
    10151037
    10161038        // Only return a srcset value if there is more than one source.
    1017         if ( count( $srcset_array ) <= 1 ) {
     1039        if ( count( $srcset_array ) < 2 ) {
    10181040                return false;
    10191041        }
    10201042
     
    10281050         *
    10291051         * @since 4.4.0
    10301052         *
    1031          * @param string       $srcset        A source set formated for a `srcset` attribute.
    1032          * @param int          $attachment_id Attachment ID for image.
    1033          * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    1034          *                                    values in pixels (in that order). Default 'medium'.
     1053         * @param string $srcset        A source set formated for a `srcset` attribute.
     1054         * @param array  $size_array    Image size. Array of width and height values in pixels (in that order).
     1055         * @param array  $image_meta    The image meta data.
     1056         * @param int    $attachment_id Image attachment ID.
    10351057         */
    1036         return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size );
     1058        return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $size_array, $image_meta, $attachment_id );
    10371059}
    10381060
    10391061/**
    1040  * Retrieves a source size attribute for an image from an array of values.
     1062 * Create `sizes` attribute value for an image.
    10411063 *
    10421064 * @since 4.4.0
    10431065 *
    1044  * @param int          $attachment_id Image attachment ID.
    1045  * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    1046  *                                    values in pixels (in that order). Default 'medium'.
    1047  * @param int          $width         Optional. Display width of the image.
     1066 * @param int|array $size          The width of the image or an array( $width, $height ).
     1067 * @param array     $image_meta    Optional. The image meta data.
     1068 * @param int       $attachment_id Optional. Image attachment ID.
     1069 *
    10481070 * @return string|bool A valid source size value for use in a 'sizes' attribute or false.
    10491071 */
    1050 function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width = null ) {
    1051         // Try to get the image width from the $width parameter.
    1052         if ( is_numeric( $width ) ) {
    1053                 $img_width = (int) $width;
    1054         // Next, see if a width value was passed in the $size parameter.
     1072function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0 ) {
     1073        $width = 0;
     1074
     1075        if ( is_numeric( $size ) ) {
     1076                $width = absint( $size );
    10551077        } elseif ( is_array( $size ) ) {
    1056                 $img_width = $size[0];
    1057         // Finally, use the $size name to return the width of the image.
    1058         } else {
    1059                 $image = image_get_intermediate_size( $attachment_id, $size );
    1060                 $img_width = $image ? $image['width'] : false;
     1078                $width = absint( $size[0] );
    10611079        }
    10621080
    1063         // Bail early if $img_width isn't set.
    1064         if ( ! $img_width ) {
     1081        if ( ! $width ) {
    10651082                return false;
    10661083        }
    10671084
    10681085        // Setup the default sizes attribute.
    1069         $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $img_width );
     1086        $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', (int) $width );
    10701087
    10711088        /**
    10721089         * Filter the output of wp_get_attachment_image_sizes().
     
    10791096         *                                    values in pixels (in that order). Default 'medium'.
    10801097         * @param int          $width         Display width of the image.
    10811098         */
    1082         return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $attachment_id, $size, $width );
     1099        return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $width, $image_meta, $attachment_id );
    10831100}
    10841101
    10851102/**
     
    10871104 *
    10881105 * @since 4.4.0
    10891106 *
    1090  * @see wp_img_add_srcset_and_sizes()
     1107 * @see wp_image_add_srcset_and_sizes()
    10911108 *
    10921109 * @param string $content The raw post content to be filtered.
    10931110 * @return string Converted content with 'srcset' and 'sizes' attributes added to images.
     
    10951112function wp_make_content_images_responsive( $content ) {
    10961113        $images = get_media_embedded_in_content( $content, 'img' );
    10971114
    1098         $attachment_ids = array();
     1115        $selected_images = array();
    10991116
    11001117        foreach( $images as $image ) {
    1101                 if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) {
    1102                         $attachment_id = (int) $class_id[1];
    1103                         if ( $attachment_id ) {
    1104                                 $attachment_ids[] = $attachment_id;
    1105                         }
     1118                if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) &&
     1119                        ( $attachment_id = absint( $class_id[1] ) ) ) {
     1120
     1121                        $selected_images[ $attachment_id ] = $image;
    11061122                }
    11071123        }
    11081124
    1109         if ( 0 < count( $attachment_ids ) ) {
     1125        if ( count( $selected_images ) > 1 ) {
    11101126                /*
    1111                  * Warm object caches for use with wp_get_attachment_metadata.
     1127                 * Warm object cache for use with get_post_meta().
    11121128                 *
    11131129                 * To avoid making a database call for each image, a single query
    11141130                 * warms the object cache with the meta information for all images.
    11151131                 */
    1116                 _prime_post_caches( $attachment_ids, false, true );
     1132                update_meta_cache( 'post', array_keys( $selected_images ) );
    11171133        }
    11181134
    1119         foreach( $images as $image ) {
    1120                 $content = str_replace( $image, wp_img_add_srcset_and_sizes( $image ), $content );
     1135        foreach ( $selected_images as $attachment_id => $image ) {
     1136                $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
     1137                $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
    11211138        }
    11221139
    11231140        return $content;
     
    11311148 * @see wp_get_attachment_image_srcset()
    11321149 * @see wp_get_attachment_image_sizes()
    11331150 *
    1134  * @param string $image An HTML 'img' element to be filtered.
     1151 * @param string $image         An HTML 'img' element to be filtered.
     1152 * @param array  $image_meta    The image meta data.
     1153 * @param int    $attachment_id Image attachment ID.
    11351154 * @return string Converted 'img' element with `srcset` and `sizes` attributes added.
    11361155 */
    1137 function wp_img_add_srcset_and_sizes( $image ) {
    1138         // Return early if a 'srcset' attribute already exists.
    1139         if ( false !== strpos( $image, ' srcset="' ) ) {
     1156function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) {
     1157        // Ensure the image meta exists
     1158        if ( empty( $image_meta['sizes'] ) ) {
    11401159                return $image;
    11411160        }
    11421161
    1143         // Parse id, size, width, and height from the `img` element.
    1144         $id     = preg_match( '/wp-image-([0-9]+)/i', $image, $match_id     ) ? (int) $match_id[1]     : false;
    1145         $size   = preg_match( '/size-([^\s|"]+)/i',   $image, $match_size   ) ? $match_size[1]         : false;
    1146         $width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : false;
     1162        $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : '';
     1163        list( $src ) = explode( '?', $src );
    11471164
    1148         if ( $id && ! $size ) {
    1149                 $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : false;
    1150 
    1151                 if ( $width && $height ) {
    1152                         $size = array( $width, $height );
    1153                 }
     1165        // Return early if we coudn't get the image source.
     1166        if ( ! $src ) {
     1167                return $image;
    11541168        }
    11551169
    1156         /*
    1157          * If attempts to parse the size value failed, attempt to use the image
    1158          * metadata to match the 'src' against the available sizes for an attachment.
    1159          */
    1160         if ( $id && ! $size ) {
    1161                 $meta = wp_get_attachment_metadata( $id );
     1170        // Bail early when an image has been inserted and later edited.
     1171        // We don't have the previous image meta to generate srcset.
     1172        if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) &&
     1173                strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) {
    11621174
    1163                 // Parse the image src value from the img element.
    1164                 $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false;
     1175                return $image;
     1176        }
    11651177
    1166                 // Return early if the metadata does not exist or the src value is empty.
    1167                 if ( ! $meta || ! $src ) {
    1168                         return $image;
    1169                 }
     1178        $width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : 0;
     1179        $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0;
    11701180
     1181        if ( ! $width || ! $height ) {
    11711182                /*
    1172                  * First, see if the file is the full size image. If not, loop through
    1173                  * the intermediate sizes until we find a file that matches.
     1183                 * If attempts to parse the size value failed, attempt to use the image
     1184                 * metadata to match the 'src' against the available sizes for an attachment.
    11741185                 */
    11751186                $image_filename = wp_basename( $src );
    11761187
    1177                 if ( $image_filename === basename( $meta['file'] ) ) {
    1178                         $size = 'full';
     1188                if ( $image_filename === basename( $image_meta['file'] ) ) {
     1189                        $width = (int) $image_meta['width'];
     1190                        $height = (int) $image_meta['height'];
    11791191                } else {
    1180                         foreach( $meta['sizes'] as $image_size => $image_size_data ) {
     1192                        foreach( $image_meta['sizes'] as $image_size_data ) {
    11811193                                if ( $image_filename === $image_size_data['file'] ) {
    1182                                         $size = $image_size;
     1194                                        $width = (int) $image_size_data['width'];
     1195                                        $height = (int) $image_size_data['height'];
    11831196                                        break;
    11841197                                }
    11851198                        }
    11861199                }
     1200        }
    11871201
     1202        if ( ! $width || ! $height ) {
     1203                return $image;
    11881204        }
    11891205
    1190         // If ID and size exist, try for 'srcset' and 'sizes' and update the markup.
    1191         if ( $id && $size ) {
    1192                 $srcset = wp_get_attachment_image_srcset( $id, $size );
    1193                 $sizes  = wp_get_attachment_image_sizes( $id, $size, $width );
     1206        $size_array = array( $width, $height );
     1207        $srcset = wp_get_attachment_image_srcset( $size_array, $image_meta, $attachment_id );
     1208        $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id );
    11941209
    1195                 if ( $srcset && $sizes ) {
    1196                         // Format the srcset and sizes string and escape attributes.
    1197                         $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) );
     1210        if ( $srcset && $sizes ) {
     1211                // Format the srcset and sizes string and escape attributes.
     1212                $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) );
    11981213
    1199                         // Add srcset and sizes attributes to the image markup.
    1200                         $image = preg_replace( '/<img ([^>]+)[\s?][\/?]>/', '<img $1' . $srcset_and_sizes . ' />', $image );
    1201                 }
     1214                // Add srcset and sizes attributes to the image markup.
     1215                $image = preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $srcset_and_sizes . ' />', $image );
    12021216        }
    12031217
    12041218        return $image;
  • tests/phpunit/tests/media.php

     
    716716        }
    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         */
    721739        function test_wp_get_attachment_image_srcset_array() {
    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                );
    742760
     
    744762                $sizes = array( 'medium', 'large', 'full', 'yoav' );
    745763
    746764                foreach ( $sizes as $size ) {
    747                         $this->assertSame( $expected, wp_get_attachment_image_srcset_array( self::$large_id, $size ) );
     765                        $size_array = $this->_get_image_size_array_from_name( $size );
     766                        $this->assertSame( $expected, wp_get_attachment_image_srcset_array( $size_array, $image_meta, $id ) );
    748767                }
    749768        }
    750769
     
    762781                $filename = DIR_TESTDATA . '/images/test-image-large.png';
    763782                $id = self::factory()->attachment->create_upload_object( $filename );
    764783
    765                 $image = wp_get_attachment_metadata( $id );
     784                $image_meta = wp_get_attachment_metadata( $id );
    766785
    767786                $expected = array(
    768787                        array(
    769                                 'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['sizes']['medium']['file'],
     788                                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['medium']['file'],
    770789                                'descriptor' => 'w',
    771                                 'value'      => $image['sizes']['medium']['width'],
     790                                'value'      => $image_meta['sizes']['medium']['width'],
    772791                        ),
    773792                        array(
    774                                 'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['sizes']['large']['file'],
     793                                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['large']['file'],
    775794                                'descriptor' => 'w',
    776                                 'value'      => $image['sizes']['large']['width'],
     795                                'value'      => $image_meta['sizes']['large']['width'],
    777796                        ),
    778797                        array(
    779                                 'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'],
     798                                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'],
    780799                                'descriptor' => 'w',
    781                                 'value'      => $image['width'],
     800                                'value'      => $image_meta['width'],
    782801                        ),
    783802                );
    784803
     
    786805                $sizes = array( 'medium', 'large', 'full', 'yoav' );
    787806
    788807                foreach ( $sizes as $size ) {
    789                         $this->assertSame( $expected, wp_get_attachment_image_srcset_array( $id, $size ) );
     808                        $size_array = $this->_get_image_size_array_from_name( $size );
     809                        $this->assertSame( $expected, wp_get_attachment_image_srcset_array( $size_array, $image_meta, $id ) );
    790810                }
    791811
    792812                // Leave the uploads option the way you found it.
     
    799819        function test_wp_get_attachment_image_srcset_array_with_edits() {
    800820                // For this test we're going to mock metadata changes from an edit.
    801821                // Start by getting the attachment metadata.
    802                 $meta = wp_get_attachment_metadata( self::$large_id );
     822                $image_meta = wp_get_attachment_metadata( self::$large_id );
     823                $size_array = $this->_get_image_size_array_from_name( 'medium' );
    803824
    804825                // Copy hash generation method used in wp_save_image().
    805826                $hash = 'e' . time() . rand(100, 999);
    806827
    807828                // 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'] );
     829                $filename_base = basename( $image_meta['file'], '.png' );
     830                $image_meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['file'] );
     831                $image_meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['medium']['file'] );
     832                $image_meta['sizes']['large']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['large']['file'] );
    811833
    812                 // Save edited metadata.
    813                 wp_update_attachment_metadata( self::$large_id, $meta );
    814 
    815834                // Calculate a srcset array.
    816                 $sizes = wp_get_attachment_image_srcset_array( self::$large_id, 'medium' );
     835                $sizes = wp_get_attachment_image_srcset_array( $size_array, $image_meta, self::$large_id );
    817836
    818837                // Test to confirm all sources in the array include the same edit hash.
    819838                foreach ( $sizes as $size ) {
     
    825844         * @ticket 33641
    826845         */
    827846        function test_wp_get_attachment_image_srcset_array_false() {
    828                 $sizes = wp_get_attachment_image_srcset_array( 99999, 'foo' );
     847                $sizes = wp_get_attachment_image_srcset_array( array( 400, 300 ), array(), 99999 );
    829848
    830849                // For canola.jpg we should return
    831850                $this->assertFalse( $sizes );
     
    835854         * @ticket 33641
    836855         */
    837856        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 );
    842857                $file = get_attached_file( self::$large_id );
     858                $image_meta = wp_generate_attachment_metadata( self::$large_id, $file );
    843859
    844                 $data = wp_generate_attachment_metadata( self::$large_id, $file );
    845                 wp_update_attachment_metadata( self::$large_id, $data );
     860                // Remove the sizes for 'large' and 'full'
     861                $image_meta['width'] = 0;
     862                $image_meta['height'] = 0;
     863                $image_meta['sizes']['large']['width'] = 0;
     864                $image_meta['sizes']['large']['height'] = 0;
    846865
    847                 $srcset = wp_get_attachment_image_srcset_array( self::$large_id, 'medium' );
     866                $size_array = $this->_get_image_size_array_from_name( 'medium' );
    848867
    849                 update_post_meta( self::$large_id, '_wp_attachment_metadata', $old_meta );
     868                $srcset = wp_get_attachment_image_srcset( $size_array, $image_meta, self::$large_id );
    850869
    851870                // The srcset should be false.
    852871                $this->assertFalse( $srcset );
     
    853872        }
    854873
    855874        /**
    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         /**
    867875         * @ticket 33641
    868876         */
    869877        function test_wp_get_attachment_image_srcset() {
    870                 $sizes = wp_get_attachment_image_srcset( self::$large_id, 'full-size' );
     878                $image_meta = wp_get_attachment_metadata( self::$large_id );
     879                $size_array = array( 1600, 1200 ); // full size
    871880
    872                 $image = wp_get_attachment_metadata( self::$large_id );
     881                $sizes = wp_get_attachment_image_srcset( $size_array, $image_meta, self::$large_id );
     882
    873883                $year_month = date('Y/m');
    874884
    875885                $expected = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month = date('Y/m') . '/'
    876                         . $image['sizes']['medium']['file'] . ' ' . $image['sizes']['medium']['width'] . 'w, ';
     886                        . $image_meta['sizes']['medium']['file'] . ' ' . $image_meta['sizes']['medium']['width'] . 'w, ';
    877887                $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';
     888                        . $image_meta['sizes']['large']['file'] . ' ' . $image_meta['sizes']['large']['width'] . 'w, ';
     889                $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
    880890
    881891                $this->assertSame( $expected, $sizes );
    882892        }
     
    885895         * @ticket 33641
    886896         */
    887897        function test_wp_get_attachment_image_srcset_single_srcset() {
     898                $image_meta = wp_get_attachment_metadata( self::$large_id );
     899                $size_array = array( 150, 150 );
    888900                /*
    889901                 * In our tests, thumbnails will only return a single srcset candidate,
    890902                 * so we shouldn't return a srcset value in order to avoid unneeded markup.
    891903                 */
    892                 $sizes = wp_get_attachment_image_srcset( self::$large_id, 'thumbnail' );
     904                $sizes = wp_get_attachment_image_srcset( $size_array, $image_meta, self::$large_id );
    893905
    894906                $this->assertFalse( $sizes );
    895907        }
     
    899911         */
    900912        function test_wp_get_attachment_image_sizes() {
    901913                // Test sizes against the default WP sizes.
    902                 $intermediates = array('thumbnail', 'medium', 'large');
     914                $intermediates = array( 'thumbnail', 'medium', 'large' );
    903915
    904                 foreach( $intermediates as $int ) {
    905                         $width = get_option( $int . '_size_w' );
     916                foreach( $intermediates as $int_size ) {
     917                        $size_array = $this->_get_image_size_array_from_name( $int_size );
     918                        list( $width, $height ) = $size_array;
    906919
    907920                        $expected = '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
    908                         $sizes = wp_get_attachment_image_sizes( self::$large_id, $int );
     921                        $sizes = wp_get_attachment_image_sizes( $size_array );
    909922
    910                         $this->assertSame($expected, $sizes);
     923                        $this->assertSame( $expected, $sizes );
    911924                }
    912925        }
    913926
     
    914927        /**
    915928         * @ticket 33641
    916929         */
    917         function test_wp_get_attachment_image_sizes_with_width() {
    918                 $width = 350;
     930        function test_wp_make_content_images_responsive() {
     931                $image_meta = wp_get_attachment_metadata( self::$large_id );
     932                $size_array = $this->_get_image_size_array_from_name( 'medium' );
    919933
    920                 $expected = '(max-width: 350px) 100vw, 350px';
    921                 $sizes = wp_get_attachment_image_sizes( self::$large_id, 'medium', $width );
     934                $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( $size_array, $image_meta, self::$large_id ) );
     935                $sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( $size_array, $image_meta, self::$large_id ) );
    922936
    923                 $this->assertSame( $expected, $sizes );
    924         }
    925 
    926         /**
    927          * @ticket 33641
    928          */
    929         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' ) );
    932 
    933937                // Function used to build HTML for the editor.
    934938                $img = get_image_tag( self::$large_id, '', '', '', 'medium' );
    935939                $img_no_size = str_replace( 'size-', '', $img );