X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/03f2fa83c13c1b532284205fa7efcab9b8b2c41f..0f74cdeda4c069bfbb9c4131ef1352f55b6f8499:/wp-includes/media.php diff --git a/wp-includes/media.php b/wp-includes/media.php index e6c27b0c..deb18a40 100644 --- a/wp-includes/media.php +++ b/wp-includes/media.php @@ -6,6 +6,23 @@ * @subpackage Media */ +/** + * Retrieve additional image sizes. + * + * @since 4.7.0 + * + * @global array $_wp_additional_image_sizes + * + * @return array Additional images size data. + */ +function wp_get_additional_image_sizes() { + global $_wp_additional_image_sizes; + if ( ! $_wp_additional_image_sizes ) { + $_wp_additional_image_sizes = array(); + } + return $_wp_additional_image_sizes; +} + /** * Scale down the default size of an image. * @@ -27,7 +44,6 @@ * @since 2.5.0 * * @global int $content_width - * @global array $_wp_additional_image_sizes * * @param int $width Width of the image in pixels. * @param int $height Height of the image in pixels. @@ -39,7 +55,9 @@ * @return array Width and height of what the result image should resize to. */ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $context = null ) { - global $content_width, $_wp_additional_image_sizes; + global $content_width; + + $_wp_additional_image_sizes = wp_get_additional_image_sizes(); if ( ! $context ) $context = is_admin() ? 'edit' : 'display'; @@ -82,11 +100,13 @@ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $co if ( intval($content_width) > 0 ) { $max_width = min( intval($content_width), $max_width ); } - } elseif ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) { + } elseif ( ! empty( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) { $max_width = intval( $_wp_additional_image_sizes[$size]['width'] ); $max_height = intval( $_wp_additional_image_sizes[$size]['height'] ); - if ( intval($content_width) > 0 && 'edit' == $context ) // Only in admin. Assume that theme authors know what they're doing. - $max_width = min( intval($content_width), $max_width ); + // Only in admin. Assume that theme authors know what they're doing. + if ( intval( $content_width ) > 0 && 'edit' === $context ) { + $max_width = min( intval( $content_width ), $max_width ); + } } // $size == 'full' has no constraint else { @@ -95,7 +115,7 @@ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $co } /** - * Filter the maximum image size dimensions for the editor. + * Filters the maximum image size dimensions for the editor. * * @since 2.5.0 * @@ -148,7 +168,7 @@ function image_hwstring( $width, $height ) { * function won't create a new resized copy, it will just return an already * resized one if it exists. * - * A plugin may use the 'image_downsize' filter to hook into and offer image + * A plugin may use the {@see 'image_downsize'} filter to hook into and offer image * resizing services for images. The hook must return an array with the same * elements that are returned in the function. The first element being the URL * to the new image that was resized. @@ -163,12 +183,10 @@ function image_hwstring( $width, $height ) { * the image is an intermediate size. False on failure. */ function image_downsize( $id, $size = 'medium' ) { - - if ( !wp_attachment_is_image($id) ) - return false; + $is_image = wp_attachment_is_image( $id ); /** - * Filter whether to preempt the output of image_downsize(). + * Filters whether to preempt the output of image_downsize(). * * Passing a truthy value to the filter will effectively short-circuit * down-sizing the image, returning that value as output instead. @@ -190,6 +208,19 @@ function image_downsize( $id, $size = 'medium' ) { $is_intermediate = false; $img_url_basename = wp_basename($img_url); + // If the file isn't an image, attempt to replace its URL with a rendered image from its meta. + // Otherwise, a non-image type could be returned. + if ( ! $is_image ) { + if ( ! empty( $meta['sizes'] ) ) { + $img_url = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url ); + $img_url_basename = $meta['sizes']['full']['file']; + $width = $meta['sizes']['full']['width']; + $height = $meta['sizes']['full']['height']; + } else { + return false; + } + } + // try for a new style intermediate size if ( $intermediate = image_get_intermediate_size($id, $size) ) { $img_url = str_replace($img_url_basename, $intermediate['file'], $img_url); @@ -258,15 +289,12 @@ function add_image_size( $name, $width = 0, $height = 0, $crop = false ) { * * @since 3.9.0 * - * @global array $_wp_additional_image_sizes - * * @param string $name The image size to check. * @return bool True if the image size exists, false if not. */ function has_image_size( $name ) { - global $_wp_additional_image_sizes; - - return isset( $_wp_additional_image_sizes[ $name ] ); + $sizes = wp_get_additional_image_sizes(); + return isset( $sizes[ $name ] ); } /** @@ -309,12 +337,12 @@ function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) { /** * Gets an img tag for an image attachment, scaling it down if requested. * - * The filter 'get_image_tag_class' allows for changing the class name for the + * The {@see 'get_image_tag_class'} filter allows for changing the class name for the * image without having to use regular expressions on the HTML content. The * parameters are: what WordPress will use for the class, the Attachment ID, * image align value, and the size the image should be. * - * The second filter 'get_image_tag' has the HTML content, which can then be + * The second filter, {@see 'get_image_tag'}, has the HTML content, which can then be * further manipulated by a plugin to change all attribute values and even HTML * content. * @@ -339,7 +367,7 @@ function get_image_tag( $id, $alt, $title, $align, $size = 'medium' ) { $class = 'align' . esc_attr($align) .' size-' . esc_attr($size) . ' wp-image-' . $id; /** - * Filter the value of the attachment's image tag class attribute. + * Filters the value of the attachment's image tag class attribute. * * @since 2.6.0 * @@ -354,7 +382,7 @@ function get_image_tag( $id, $alt, $title, $align, $size = 'medium' ) { $html = '' . esc_attr($alt) . ''; /** - * Filter the HTML content for the image tag. + * Filters the HTML content for the image tag. * * @since 2.6.0 * @@ -431,7 +459,7 @@ function wp_constrain_dimensions( $current_width, $current_height, $max_width = } /** - * Filter dimensions to constrain down-sampled images to. + * Filters dimensions to constrain down-sampled images to. * * @since 4.1.0 * @@ -477,7 +505,7 @@ function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = fa return false; /** - * Filter whether to preempt calculating the image resize dimensions. + * Filters whether to preempt calculating the image resize dimensions. * * Passing a non-null value to the filter will effectively short-circuit * image_resize_dimensions(), returning that value instead. @@ -562,7 +590,7 @@ function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = fa * Resizes an image to make a thumbnail or intermediate size. * * The returned array has the file size, the image width, and image height. The - * filter 'image_make_intermediate_size' can be used to hook in and change the + * {@see 'image_make_intermediate_size'} filter can be used to hook in and change the * values of the returned array. The only parameter is the resized file path. * * @since 2.5.0 @@ -591,6 +619,36 @@ function image_make_intermediate_size( $file, $width, $height, $crop = false ) { return false; } +/** + * Helper function to test if aspect ratios for two images match. + * + * @since 4.6.0 + * + * @param int $source_width Width of the first image in pixels. + * @param int $source_height Height of the first image in pixels. + * @param int $target_width Width of the second image in pixels. + * @param int $target_height Height of the second image in pixels. + * @return bool True if aspect ratios match within 1px. False if not. + */ +function wp_image_matches_ratio( $source_width, $source_height, $target_width, $target_height ) { + /* + * To test for varying crops, we constrain the dimensions of the larger image + * to the dimensions of the smaller image and see if they match. + */ + if ( $source_width > $target_width ) { + $constrained_size = wp_constrain_dimensions( $source_width, $source_height, $target_width ); + $expected_size = array( $target_width, $target_height ); + } else { + $constrained_size = wp_constrain_dimensions( $target_width, $target_height, $source_width ); + $expected_size = array( $source_width, $source_height ); + } + + // If the image dimensions are within 1px of the expected size, we consider it a match. + $matched = ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 ); + + return $matched; +} + /** * Retrieves the image's intermediate size (resized) path, width, and height. * @@ -623,73 +681,87 @@ function image_make_intermediate_size( $file, $width, $height, $crop = false ) { * @type string $file Image's path relative to uploads directory * @type int $width Width of image * @type int $height Height of image - * @type string $path Optional. Image's absolute filesystem path. Only returned if registered - * size is passed to `$size` parameter. - * @type string $url Optional. Image's URL. Only returned if registered size is passed to `$size` - * parameter. + * @type string $path Image's absolute filesystem path. + * @type string $url Image's URL. * } */ function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) { - if ( !is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) ) + if ( ! $size || ! is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) || empty( $imagedata['sizes'] ) ) { return false; + } + + $data = array(); - // get the best one for a specified set of dimensions - if ( is_array($size) && !empty($imagedata['sizes']) ) { + // Find the best match when '$size' is an array. + if ( is_array( $size ) ) { $candidates = array(); + if ( ! isset( $imagedata['file'] ) && isset( $imagedata['sizes']['full'] ) ) { + $imagedata['height'] = $imagedata['sizes']['full']['height']; + $imagedata['width'] = $imagedata['sizes']['full']['width']; + } + foreach ( $imagedata['sizes'] as $_size => $data ) { // If there's an exact match to an existing image size, short circuit. if ( $data['width'] == $size[0] && $data['height'] == $size[1] ) { - list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); - - /** This filter is documented in wp-includes/media.php */ - return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size ); + $candidates[ $data['width'] * $data['height'] ] = $data; + break; } - // If it's not an exact match but it's at least the dimensions requested. + + // If it's not an exact match, consider larger sizes with the same aspect ratio. if ( $data['width'] >= $size[0] && $data['height'] >= $size[1] ) { - $candidates[ $data['width'] * $data['height'] ] = $_size; + // If '0' is passed to either size, we test ratios against the original file. + if ( 0 === $size[0] || 0 === $size[1] ) { + $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $imagedata['width'], $imagedata['height'] ); + } else { + $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $size[0], $size[1] ); + } + + if ( $same_ratio ) { + $candidates[ $data['width'] * $data['height'] ] = $data; + } } } if ( ! empty( $candidates ) ) { - // find for the smallest image not smaller than the desired size - ksort( $candidates ); - foreach ( $candidates as $_size ) { - $data = $imagedata['sizes'][$_size]; - - // Skip images with unexpectedly divergent aspect ratios (crops) - // First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop - $maybe_cropped = image_resize_dimensions($imagedata['width'], $imagedata['height'], $data['width'], $data['height'], false ); - // If the size doesn't match within one pixel, then it is of a different aspect ratio, so we skip it, unless it's the thumbnail size - if ( 'thumbnail' != $_size && - ( ! $maybe_cropped - || ( $maybe_cropped[4] != $data['width'] && $maybe_cropped[4] + 1 != $data['width'] ) - || ( $maybe_cropped[5] != $data['height'] && $maybe_cropped[5] + 1 != $data['height'] ) - ) ) { - continue; - } - // If we're still here, then we're going to use this size. - list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); - - /** This filter is documented in wp-includes/media.php */ - return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size ); + // Sort the array by size if we have more than one candidate. + if ( 1 < count( $candidates ) ) { + ksort( $candidates ); } + + $data = array_shift( $candidates ); + /* + * When the size requested is smaller than the thumbnail dimensions, we + * fall back to the thumbnail size to maintain backwards compatibility with + * pre 4.6 versions of WordPress. + */ + } elseif ( ! empty( $imagedata['sizes']['thumbnail'] ) && $imagedata['sizes']['thumbnail']['width'] >= $size[0] && $imagedata['sizes']['thumbnail']['width'] >= $size[1] ) { + $data = $imagedata['sizes']['thumbnail']; + } else { + return false; } + + // Constrain the width and height attributes to the requested values. + list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); + + } elseif ( ! empty( $imagedata['sizes'][ $size ] ) ) { + $data = $imagedata['sizes'][ $size ]; } - if ( is_array($size) || empty($size) || empty($imagedata['sizes'][$size]) ) + // If we still don't have a match at this point, return false. + if ( empty( $data ) ) { return false; + } - $data = $imagedata['sizes'][$size]; // include the full filesystem path of the intermediate file - if ( empty($data['path']) && !empty($data['file']) ) { + if ( empty( $data['path'] ) && ! empty( $data['file'] ) && ! empty( $imagedata['file'] ) ) { $file_url = wp_get_attachment_url($post_id); $data['path'] = path_join( dirname($imagedata['file']), $data['file'] ); $data['url'] = path_join( dirname($file_url), $data['file'] ); } /** - * Filter the output of image_get_intermediate_size() + * Filters the output of image_get_intermediate_size() * * @since 4.4.0 * @@ -709,18 +781,17 @@ function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) { * * @since 3.0.0 * - * @global array $_wp_additional_image_sizes - * * @return array Returns a filtered array of image size strings. */ function get_intermediate_image_sizes() { - global $_wp_additional_image_sizes; + $_wp_additional_image_sizes = wp_get_additional_image_sizes(); $image_sizes = array('thumbnail', 'medium', 'medium_large', 'large'); // Standard sizes - if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) ) + if ( ! empty( $_wp_additional_image_sizes ) ) { $image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) ); + } /** - * Filter the list of intermediate image sizes. + * Filters the list of intermediate image sizes. * * @since 2.5.0 * @@ -767,7 +838,7 @@ function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon } } /** - * Filter the image src result. + * Filters the image src result. * * @since 4.3.0 * @@ -811,18 +882,14 @@ function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = fa $default_attr = array( 'src' => $src, 'class' => "attachment-$size_class size-$size_class", - 'alt' => trim(strip_tags( get_post_meta($attachment_id, '_wp_attachment_image_alt', true) )), // Use Alt field first + 'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ), ); - if ( empty($default_attr['alt']) ) - $default_attr['alt'] = trim(strip_tags( $attachment->post_excerpt )); // If not, Use the Caption - if ( empty($default_attr['alt']) ) - $default_attr['alt'] = trim(strip_tags( $attachment->post_title )); // Finally, use the title $attr = wp_parse_args( $attr, $default_attr ); // Generate 'srcset' and 'sizes' if not already present. if ( empty( $attr['srcset'] ) ) { - $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + $image_meta = wp_get_attachment_metadata( $attachment_id ); if ( is_array( $image_meta ) ) { $size_array = array( absint( $width ), absint( $height ) ); @@ -840,7 +907,7 @@ function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = fa } /** - * Filter the list of attachment image attributes. + * Filters the list of attachment image attributes. * * @since 2.8.0 * @@ -878,24 +945,28 @@ function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon } /** - * Caches and returns the base URL of the uploads directory. + * Get the attachment path relative to the upload directory. * - * @since 4.4.0 + * @since 4.4.1 * @access private * - * @return string The base URL, cached. + * @param string $file Attachment file name. + * @return string Attachment path relative to the upload directory. */ -function _wp_upload_dir_baseurl() { - static $baseurl = array(); +function _wp_get_attachment_relative_path( $file ) { + $dirname = dirname( $file ); - $blog_id = get_current_blog_id(); + if ( '.' === $dirname ) { + return ''; + } - if ( empty( $baseurl[$blog_id] ) ) { - $uploads_dir = wp_upload_dir(); - $baseurl[$blog_id] = $uploads_dir['baseurl']; + if ( false !== strpos( $dirname, 'wp-content/uploads' ) ) { + // Get the directory name relative to the upload directory (back compat for pre-2.7 uploads) + $dirname = substr( $dirname, strpos( $dirname, 'wp-content/uploads' ) + 18 ); + $dirname = ltrim( $dirname, '/' ); } - return $baseurl[$blog_id]; + return $dirname; } /** @@ -947,7 +1018,7 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag } if ( ! is_array( $image_meta ) ) { - $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + $image_meta = wp_get_attachment_metadata( $attachment_id ); } $image_src = $image[0]; @@ -971,7 +1042,17 @@ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag * @return string|bool The 'srcset' attribute value. False on error or when only one source exists. */ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0 ) { - if ( empty( $image_meta['sizes'] ) ) { + /** + * Let plugins pre-filter the image meta to be able to fix inconsistencies in the stored data. + * + * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. + * @param array $size_array Array of width and height values in pixels (in that order). + * @param string $image_src The 'src' of the image. + * @param int $attachment_id The image attachment ID or 0 if not supplied. + */ + $image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id ); + + if ( empty( $image_meta['sizes'] ) || ! isset( $image_meta['file'] ) || strlen( $image_meta['file'] ) < 4 ) { return false; } @@ -987,7 +1068,6 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac } $image_basename = wp_basename( $image_meta['file'] ); - $image_baseurl = _wp_upload_dir_baseurl(); /* * WordPress flattens animated GIFs into one frame when generating intermediate sizes. @@ -995,7 +1075,7 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac * If src is an intermediate size GIF, the full size is excluded from srcset to keep a flattened GIF from becoming animated. */ if ( ! isset( $image_sizes['thumbnail']['mime-type'] ) || 'image/gif' !== $image_sizes['thumbnail']['mime-type'] ) { - $image_sizes['full'] = array( + $image_sizes[] = array( 'width' => $image_meta['width'], 'height' => $image_meta['height'], 'file' => $image_basename, @@ -1004,19 +1084,23 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac return false; } - // Uploads are (or have been) in year/month sub-directories. - if ( $image_basename !== $image_meta['file'] ) { - $dirname = dirname( $image_meta['file'] ); + // Retrieve the uploads sub-directory from the full size image. + $dirname = _wp_get_attachment_relative_path( $image_meta['file'] ); - if ( $dirname !== '.' ) { - $image_baseurl = trailingslashit( $image_baseurl ) . $dirname; - } + if ( $dirname ) { + $dirname = trailingslashit( $dirname ); } - $image_baseurl = trailingslashit( $image_baseurl ); + $upload_dir = wp_get_upload_dir(); + $image_baseurl = trailingslashit( $upload_dir['baseurl'] ) . $dirname; - // Calculate the image aspect ratio. - $image_ratio = $image_height / $image_width; + /* + * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain + * (which is to say, when they share the domain name of the current request). + */ + if ( is_ssl() && 'https' !== substr( $image_baseurl, 0, 5 ) && parse_url( $image_baseurl, PHP_URL_HOST ) === $_SERVER['HTTP_HOST'] ) { + $image_baseurl = set_url_scheme( $image_baseurl, 'https' ); + } /* * Images that have been edited in WordPress after being uploaded will @@ -1026,7 +1110,7 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac $image_edited = preg_match( '/-e[0-9]{13}/', wp_basename( $image_src ), $image_edit_hash ); /** - * Filter the maximum image width to be included in a 'srcset' attribute. + * Filters the maximum image width to be included in a 'srcset' attribute. * * @since 4.4.0 * @@ -1038,42 +1122,63 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac // Array to hold URL candidates. $sources = array(); + /** + * To make sure the ID matches our image src, we will check to see if any sizes in our attachment + * meta match our $image_src. If no matches are found we don't return a srcset to avoid serving + * an incorrect image. See #35045. + */ + $src_matched = false; + /* * Loop through available images. Only use images that are resized * versions of the same edit. */ foreach ( $image_sizes as $image ) { + $is_src = false; - // Filter out images that are from previous edits. - if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { + // Check if image meta isn't corrupted. + if ( ! is_array( $image ) ) { continue; } - // Filter out images that are wider than '$max_srcset_image_width'. - if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width ) { + // If the file name is part of the `src`, we've confirmed a match. + if ( ! $src_matched && false !== strpos( $image_src, $dirname . $image['file'] ) ) { + $src_matched = $is_src = true; + } + + // Filter out images that are from previous edits. + if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { continue; } - // Calculate the new image ratio. - if ( $image['width'] ) { - $image_ratio_compare = $image['height'] / $image['width']; - } else { - $image_ratio_compare = 0; + /* + * Filters out images that are wider than '$max_srcset_image_width' unless + * that file is in the 'src' attribute. + */ + if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width && ! $is_src ) { + continue; } - // If the new ratio differs by less than 0.002, use it. - if ( abs( $image_ratio - $image_ratio_compare ) < 0.002 ) { + // If the image dimensions are within 1px of the expected size, use it. + if ( wp_image_matches_ratio( $image_width, $image_height, $image['width'], $image['height'] ) ) { // Add the URL, descriptor, and value to the sources array to be returned. - $sources[ $image['width'] ] = array( + $source = array( 'url' => $image_baseurl . $image['file'], 'descriptor' => 'w', 'value' => $image['width'], ); + + // The 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030. + if ( $is_src ) { + $sources = array( $image['width'] => $source ) + $sources; + } else { + $sources[ $image['width'] ] = $source; + } } } /** - * Filter an image's 'srcset' sources. + * Filters an image's 'srcset' sources. * * @since 4.4.0 * @@ -1091,19 +1196,19 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac * @param array $size_array Array of width and height values in pixels (in that order). * @param string $image_src The 'src' of the image. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. - * @param int $attachment_id Image attachment ID or 0. + * @param int $attachment_id Image attachment ID or 0. */ $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id ); // Only return a 'srcset' value if there is more than one source. - if ( count( $sources ) < 2 ) { + if ( ! $src_matched || count( $sources ) < 2 ) { return false; } $srcset = ''; foreach ( $sources as $source ) { - $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; + $srcset .= str_replace( ' ', '%20', $source['url'] ) . ' ' . $source['value'] . $source['descriptor'] . ', '; } return rtrim( $srcset, ', ' ); @@ -1129,7 +1234,7 @@ function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image } if ( ! is_array( $image_meta ) ) { - $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + $image_meta = wp_get_attachment_metadata( $attachment_id ); } $image_src = $image[0]; @@ -1162,7 +1267,7 @@ function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, $width = absint( $size[0] ); } elseif ( is_string( $size ) ) { if ( ! $image_meta && $attachment_id ) { - $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + $image_meta = wp_get_attachment_metadata( $attachment_id ); } if ( is_array( $image_meta ) ) { @@ -1181,7 +1286,7 @@ function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $width ); /** - * Filter the output of 'wp_calculate_image_sizes()'. + * Filters the output of 'wp_calculate_image_sizes()'. * * @since 4.4.0 * @@ -1237,7 +1342,7 @@ function wp_make_content_images_responsive( $content ) { } foreach ( $selected_images as $image => $attachment_id ) { - $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); + $image_meta = wp_get_attachment_metadata( $attachment_id ); $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content ); } @@ -1278,28 +1383,6 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { return $image; } - $base_url = trailingslashit( _wp_upload_dir_baseurl() ); - $image_base_url = $base_url; - - $dirname = dirname( $image_meta['file'] ); - if ( $dirname !== '.' ) { - $image_base_url .= trailingslashit( $dirname ); - } - - $all_sizes = wp_list_pluck( $image_meta['sizes'], 'file' ); - - foreach ( $all_sizes as $key => $file ) { - $all_sizes[ $key ] = $image_base_url . $file; - } - - // Add the original image. - $all_sizes[] = $base_url . $image_meta['file']; - - // Bail early if the image src doesn't match any of the known image sizes. - if ( ! in_array( $image_src, $all_sizes ) ) { - return $image; - } - $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0; $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0; @@ -1358,8 +1441,8 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { /** * Adds a 'wp-post-image' class to post thumbnails. Internal use only. * - * Uses the 'begin_fetch_post_thumbnail_html' and 'end_fetch_post_thumbnail_html' action hooks to - * dynamically add/remove itself so as to only filter post thumbnails. + * Uses the {@see 'begin_fetch_post_thumbnail_html'} and {@see 'end_fetch_post_thumbnail_html'} + * action hooks to dynamically add/remove itself so as to only filter post thumbnails. * * @ignore * @since 2.9.0 @@ -1405,7 +1488,7 @@ add_shortcode('caption', 'img_caption_shortcode'); * Builds the Caption shortcode output. * * Allows a plugin to replace the content that would otherwise be returned. The - * filter is 'img_caption_shortcode' and passes an empty string, the attr + * filter is {@see 'img_caption_shortcode'} and passes an empty string, the attr * parameter and the content parameter values. * * The supported attributes for the shortcode are 'id', 'align', 'width', and @@ -1438,7 +1521,7 @@ function img_caption_shortcode( $attr, $content = null ) { } /** - * Filter the default caption shortcode output. + * Filters the default caption shortcode output. * * If the filtered output isn't empty, it will be used instead of generating * the default caption template. @@ -1477,7 +1560,7 @@ function img_caption_shortcode( $attr, $content = null ) { $width = $html5 ? $atts['width'] : ( 10 + $atts['width'] ); /** - * Filter the width of an image's caption. + * Filters the width of an image's caption. * * By default, the caption is 10 pixels greater than the width of the image, * to prevent post content from running up against a floated image. @@ -1494,10 +1577,10 @@ function img_caption_shortcode( $attr, $content = null ) { $caption_width = apply_filters( 'img_caption_shortcode_width', $width, $atts, $content ); $style = ''; - if ( $caption_width ) + if ( $caption_width ) { $style = 'style="width: ' . (int) $caption_width . 'px" '; + } - $html = ''; if ( $html5 ) { $html = '
' . do_shortcode( $content ) . '
' . $atts['caption'] . '
'; @@ -1560,7 +1643,7 @@ function gallery_shortcode( $attr ) { } /** - * Filter the default gallery shortcode output. + * Filters the default gallery shortcode output. * * If the filtered output isn't empty, it will be used instead of generating * the default gallery template. @@ -1644,7 +1727,7 @@ function gallery_shortcode( $attr ) { $gallery_style = ''; /** - * Filter whether to print default gallery styles. + * Filters whether to print default gallery styles. * * @since 3.1.0 * @@ -1678,7 +1761,7 @@ function gallery_shortcode( $attr ) { $gallery_div = "