From f39a799718395d891d132581af0b0ee5eca1ac40 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Wed, 30 Dec 2015 00:05:07 +0000 Subject: [PATCH] Responsive images: add compatibility for versions < 2.7 when the full image path was stored in the metadata. Introduces `_wp_get_attachment_relative_path()` and uses it in `wp_get_attachment_url()`. Props dd32, SergeyBiryukov. Fixes #35106 for trunk. git-svn-id: https://develop.svn.wordpress.org/trunk@36120 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/media.php | 35 ++++++++++++++++++++++++----- src/wp-includes/post.php | 3 ++- tests/phpunit/tests/media.php | 42 +++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index d200d4ee91..9428b7e050 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -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. * @@ -1006,9 +1031,9 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac // Uploads are (or have been) in year/month sub-directories. if ( $image_basename !== $image_meta['file'] ) { - $dirname = dirname( $image_meta['file'] ); + $dirname = _wp_get_attachment_relative_path( $image_meta['file'] ); - if ( $dirname !== '.' ) { + if ( $dirname ) { $image_baseurl = trailingslashit( $image_baseurl ) . $dirname; } } @@ -1289,8 +1314,8 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { $base_url = trailingslashit( _wp_upload_dir_baseurl() ); $image_base_url = $base_url; - $dirname = dirname( $image_meta['file'] ); - if ( $dirname !== '.' ) { + $dirname = _wp_get_attachment_relative_path( $image_meta['file'] ); + if ( $dirname ) { $image_base_url .= trailingslashit( $dirname ); } @@ -1301,7 +1326,7 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { } // Add the original image. - $all_sizes[] = $base_url . $image_meta['file']; + $all_sizes[] = $image_base_url . basename( $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 ) ) { diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 0fb1dfa348..bf60e5b156 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -4879,7 +4879,8 @@ function wp_get_attachment_url( $post_id = 0 ) { // Replace file location with url location. $url = str_replace($uploads['basedir'], $uploads['baseurl'], $file); } elseif ( false !== strpos($file, 'wp-content/uploads') ) { - $url = $uploads['baseurl'] . substr( $file, strpos($file, 'wp-content/uploads') + 18 ); + // Get the directory name relative to the basedir (back compat for pre-2.7 uploads) + $url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $file ) ) . basename( $file ); } else { // It's a newly-uploaded file, therefore $file is relative to the basedir. $url = $uploads['baseurl'] . "/$file"; diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index c6784a5824..3901108e59 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -865,6 +865,48 @@ EOF; } } + /** + * @ticket 35106 + */ + function test_wp_calculate_image_srcset_with_absolute_path_in_meta() { + global $_wp_additional_image_sizes; + + $year_month = date('Y/m'); + $image_meta = wp_get_attachment_metadata( self::$large_id ); + $uploads_dir_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/'; + + // Set up test cases for all expected size names. + $intermediates = array( 'medium', 'medium_large', 'large', 'full' ); + + // Add any soft crop intermediate sizes. + foreach ( $_wp_additional_image_sizes as $name => $additional_size ) { + if ( ! $_wp_additional_image_sizes[$name]['crop'] || 0 === $_wp_additional_image_sizes[$name]['height'] ) { + $intermediates[] = $name; + } + } + + $expected = ''; + + foreach( $image_meta['sizes'] as $name => $size ) { + // Whitelist the sizes that should be included so we pick up 'medium_large' in 4.4. + if ( in_array( $name, $intermediates ) ) { + $expected .= $uploads_dir_url . $year_month . '/' . $size['file'] . ' ' . $size['width'] . 'w, '; + } + } + + // Add the full size width at the end. + $expected .= $uploads_dir_url . $image_meta['file'] . ' ' . $image_meta['width'] .'w'; + + // Prepend an absolute path to simulate a pre-2.7 upload + $image_meta['file'] = 'H:\home\wordpress\trunk/wp-content/uploads/' . $image_meta['file']; + + foreach ( $intermediates as $int ) { + $image_url = wp_get_attachment_image_url( self::$large_id, $int ); + $size_array = $this->_get_image_size_array_from_name( $int ); + $this->assertSame( $expected, wp_calculate_image_srcset( $size_array, $image_url, $image_meta ) ); + } + } + /** * @ticket 33641 */