- Introduce `wp_image_file_matches_image_meta()` utility function to check whether the image meta (retrieved by attachment ID) matches an image path or URI. A mismatch may happen in some cases, for example after the posts have been exported from one website and imported in another.
- Add unit tests for the new function.
- Improve `wp_image_src_get_dimensions()` a bit and use the new function to prevent these edge cases.

Fixes #50543.

git-svn-id: https://develop.svn.wordpress.org/trunk@48329 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Ozz 2020-07-05 23:30:36 +00:00
parent 530eedb538
commit 27ccafd0e9
2 changed files with 117 additions and 8 deletions

View File

@ -1497,6 +1497,65 @@ function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null,
return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id );
}
/**
* Determines if the image meta data is for the image source file.
*
* The image meta data is retrieved by attachment post ID. In some cases the post IDs may change.
* For example when the website is exported and imported at another website. Then the
* attachment post IDs that are in post_content for the exported website may not match
* the same attachments at the new website.
*
* @since 5.5.0
*
* @param string $image_location The full path or URI to the image file.
* @param array $image_meta The attachment meta data as returned by 'wp_get_attachment_metadata()'.
* @return bool Whether the image meta is for this image file.
*/
function wp_image_file_matches_image_meta( $image_location, $image_meta ) {
$match = false;
// Ensure the $image_meta is valid.
if ( isset( $image_meta['file'] ) && strlen( $image_meta['file'] ) > 4 ) {
// Remove quiery args if image URI.
list( $image_location ) = explode( '?', $image_location );
// Check if the relative image path from the image meta is at the end of $image_location.
if ( strrpos( $image_location, $image_meta['file'] ) === strlen( $image_location ) - strlen( $image_meta['file'] ) ) {
$match = true;
}
if ( ! empty( $image_meta['sizes'] ) ) {
// Retrieve the uploads sub-directory from the full size image.
$dirname = _wp_get_attachment_relative_path( $image_meta['file'] );
if ( $dirname ) {
$dirname = trailingslashit( $dirname );
}
foreach ( $image_meta['sizes'] as $image_size_data ) {
$relative_path = $dirname . $image_size_data['file'];
if ( strrpos( $image_location, $relative_path ) === strlen( $image_location ) - strlen( $relative_path ) ) {
$match = true;
break;
}
}
}
}
/**
* Filter whether an image path or URI matches image meta.
*
* @since 5.5.0
*
* @param bool $match Whether the image relative path from the image meta
* matches the end of the URI or path to the image file.
* @param string $image_location Full path or URI to the tested image file.
* @param array $image_meta The image meta data being tested.
*/
return apply_filters( 'wp_image_file_matches_image_meta', $match, $image_location, $image_meta );
}
/**
* Determines an image's width and height dimensions based on the source file.
*
@ -1508,21 +1567,28 @@ function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null,
* or false if dimensions cannot be determined.
*/
function wp_image_src_get_dimensions( $image_src, $image_meta ) {
$image_filename = wp_basename( $image_src );
if ( ! wp_image_file_matches_image_meta( $image_src, $image_meta ) ) {
return false;
}
if ( wp_basename( $image_meta['file'] ) === $image_filename ) {
// Is it a full size image?
if ( strpos( $image_src, $image_meta['file'] ) !== false ) {
return array(
(int) $image_meta['width'],
(int) $image_meta['height'],
);
}
foreach ( $image_meta['sizes'] as $image_size_data ) {
if ( $image_filename === $image_size_data['file'] ) {
return array(
(int) $image_size_data['width'],
(int) $image_size_data['height'],
);
if ( ! empty( $image_meta['sizes'] ) ) {
$src_filename = wp_basename( $image_src );
foreach ( $image_meta['sizes'] as $image_size_data ) {
if ( $src_filename === $image_size_data['file'] ) {
return array(
(int) $image_size_data['width'],
(int) $image_size_data['height'],
);
}
}
}

View File

@ -2808,6 +2808,49 @@ EOF;
'arbitrary context => true' => array( 'something_completely_arbitrary', true ),
);
}
/**
* @ticket 50543
*/
function test_wp_image_file_matches_image_meta() {
$image_meta = wp_get_attachment_metadata( self::$large_id );
$image_src_full = wp_get_attachment_image_url( self::$large_id, 'full' );
$image_src_medium = wp_get_attachment_image_url( self::$large_id, 'medium' );
$this->assertTrue( wp_image_file_matches_image_meta( $image_src_full, $image_meta ) );
$this->assertTrue( wp_image_file_matches_image_meta( $image_src_medium, $image_meta ) );
}
/**
* @ticket 50543
*/
function test_wp_image_file_matches_image_meta_no_subsizes() {
$image_meta = wp_get_attachment_metadata( self::$large_id );
$image_src = wp_get_attachment_image_url( self::$large_id, 'full' );
$image_meta['sizes'] = array();
$this->assertTrue( wp_image_file_matches_image_meta( $image_src, $image_meta ) );
}
/**
* @ticket 50543
*/
function test_wp_image_file_matches_image_meta_invalid_meta() {
$image_meta = ''; // Attachment is not an image.
$image_src = $this->img_url;
$this->assertFalse( wp_image_file_matches_image_meta( $image_src, $image_meta ) );
}
/**
* @ticket 50543
*/
function test_wp_image_file_matches_image_meta_different_meta() {
$image_meta = wp_get_attachment_metadata( self::$large_id );
$image_src = $this->img_url; // Different image.
$this->assertFalse( wp_image_file_matches_image_meta( $image_src, $image_meta ) );
}
}
/**