WordPress.org

Make WordPress Core

Ticket #34430: 34430.1.diff

File 34430.1.diff, 29.8 KB (added by azaozz, 6 years ago)
  • src/wp-includes/media.php

     
    812812                $attr = wp_parse_args($attr, $default_attr);
    813813
    814814                // Generate srcset and sizes if not already present.
    815                 if ( empty( $attr['srcset'] ) && ( $srcset = wp_get_attachment_image_srcset( $attachment_id, $size ) ) && ( $sizes = wp_get_attachment_image_sizes( $attachment_id, $size, $width ) ) ) {
    816                         $attr['srcset'] = $srcset;
     815                if ( empty( $attr['srcset'] ) ) {
     816                        $image_meta = wp_get_attachment_metadata( $attachment_id );
     817                        $size_array = array( absint( $width ), absint( $height ) );
    817818
    818                         if ( empty( $attr['sizes'] ) ) {
     819                        if ( $srcset = wp_get_attachment_image_srcset( $size_array, $image_meta, $attachment_id ) ) {
     820                                $attr['srcset'] = $srcset;
     821                        }
     822
     823                        if ( empty( $attr['sizes'] ) && ( $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id ) ) ) {
    819824                                $attr['sizes'] = $sizes;
    820825                        }
    821826                }
     
    859864}
    860865
    861866/**
     867 * Private, do not use
     868 */
     869function _wp_upload_dir_baseurl() {
     870        static $baseurl = null;
     871
     872        if ( ! $baseurl ) {
     873                $uploads_dir = wp_upload_dir();
     874                $baseurl = $uploads_dir['baseurl'];
     875        }
     876
     877        return $baseurl;
     878}
     879
     880// TODO: needed??
     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/**
    862901 * Retrieves an array of URLs and pixel widths representing sizes of an image.
    863902 *
    864903 * The purpose is to populate a source set when creating responsive image markup.
     
    865904 *
    866905 * @since 4.4.0
    867906 *
    868  * @param int          $attachment_id Image attachment ID.
    869  * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    870  *                                    values in pixels (in that order). Default 'medium'.
     907 * @param array $size_array    Array of width and height values in pixels (in that order).
     908 * @param array $image_meta    The image meta data.
     909 * @param int   $attachment_id Optional. Image attachment ID. Used only for the filter.
     910 *
    871911 * @return array|bool $sources {
    872912 *     Array image candidate values containing a URL, descriptor type, and
    873913 *     descriptor value. False if none exist.
     
    881921 * }
    882922 *
    883923 */
    884 function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' ) {
    885         // Get the intermediate size.
    886         $image = image_get_intermediate_size( $attachment_id, $size );
    887 
    888         // Get the post meta.
    889         $img_meta = wp_get_attachment_metadata( $attachment_id );
    890         if ( ! is_array( $img_meta ) ) {
     924function wp_get_attachment_image_srcset_array( $size_array, $image_meta, $attachment_id = 0 ) {
     925        if ( empty( $image_meta['sizes'] ) ) {
    891926                return false;
    892927        }
    893928
    894         // Extract the height and width from the intermediate or the full size.
    895         $img_width  = ( $image ) ? $image['width']  : $img_meta['width'];
    896         $img_height = ( $image ) ? $image['height'] : $img_meta['height'];
     929        $img_sizes = $image_meta['sizes'];
    897930
    898         // Bail early if the width isn't greater than zero.
    899         if ( ! $img_width > 0 ) {
     931        // Get the height and width for the image.
     932        $img_width = (int) $size_array[0];
     933        $img_height = (int) $size_array[1];
     934
     935        // Bail early if error/no width.
     936        if ( $img_width < 1 ) {
    900937                return false;
    901938        }
    902939
    903         // Use the URL from the intermediate size or build the url from the metadata.
    904         if ( ! empty( $image['url'] ) ) {
    905                 $img_url = $image['url'];
    906         } else {
    907                 $uploads_dir = wp_upload_dir();
    908                 $img_file = ( $image ) ? path_join( dirname( $img_meta['file'] ) , $image['file'] ) : $img_meta['file'];
    909                 $img_url = $uploads_dir['baseurl'] . '/' . $img_file;
    910         }
    911 
    912         $img_sizes = $img_meta['sizes'];
    913 
    914940        // Add full size to the img_sizes array.
    915941        $img_sizes['full'] = array(
    916                 'width'  => $img_meta['width'],
    917                 'height' => $img_meta['height'],
    918                 'file'   => wp_basename( $img_meta['file'] )
     942                'width'  => $image_meta['width'],
     943                'height' => $image_meta['height'],
     944                'file'   => wp_basename( $image_meta['file'] ),
    919945        );
    920946
     947        $img_baseurl = _wp_upload_dir_baseurl();
     948        $dirname = dirname( $image_meta['file'] );
     949
     950        if ( $dirname !== '.' ) {
     951                $img_baseurl = path_join( $img_baseurl, $dirname );
     952        }
     953
    921954        // Calculate the image aspect ratio.
    922955        $img_ratio = $img_height / $img_width;
    923956
     
    926959         * contain a unique hash. Look for that hash and use it later to filter
    927960         * out images that are leftovers from previous versions.
    928961         */
    929         $img_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash );
     962        $img_edited = preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash );
    930963
    931964        /**
    932965         * Filter the maximum width included in a srcset attribute.
     
    933966         *
    934967         * @since 4.4.0
    935968         *
    936          * @param array|string $size Size of image, either array or string.
     969         * @param array|string $size_array Size of image, either array or string.
    937970         */
    938         $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size );
     971        $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size_array );
    939972
    940         /*
    941          * Set up arrays to hold url candidates and matched image sources so
    942          * we can avoid duplicates without looping through the full sources array
    943          */
    944         $candidates = $sources = array();
     973        // Array to hold url candidates.
     974        $sources = array();
    945975
    946976        /*
    947          * Loop through available images and only use images that are resized
     977         * Loop through available images. Only use images that are resized
    948978         * versions of the same rendition.
    949979         */
    950980        foreach ( $img_sizes as $img ) {
    951981
    952                 // Filter out images that are leftovers from previous renditions.
     982                // Filter out images that are from previous renditions.
    953983                if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) {
    954984                        continue;
    955985                }
     
    959989                        continue;
    960990                }
    961991
    962                 $candidate_url = path_join( dirname( $img_url ), $img['file'] );
     992                $candidate_url = path_join( $img_baseurl, $img['file'] );
    963993
    964994                // Calculate the new image ratio.
    965995                if ( $img['width'] ) {
     
    969999                }
    9701000
    9711001                // If the new ratio differs by less than 0.01, use it.
    972                 if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! in_array( $candidate_url, $candidates ) ) {
    973                         // Add the URL to our list of candidates.
    974                         $candidates[] = $candidate_url;
    975 
     1002                if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) {
    9761003                        // Add the url, descriptor, and value to the sources array to be returned.
    977                         $sources[] = array(
     1004                        $sources[ $candidate_url ] = array(
    9781005                                'url'        => $candidate_url,
    9791006                                'descriptor' => 'w',
    9801007                                'value'      => $img['width'],
     
    9871014         *
    9881015         * @since 4.4.0
    9891016         *
    990          * @param array        $sources       An array of image urls and widths.
    991          * @param int          $attachment_id Attachment ID for image.
    992          * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    993          *                                    values in pixels (in that order). Default 'medium'.
     1017         * @param array $sources       An array of image urls and widths.
     1018         * @param array $size_array    Image size. Array of width and height values in pixels (in that order).
     1019         * @param array $image_meta    The image meta data.
     1020         * @param int   $attachment_id Attachment ID for image.
    9941021         */
    995         return apply_filters( 'wp_get_attachment_image_srcset_array', $sources, $attachment_id, $size );
     1022        return apply_filters( 'wp_get_attachment_image_srcset_array', array_values( $sources ), $size_array, $image_meta, $attachment_id );
    9961023}
    9971024
    9981025/**
     
    10001027 *
    10011028 * @since 4.4.0
    10021029 *
    1003  * @param int          $attachment_id Image attachment ID.
    1004  * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    1005  *                                    values in pixels (in that order). Default 'medium'.
    1006  * @return string|bool A 'srcset' value string or false.
     1030 * @param  int   $image_meta The image meta data.
     1031 * @param  array $size_array Image size. An array of width and height values in pixels (in that order).
     1032 * @return string|bool       A 'srcset' value string or false.
    10071033 */
    1008 function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium' ) {
    1009         $srcset_array = wp_get_attachment_image_srcset_array( $attachment_id, $size );
     1034function wp_get_attachment_image_srcset( $size_array, $image_meta, $attachment_id = 0 ) {
     1035        $srcset_array = wp_get_attachment_image_srcset_array( $size_array, $image_meta, $attachment_id );
    10101036
    10111037        // Only return a srcset value if there is more than one source.
    1012         if ( count( $srcset_array ) <= 1 ) {
     1038        if ( count( $srcset_array ) < 2 ) {
    10131039                return false;
    10141040        }
    10151041
     
    10231049         *
    10241050         * @since 4.4.0
    10251051         *
    1026          * @param string       $srcset        A source set formated for a `srcset` attribute.
    1027          * @param int          $attachment_id Attachment ID for image.
    1028          * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    1029          *                                    values in pixels (in that order). Default 'medium'.
     1052         * @param string $srcset        A source set formated for a `srcset` attribute.
     1053         * @param array  $size_array    Image size. Array of width and height values in pixels (in that order).
     1054         * @param array  $image_meta    The image meta data.
     1055         * @param int    $attachment_id Image attachment ID.
    10301056         */
    1031         return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size );
     1057        return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $size_array, $image_meta, $attachment_id );
    10321058}
    10331059
    10341060/**
    1035  * Retrieves a source size attribute for an image from an array of values.
     1061 * Create `sizes` attribute value for an image.
    10361062 *
    10371063 * @since 4.4.0
    10381064 *
    1039  * @param int          $attachment_id Image attachment ID.
    1040  * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    1041  *                                    values in pixels (in that order). Default 'medium'.
    1042  * @param int          $width         Optional. Display width of the image.
     1065 * @param int|array $size          The width of the image or an array( $width, $height ).
     1066 * @param array     $image_meta    Optional. The image meta data.
     1067 * @param int       $attachment_id Optional. Image attachment ID.
     1068 *
    10431069 * @return string|bool A valid source size value for use in a 'sizes' attribute or false.
    10441070 */
    1045 function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width = null ) {
    1046         // Try to get the image width from $args parameter.
    1047         if ( is_numeric( $width ) ) {
    1048                 $img_width = (int) $width;
    1049         // Next, use see if a width value was passed in the $size parameter.
     1071function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0 ) {
     1072        $width = 0;
     1073
     1074        if ( is_numeric( $size ) ) {
     1075                $width = absint( $size );
    10501076        } elseif ( is_array( $size ) ) {
    1051                 $img_width = $size[0];
    1052         // Finally, use the $size name to return the width of the image.
    1053         } else {
    1054                 $image = image_get_intermediate_size( $attachment_id, $size );
    1055                 $img_width = $image ? $image['width'] : false;
     1077                $width = absint( $size[0] );
    10561078        }
    10571079
    1058         // Bail early if $image_width isn't set.
    1059         if ( ! $img_width ) {
     1080        if ( ! $width ) {
    10601081                return false;
    10611082        }
    10621083
    10631084        // Setup the default sizes attribute.
    1064         $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $img_width );
     1085        $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', (int) $width );
    10651086
    10661087        /**
    10671088         * Filter the output of wp_get_attachment_image_sizes().
     
    10741095         *                                    values in pixels (in that order). Default 'medium'.
    10751096         * @param int          $width         Display width of the image.
    10761097         */
    1077         return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $attachment_id, $size, $width );
     1098        return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $width, $image_meta, $attachment_id );
    10781099}
    10791100
    10801101/**
     
    10821103 *
    10831104 * @since 4.4.0
    10841105 *
    1085  * @see wp_img_add_srcset_and_sizes()
     1106 * @see wp_image_add_srcset_and_sizes()
    10861107 *
    10871108 * @param string $content The raw post content to be filtered.
    10881109 * @return string Converted content with 'srcset' and 'sizes' attributes added to images.
     
    10901111function wp_make_content_images_responsive( $content ) {
    10911112        $images = get_media_embedded_in_content( $content, 'img' );
    10921113
    1093         $attachment_ids = array();
     1114        foreach( $images as $image ) {
     1115                if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) &&
     1116                        ( $attachment_id = absint( $class_id[1] ) ) ) {
    10941117
    1095         foreach( $images as $image ) {
    1096                 if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) {
    1097                         $attachment_id = (int) $class_id[1];
    1098                         if ( $attachment_id ) {
    1099                                 $attachment_ids[] = $attachment_id;
    1100                         }
     1118                        $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
     1119                        $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
    11011120                }
    11021121        }
    11031122
    1104         if ( 0 < count( $attachment_ids ) ) {
    1105                 /*
    1106                  * Warm object caches for use with wp_get_attachment_metadata.
    1107                  *
    1108                  * To avoid making a database call for each image, a single query
    1109                  * warms the object cache with the meta information for all images.
    1110                  */
    1111                 _prime_post_caches( $attachment_ids, false, true );
    1112         }
    1113 
    1114         foreach( $images as $image ) {
    1115                 $content = str_replace( $image, wp_img_add_srcset_and_sizes( $image ), $content );
    1116         }
    1117 
    11181123        return $content;
    11191124}
    11201125
     
    11261131 * @see wp_get_attachment_image_srcset()
    11271132 * @see wp_get_attachment_image_sizes()
    11281133 *
    1129  * @param string $image An HTML 'img' element to be filtered.
     1134 * @param string $image         An HTML 'img' element to be filtered.
     1135 * @param array  $image_meta    The image meta data.
     1136 * @param int    $attachment_id Image attachment ID.
    11301137 * @return string Converted 'img' element with `srcset` and `sizes` attributes added.
    11311138 */
    1132 function wp_img_add_srcset_and_sizes( $image ) {
    1133         // Return early if a 'srcset' attribute already exists.
    1134         if ( false !== strpos( $image, ' srcset="' ) ) {
     1139function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) {
     1140        // Ensure the image meta exists
     1141        if ( empty( $image_meta['sizes'] ) ) {
    11351142                return $image;
    11361143        }
    11371144
    1138         // Parse id, size, width, and height from the `img` element.
    1139         $id     = preg_match( '/wp-image-([0-9]+)/i', $image, $match_id     ) ? (int) $match_id[1]     : false;
    1140         $size   = preg_match( '/size-([^\s|"]+)/i',   $image, $match_size   ) ? $match_size[1]         : false;
    1141         $width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : false;
     1145        $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : '';
     1146        list( $src ) = explode( '?', $src );
    11421147
    1143         if ( $id && false === $size ) {
    1144                 $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : false;
     1148        // Return early if we coudn't get the image source.
     1149        if ( ! $src ) {
     1150                return $image;
     1151        }
    11451152
    1146                 if ( $width && $height ) {
    1147                         $size = array( $width, $height );
    1148                 }
     1153        // Bail early when an image has been inserted and later edited.
     1154        // We don't have the previous image meta to generate srcset.
     1155        if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) &&
     1156                strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) {
     1157
     1158                return $image;
    11491159        }
    11501160
    1151         /*
    1152          * If attempts to parse the size value failed, attempt to use the image
    1153          * metadata to match the 'src' against the available sizes for an attachment.
    1154          */
    1155         if ( ! $size && ! empty( $id ) && is_array( $meta = wp_get_attachment_metadata( $id ) ) ) {
    1156                 // Parse the image src value from the img element.
    1157                 $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false;
     1161        $width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : 0;
     1162        $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0;
    11581163
    1159                 // Return early if the src value is empty.
    1160                 if ( ! $src ) {
    1161                         return $image;
    1162                 }
    1163 
     1164        if ( ! $width || ! $height ) {
    11641165                /*
    1165                  * First, see if the file is the full size image. If not, loop through
    1166                  * the intermediate sizes until we find a file that matches.
     1166                 * If attempts to parse the size value failed, attempt to use the image
     1167                 * metadata to match the 'src' against the available sizes for an attachment.
    11671168                 */
    11681169                $image_filename = wp_basename( $src );
    11691170
    1170                 if ( $image_filename === basename( $meta['file'] ) ) {
    1171                         $size = 'full';
     1171                if ( $image_filename === basename( $image_meta['file'] ) ) {
     1172                        $width = (int) $image_meta['width'];
     1173                        $height = (int) $image_meta['height'];
    11721174                } else {
    1173                         foreach( $meta['sizes'] as $image_size => $image_size_data ) {
     1175                        foreach( $image_meta['sizes'] as $image_size_data ) {
    11741176                                if ( $image_filename === $image_size_data['file'] ) {
    1175                                         $size = $image_size;
     1177                                        $width = (int) $image_size_data['width'];
     1178                                        $height = (int) $image_size_data['height'];
    11761179                                        break;
    11771180                                }
    11781181                        }
    11791182                }
     1183        }
    11801184
     1185        if ( ! $width || ! $height ) {
     1186                return $image;
    11811187        }
    11821188
    1183         // If ID and size exist, try for 'srcset' and 'sizes' and update the markup.
    1184         if ( $id && $size && ( $srcset = wp_get_attachment_image_srcset( $id, $size ) ) && ( $sizes = wp_get_attachment_image_sizes( $id, $size, $width ) ) ) {
     1189        $size_array = array( $width, $height );
     1190        $srcset = wp_get_attachment_image_srcset( $size_array, $image_meta, $attachment_id );
     1191        $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id );
     1192
     1193        if ( $srcset && $sizes ) {
    11851194                // Format the srcset and sizes string and escape attributes.
    1186                 $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) );
     1195                $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) );
    11871196
    11881197                // Add srcset and sizes attributes to the image markup.
    1189                 $image = preg_replace( '/<img ([^>]+)[\s?][\/?]>/', '<img $1' . $srcset_and_sizes . ' />', $image );
     1198                $image = preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $srcset_and_sizes . ' />', $image );
    11901199        }
    11911200
    11921201        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 );