WordPress.org

Make WordPress Core

Ticket #34430: 34430.4.diff

File 34430.4.diff, 30.8 KB (added by joemcgill, 5 years ago)
  • src/wp-includes/media.php

    diff --git src/wp-includes/media.php src/wp-includes/media.php
    index 30df322..739408d 100644
    function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = fa 
    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                        }
    function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon 
    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/**
     882 * Private, do not use
     883 */
     884function _wp_get_image_size_from_meta( $size, $image_meta ) {
     885        if ( $size === 'full' ) {
     886                return array(
     887                        absint( $image_meta['width'] ),
     888                        absint( $image_meta['height'] ),
     889                );
     890        } elseif ( ! empty( $image_meta['sizes'][$size] ) ) {
     891                return array(
     892                        absint( $image_meta['sizes'][$size]['width'] ),
     893                        absint( $image_meta['sizes'][$size]['height'] ),
     894                );
     895        }
     896
     897        return false;
     898}
     899
     900/**
    867901 * Retrieves an array of URLs and pixel widths representing sizes of an image.
    868902 *
    869903 * The purpose is to populate a source set when creating responsive image markup.
    870904 *
    871905 * @since 4.4.0
    872906 *
    873  * @param int          $attachment_id Image attachment ID.
     907 * @param int          $attachment_id Optional. Image attachment ID.
    874908 * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    875909 *                                    values in pixels (in that order). Default 'medium'.
     910 * @param array        $image_meta    Optional. The image meta data.
     911 *
    876912 * @return array|bool $sources {
    877913 *     Array image candidate values containing a URL, descriptor type, and
    878914 *     descriptor value. False if none exist.
    function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon 
    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 );
     925function wp_get_attachment_image_srcset_array( $attachment_id = 0, $size = 'medium', $image_meta = null ) {
     926        if ( ! is_array($image_meta ) ) {
     927                $image_meta = wp_get_attachment_metadata( $attachment_id );
     928        }
    892929
    893         // Get the post meta.
    894         $img_meta = wp_get_attachment_metadata( $attachment_id );
    895         if ( ! is_array( $img_meta ) ) {
     930        if ( empty( $image_meta['sizes'] ) ) {
    896931                return false;
    897932        }
    898933
    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'];
     934        $img_sizes = $image_meta['sizes'];
    902935
    903         // Bail early if the width isn't greater than zero.
    904         if ( ! $img_width > 0 ) {
    905                 return false;
    906         }
     936        $size_array = is_array( $size ) ? $size : _wp_get_image_size_from_meta( $size, $image_meta );
    907937
    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         }
     938        // Get the height and width for the image.
     939        $img_width = (int) $size_array[0];
     940        $img_height = (int) $size_array[1];
    916941
    917         $img_sizes = $img_meta['sizes'];
     942        // Bail early if error/no width.
     943        if ( $img_width < 1 ) {
     944                return false;
     945        }
    918946
    919947        // Add full size to the img_sizes array.
    920948        $img_sizes['full'] = array(
    921                 'width'  => $img_meta['width'],
    922                 'height' => $img_meta['height'],
    923                 'file'   => wp_basename( $img_meta['file'] )
     949                'width'  => $image_meta['width'],
     950                'height' => $image_meta['height'],
     951                'file'   => wp_basename( $image_meta['file'] ),
    924952        );
    925953
     954        $img_baseurl = _wp_upload_dir_baseurl();
     955        $dirname = dirname( $image_meta['file'] );
     956
     957        if ( $dirname !== '.' ) {
     958                $img_baseurl = path_join( $img_baseurl, $dirname );
     959        }
     960
    926961        // Calculate the image aspect ratio.
    927962        $img_ratio = $img_height / $img_width;
    928963
    function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' 
    931966         * contain a unique hash. Look for that hash and use it later to filter
    932967         * out images that are leftovers from previous versions.
    933968         */
    934         $img_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash );
     969        $img_edited = preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash );
    935970
    936971        /**
    937972         * Filter the maximum width included in a srcset attribute.
    938973         *
    939974         * @since 4.4.0
    940975         *
    941          * @param array|string $size Size of image, either array or string.
     976         * @param array|string $size_array Size of image, either array or string.
    942977         */
    943         $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size );
     978        $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size_array );
    944979
    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();
     980        // Array to hold url candidates.
     981        $sources = array();
    950982
    951983        /*
    952          * Loop through available images and only use images that are resized
    953          * versions of the same rendition.
     984         * Loop through available images. Only use images that are resized
     985         * versions of the same edit.
    954986         */
    955987        foreach ( $img_sizes as $img ) {
    956988
    957                 // Filter out images that are leftovers from previous renditions.
     989                // Filter out images that are from previous edits.
    958990                if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) {
    959991                        continue;
    960992                }
    function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' 
    964996                        continue;
    965997                }
    966998
    967                 $candidate_url = path_join( dirname( $img_url ), $img['file'] );
     999                $candidate_url = $img['file'];
    9681000
    9691001                // Calculate the new image ratio.
    9701002                if ( $img['width'] ) {
    function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' 
    9741006                }
    9751007
    9761008                // 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 
     1009                if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) {
    9811010                        // Add the url, descriptor, and value to the sources array to be returned.
    982                         $sources[] = array(
    983                                 'url'        => $candidate_url,
     1011                        $sources[ $candidate_url ] = array(
     1012                                'url'        => path_join( $img_baseurl, $candidate_url ),
    9841013                                'descriptor' => 'w',
    9851014                                'value'      => $img['width'],
    9861015                        );
    function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' 
    9961025         * @param int          $attachment_id Attachment ID for image.
    9971026         * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    9981027         *                                    values in pixels (in that order). Default 'medium'.
     1028         * @param array        $image_meta    The image meta data.
     1029
    9991030         */
    1000         return apply_filters( 'wp_get_attachment_image_srcset_array', $sources, $attachment_id, $size );
     1031        return apply_filters( 'wp_get_attachment_image_srcset_array', array_values( $sources ), $attachment_id, $size, $image_meta );
    10011032}
    10021033
    10031034/**
    function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' 
    10051036 *
    10061037 * @since 4.4.0
    10071038 *
    1008  * @param int          $attachment_id Image attachment ID.
     1039
     1040 * @param int          $attachment_id Optional. Image attachment ID.
    10091041 * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    10101042 *                                    values in pixels (in that order). Default 'medium'.
     1043 * @param array        $image_meta    Optional. The image meta data.
    10111044 * @return string|bool A 'srcset' value string or false.
    10121045 */
    1013 function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium' ) {
    1014         $srcset_array = wp_get_attachment_image_srcset_array( $attachment_id, $size );
     1046function wp_get_attachment_image_srcset( $attachment_id = 0, $size = 'medium', $image_meta = null ) {
     1047        $srcset_array = wp_get_attachment_image_srcset_array( $attachment_id, $size, $image_meta );
    10151048
    10161049        // Only return a srcset value if there is more than one source.
    1017         if ( count( $srcset_array ) <= 1 ) {
     1050        if ( count( $srcset_array ) < 2 ) {
    10181051                return false;
    10191052        }
    10201053
    function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium' ) { 
    10291062         * @since 4.4.0
    10301063         *
    10311064         * @param string       $srcset        A source set formated for a `srcset` attribute.
    1032          * @param int          $attachment_id Attachment ID for image.
     1065         * @param int          $attachment_id Image attachment ID.
    10331066         * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    10341067         *                                    values in pixels (in that order). Default 'medium'.
     1068         * @param array        $image_meta    The image meta data.
    10351069         */
    1036         return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size );
     1070        return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size, $image_meta );
    10371071}
    10381072
    10391073/**
    1040  * Retrieves a source size attribute for an image from an array of values.
     1074 * Create `sizes` attribute value for an image.
    10411075 *
    10421076 * @since 4.4.0
    10431077 *
    1044  * @param int          $attachment_id Image attachment ID.
     1078 * @param int          $attachment_id Optional. Image attachment ID.
    10451079 * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    10461080 *                                    values in pixels (in that order). Default 'medium'.
    1047  * @param int          $width         Optional. Display width of the image.
     1081 * @param array        $image_meta    Optional. The image meta data.
     1082 *
    10481083 * @return string|bool A valid source size value for use in a 'sizes' attribute or false.
    10491084 */
    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.
     1085function wp_get_attachment_image_sizes( $attachment_id = 0, $size, $image_meta = null ) {
     1086        $width = 0;
     1087
     1088        if ( is_numeric( $size ) ) {
     1089                $width = absint( $size );
    10551090        } 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;
     1091                $width = absint( $size[0] );
     1092        }
     1093
     1094        if ( ! $width && ( $image_meta || $attachment_id ) ) {
     1095                $image_meta = ( $image_meta ) ? $image_meta : wp_get_attachment_metadata( $attachment_id );
     1096                $width = _wp_get_image_size_from_meta( $size, $image_meta )[0];
    10611097        }
    10621098
    1063         // Bail early if $img_width isn't set.
    1064         if ( ! $img_width ) {
     1099        if ( ! $width ) {
    10651100                return false;
    10661101        }
    10671102
    10681103        // Setup the default sizes attribute.
    1069         $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $img_width );
     1104        $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', (int) $width );
    10701105
    10711106        /**
    10721107         * Filter the output of wp_get_attachment_image_sizes().
    function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width 
    10781113         * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    10791114         *                                    values in pixels (in that order). Default 'medium'.
    10801115         * @param int          $width         Display width of the image.
     1116         * @param array        $image_meta    The image meta data.
    10811117         */
    1082         return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $attachment_id, $size, $width );
     1118        return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $attachment_id, $size, $width, $image_meta );
    10831119}
    10841120
    10851121/**
    function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width 
    10871123 *
    10881124 * @since 4.4.0
    10891125 *
    1090  * @see wp_img_add_srcset_and_sizes()
     1126 * @see wp_image_add_srcset_and_sizes()
    10911127 *
    10921128 * @param string $content The raw post content to be filtered.
    10931129 * @return string Converted content with 'srcset' and 'sizes' attributes added to images.
    function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width 
    10951131function wp_make_content_images_responsive( $content ) {
    10961132        $images = get_media_embedded_in_content( $content, 'img' );
    10971133
    1098         $attachment_ids = array();
     1134        $selected_images = array();
    10991135
    11001136        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                         }
     1137                if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) &&
     1138                        ( $attachment_id = absint( $class_id[1] ) ) ) {
     1139
     1140                        $selected_images[$image] = $attachment_id;
    11061141                }
    11071142        }
    11081143
    1109         if ( 0 < count( $attachment_ids ) ) {
     1144        if ( count( $selected_images ) > 1 ) {
    11101145                /*
    1111                  * Warm object caches for use with wp_get_attachment_metadata.
     1146                 * Warm object cache for use with get_post_meta().
    11121147                 *
    11131148                 * To avoid making a database call for each image, a single query
    11141149                 * warms the object cache with the meta information for all images.
    11151150                 */
    1116                 _prime_post_caches( $attachment_ids, false, true );
     1151                update_meta_cache( 'post', array_unique( array_values( ( $selected_images ) ) ) );
    11171152        }
    11181153
    1119         foreach( $images as $image ) {
    1120                 $content = str_replace( $image, wp_img_add_srcset_and_sizes( $image ), $content );
     1154        foreach ( $selected_images as $image => $attachment_id ) {
     1155                $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
     1156                $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
    11211157        }
    11221158
    11231159        return $content;
    function wp_make_content_images_responsive( $content ) { 
    11311167 * @see wp_get_attachment_image_srcset()
    11321168 * @see wp_get_attachment_image_sizes()
    11331169 *
    1134  * @param string $image An HTML 'img' element to be filtered.
     1170 * @param string $image         An HTML 'img' element to be filtered.
     1171 * @param array  $image_meta    The image meta data.
     1172 * @param int    $attachment_id Image attachment ID.
    11351173 * @return string Converted 'img' element with `srcset` and `sizes` attributes added.
    11361174 */
    1137 function wp_img_add_srcset_and_sizes( $image ) {
    1138         // Return early if a 'srcset' attribute already exists.
    1139         if ( false !== strpos( $image, ' srcset="' ) ) {
     1175function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) {
     1176        // Ensure the image meta exists
     1177        if ( empty( $image_meta['sizes'] ) ) {
    11401178                return $image;
    11411179        }
    11421180
    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;
    1147 
    1148         if ( $id && ! $size ) {
    1149                 $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : false;
     1181        $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : '';
     1182        list( $src ) = explode( '?', $src );
    11501183
    1151                 if ( $width && $height ) {
    1152                         $size = array( $width, $height );
    1153                 }
     1184        // Return early if we coudn't get the image source.
     1185        if ( ! $src ) {
     1186                return $image;
    11541187        }
    11551188
    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 );
     1189        // Bail early when an image has been inserted and later edited.
     1190        // We don't have the previous image meta to generate srcset.
     1191        if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) &&
     1192                strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) {
    11621193
    1163                 // Parse the image src value from the img element.
    1164                 $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false;
     1194                return $image;
     1195        }
    11651196
    1166                 // Return early if the metadata does not exist or the src value is empty.
    1167                 if ( ! $meta || ! $src ) {
    1168                         return $image;
    1169                 }
     1197        $width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : 0;
     1198        $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0;
    11701199
     1200        if ( ! $width || ! $height ) {
    11711201                /*
    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.
     1202                 * If attempts to parse the size value failed, attempt to use the image
     1203                 * metadata to match the 'src' against the available sizes for an attachment.
    11741204                 */
    11751205                $image_filename = wp_basename( $src );
    11761206
    1177                 if ( $image_filename === basename( $meta['file'] ) ) {
    1178                         $size = 'full';
     1207                if ( $image_filename === basename( $image_meta['file'] ) ) {
     1208                        $width = (int) $image_meta['width'];
     1209                        $height = (int) $image_meta['height'];
    11791210                } else {
    1180                         foreach( $meta['sizes'] as $image_size => $image_size_data ) {
     1211                        foreach( $image_meta['sizes'] as $image_size_data ) {
    11811212                                if ( $image_filename === $image_size_data['file'] ) {
    1182                                         $size = $image_size;
     1213                                        $width = (int) $image_size_data['width'];
     1214                                        $height = (int) $image_size_data['height'];
    11831215                                        break;
    11841216                                }
    11851217                        }
    11861218                }
     1219        }
    11871220
     1221        if ( ! $width || ! $height ) {
     1222                return $image;
    11881223        }
    11891224
    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 );
     1225        $size_array = array( $width, $height );
     1226        $srcset = wp_get_attachment_image_srcset( $attachment_id, $size_array, $image_meta );
     1227        $sizes = wp_get_attachment_image_sizes( $attachment_id, $size_array, $image_meta );
    11941228
    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) );
     1229        if ( $srcset && $sizes ) {
     1230                // Format the srcset and sizes string and escape attributes.
     1231                $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) );
    11981232
    1199                         // Add srcset and sizes attributes to the image markup.
    1200                         $image = preg_replace( '/<img ([^>]+)[\s?][\/?]>/', '<img $1' . $srcset_and_sizes . ' />', $image );
    1201                 }
     1233                // Add srcset and sizes attributes to the image markup.
     1234                $image = preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $srcset_and_sizes . ' />', $image );
    12021235        }
    12031236
    12041237        return $image;
  • tests/phpunit/tests/media.php

    diff --git tests/phpunit/tests/media.php tests/phpunit/tests/media.php
    index b682b09..0ea12a7 100644
    EOF; 
    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
    EOF; 
    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( self::$large_id, $size_array, $image_meta ) );
    748767                }
    749768        }
    750769
    EOF; 
    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
    EOF; 
    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( $id, $size_array, $image_meta ) );
    790810                }
    791811
    792812                // Leave the uploads option the way you found it.
    EOF; 
    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'] );
    811 
    812                 // Save edited metadata.
    813                 wp_update_attachment_metadata( self::$large_id, $meta );
     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'] );
    814833
    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( self::$large_id, $size_array, $image_meta );
    817836
    818837                // Test to confirm all sources in the array include the same edit hash.
    819838                foreach ( $sizes as $size ) {
    EOF; 
    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( 99999, array( 400, 300 ), array() );
    829848
    830849                // For canola.jpg we should return
    831850                $this->assertFalse( $sizes );
    EOF; 
    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( self::$large_id, $size_array, $image_meta );
    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
     880
     881                $sizes = wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta );
    871882
    872                 $image = wp_get_attachment_metadata( self::$large_id );
    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        }
    EOF; 
    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( self::$large_id, $size_array, $image_meta );
    893905
    894906                $this->assertFalse( $sizes );
    895907        }
    EOF; 
    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( self::$large_id, $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;
    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          */
    929930        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' ) );
     931                $image_meta = wp_get_attachment_metadata( self::$large_id );
     932                $size_array = $this->_get_image_size_array_from_name( 'medium' );
     933
     934                $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta ) );
     935                $sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( self::$large_id, $size_array, $image_meta ) );
    932936
    933937                // Function used to build HTML for the editor.
    934938                $img = get_image_tag( self::$large_id, '', '', '', 'medium' );