X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/03f2fa83c13c1b532284205fa7efcab9b8b2c41f..4feeb71a9d812a9ae371c28a3d8b442a4394ded7:/wp-includes/media.php diff --git a/wp-includes/media.php b/wp-includes/media.php index e6c27b0c..9f35f798 100644 --- a/wp-includes/media.php +++ b/wp-includes/media.php @@ -878,24 +878,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; } /** @@ -971,7 +975,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 +1001,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. @@ -1004,19 +1017,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 @@ -1038,37 +1055,71 @@ 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; + + // Check if image meta isn't corrupted. + if ( ! is_array( $image ) ) { + continue; + } + + // 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; } - // Filter out images that are wider than '$max_srcset_image_width'. - if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width ) { + /* + * Filter 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; } - // Calculate the new image ratio. - if ( $image['width'] ) { - $image_ratio_compare = $image['height'] / $image['width']; + /** + * To check for varying crops, we calculate the expected size of the smaller + * image if the larger were constrained by the width of the smaller and then + * see if it matches what we're expecting. + */ + if ( $image_width > $image['width'] ) { + $constrained_size = wp_constrain_dimensions( $image_width, $image_height, $image['width'] ); + $expected_size = array( $image['width'], $image['height'] ); } else { - $image_ratio_compare = 0; + $constrained_size = wp_constrain_dimensions( $image['width'], $image['height'], $image_width ); + $expected_size = array( $image_width, $image_height ); } - // 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 ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 ) { // 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; + } } } @@ -1096,7 +1147,7 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac $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; } @@ -1278,28 +1329,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; @@ -2132,9 +2161,9 @@ function wp_get_attachment_id3_keys( $attachment, $context = 'display' ) { * @type string $src URL to the source of the audio file. Default empty. * @type string $loop The 'loop' attribute for the `