WordPress 4.4.1
[autoinstalls/wordpress.git] / wp-includes / media.php
index e6c27b0c85af3b2c90c438c9846d5bcb87030037..70b09584cc3546d7a8987f69f56ae7ee99520730 100644 (file)
@@ -877,6 +877,31 @@ function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon
        return isset( $image['0'] ) ? $image['0'] : false;
 }
 
+/**
+ * Get the attachment path relative to the upload directory.
+ *
+ * @since 4.4.1
+ * @access private
+ *
+ * @param string $file Attachment file name.
+ * @return string Attachment path relative to the upload directory.
+ */
+function _wp_get_attachment_relative_path( $file ) {
+       $dirname = dirname( $file );
+
+       if ( '.' === $dirname ) {
+               return '';
+       }
+
+       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 $dirname;
+}
+
 /**
  * Caches and returns the base URL of the uploads directory.
  *
@@ -971,6 +996,16 @@ 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 ) {
+       /**
+        * 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'] ) ) {
                return false;
        }
@@ -987,7 +1022,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,16 +1038,15 @@ 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 );
+       $image_baseurl = _wp_upload_dir_baseurl();
+       $image_baseurl = trailingslashit( $image_baseurl ) . $dirname;
 
        // Calculate the image aspect ratio.
        $image_ratio = $image_height / $image_width;
@@ -1038,19 +1071,36 @@ 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 mathces 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 ) {
 
+               // 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 = 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 &&
+                       false === strpos( $image_src, $image['file'] ) ) {
+
                        continue;
                }
 
@@ -1096,7 +1146,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 +1328,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;