From 6a07d7a81438af2864ab9a59418632bc983575ad Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Wed, 9 Oct 2024 23:30:05 +0000 Subject: [PATCH] Media: Update file size meta data when editing images. Fixes an error in which the file size meta data retained the original upload's values follow a user editing the images in the media screen. The original images' file sizes are now stored in the backup image data to allow for them to be restored when a user restores the original image. Props ankit-k-gupta, antpb, audrasjb, chaion07, gauravsingh7, joedolson, oglekler, pls78, rajinsharwar, sayedulsayem, vertisoft. Fixes #59684. git-svn-id: https://develop.svn.wordpress.org/trunk@59202 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/image-edit.php | 32 +++++--- .../phpunit/tests/ajax/wpAjaxImageEditor.php | 80 +++++++++++++++++++ 2 files changed, 102 insertions(+), 10 deletions(-) diff --git a/src/wp-admin/includes/image-edit.php b/src/wp-admin/includes/image-edit.php index 5417eac45e7b0..7f9ebf7f9f875 100644 --- a/src/wp-admin/includes/image-edit.php +++ b/src/wp-admin/includes/image-edit.php @@ -826,9 +826,10 @@ function wp_restore_image( $post_id ) { } } elseif ( isset( $meta['width'], $meta['height'] ) ) { $backup_sizes[ "full-$suffix" ] = array( - 'width' => $meta['width'], - 'height' => $meta['height'], - 'file' => $parts['basename'], + 'width' => $meta['width'], + 'height' => $meta['height'], + 'filesize' => $meta['filesize'], + 'file' => $parts['basename'], ); } } @@ -839,6 +840,14 @@ function wp_restore_image( $post_id ) { $meta['file'] = _wp_relative_upload_path( $restored_file ); $meta['width'] = $data['width']; $meta['height'] = $data['height']; + if ( isset( $data['filesize'] ) ) { + /* + * Restore the original filesize if it was backed up. + * + * See https://core.trac.wordpress.org/ticket/59684. + */ + $meta['filesize'] = $data['filesize']; + } } foreach ( $default_sizes as $default_size ) { @@ -997,8 +1006,9 @@ function wp_save_image( $post_id ) { } } + $saved_image = wp_save_image_file( $new_path, $img, $post->post_mime_type, $post_id ); // Save the full-size file, also needed to create sub-sizes. - if ( ! wp_save_image_file( $new_path, $img, $post->post_mime_type, $post_id ) ) { + if ( ! $saved_image ) { $return->error = esc_js( __( 'Unable to save the image.' ) ); return $return; } @@ -1018,9 +1028,10 @@ function wp_save_image( $post_id ) { if ( $tag ) { $backup_sizes[ $tag ] = array( - 'width' => $meta['width'], - 'height' => $meta['height'], - 'file' => $basename, + 'width' => $meta['width'], + 'height' => $meta['height'], + 'filesize' => $meta['filesize'], + 'file' => $basename, ); } @@ -1028,9 +1039,10 @@ function wp_save_image( $post_id ) { $meta['file'] = _wp_relative_upload_path( $new_path ); - $size = $img->get_size(); - $meta['width'] = $size['width']; - $meta['height'] = $size['height']; + $size = $img->get_size(); + $meta['width'] = $size['width']; + $meta['height'] = $size['height']; + $meta['filesize'] = $saved_image['filesize']; if ( $success && ( 'nothumb' === $target || 'all' === $target ) ) { $sizes = get_intermediate_image_sizes(); diff --git a/tests/phpunit/tests/ajax/wpAjaxImageEditor.php b/tests/phpunit/tests/ajax/wpAjaxImageEditor.php index 89745d645883c..205f61636149c 100644 --- a/tests/phpunit/tests/ajax/wpAjaxImageEditor.php +++ b/tests/phpunit/tests/ajax/wpAjaxImageEditor.php @@ -114,4 +114,84 @@ public function testImageEditOverwriteConstant() { $this->assertSame( array(), $files_that_should_not_exist ); } } + + /** + * Ensure the filesize is updated after editing an image. + * + * Tests that the image meta data file size is updated after editing an image, + * this includes both the full size image and all the generated sizes. + * + * @ticket 59684 + */ + public function test_filesize_updated_after_editing_an_image() { + require_once ABSPATH . 'wp-admin/includes/image-edit.php'; + + $filename = DIR_TESTDATA . '/images/canola.jpg'; + $contents = file_get_contents( $filename ); + + $upload = wp_upload_bits( wp_basename( $filename ), null, $contents ); + $id = $this->_make_attachment( $upload ); + $original_image_meta = wp_get_attachment_metadata( $id ); + + $_REQUEST['action'] = 'image-editor'; + $_REQUEST['context'] = 'edit-attachment'; + $_REQUEST['postid'] = $id; + $_REQUEST['target'] = 'all'; + $_REQUEST['do'] = 'save'; + $_REQUEST['history'] = '[{"c":{"x":5,"y":8,"w":289,"h":322}}]'; + + wp_save_image( $id ); + + $post_edit_meta = wp_get_attachment_metadata( $id ); + + $pre_file_sizes = array_combine( array_keys( $original_image_meta['sizes'] ), array_column( $original_image_meta['sizes'], 'filesize' ) ); + $pre_file_sizes['full'] = $original_image_meta['filesize']; + + $post_file_sizes = array_combine( array_keys( $post_edit_meta['sizes'] ), array_column( $post_edit_meta['sizes'], 'filesize' ) ); + $post_file_sizes['full'] = $post_edit_meta['filesize']; + + foreach ( $pre_file_sizes as $size => $size_filesize ) { + // These are asserted individually as each image size needs to be checked separately. + $this->assertNotSame( $size_filesize, $post_file_sizes[ $size ], "Filesize for $size should have changed after editing an image." ); + } + } + + /** + * Ensure the filesize is restored after restoring the original image. + * + * Tests that the image meta data file size is restored after restoring the original image, + * this includes both the full size image and all the generated sizes. + * + * @ticket 59684 + */ + public function test_filesize_restored_after_restoring_original_image() { + require_once ABSPATH . 'wp-admin/includes/image-edit.php'; + + $filename = DIR_TESTDATA . '/images/canola.jpg'; + $contents = file_get_contents( $filename ); + + $upload = wp_upload_bits( wp_basename( $filename ), null, $contents ); + $id = $this->_make_attachment( $upload ); + $original_image_meta = wp_get_attachment_metadata( $id ); + + $_REQUEST['action'] = 'image-editor'; + $_REQUEST['context'] = 'edit-attachment'; + $_REQUEST['postid'] = $id; + $_REQUEST['target'] = 'all'; + $_REQUEST['do'] = 'save'; + $_REQUEST['history'] = '[{"c":{"x":5,"y":8,"w":289,"h":322}}]'; + + wp_save_image( $id ); + wp_restore_image( $id ); + + $post_restore_meta = wp_get_attachment_metadata( $id ); + + $pre_file_sizes = array_combine( array_keys( $original_image_meta['sizes'] ), array_column( $original_image_meta['sizes'], 'filesize' ) ); + $pre_file_sizes['full'] = $original_image_meta['filesize']; + + $post_restore_file_sizes = array_combine( array_keys( $post_restore_meta['sizes'] ), array_column( $post_restore_meta['sizes'], 'filesize' ) ); + $post_restore_file_sizes['full'] = $post_restore_meta['filesize']; + + $this->assertSameSetsWithIndex( $pre_file_sizes, $post_restore_file_sizes, 'Filesize should have restored after restoring the original image.' ); + } }