diff --git a/src/wp-admin/includes/image-edit.php b/src/wp-admin/includes/image-edit.php index c614a7793e..2a6f6af0ea 100644 --- a/src/wp-admin/includes/image-edit.php +++ b/src/wp-admin/includes/image-edit.php @@ -825,6 +825,21 @@ function wp_save_image( $post_id ) { $success = $delete = $nocrop = true; } + /* + * We need to remove any existing resized image files because + * a new crop or rotate could generate different sizes (and hence, filenames), + * keeping the new resized images from overwriting the existing image files. + * https://core.trac.wordpress.org/ticket/32171 + */ + if ( defined( 'IMAGE_EDIT_OVERWRITE' ) && IMAGE_EDIT_OVERWRITE && ! empty( $meta['sizes'] ) ) { + foreach ( $meta['sizes'] as $size ) { + if ( ! empty( $size['file'] ) && preg_match( '/-e[0-9]{13}-/', $size['file'] ) ) { + $delete_file = path_join( $path_parts['dirname'], $size['file'] ); + wp_delete_file( $delete_file ); + } + } + } + if ( isset( $sizes ) ) { $_sizes = array(); diff --git a/tests/phpunit/tests/ajax/MediaEdit.php b/tests/phpunit/tests/ajax/MediaEdit.php index 7ef94694b2..2ec07562cc 100644 --- a/tests/phpunit/tests/ajax/MediaEdit.php +++ b/tests/phpunit/tests/ajax/MediaEdit.php @@ -51,4 +51,50 @@ class Tests_Ajax_MediaEdit extends WP_Ajax_UnitTestCase { $this->assertArrayHasKey('sizes', $media_meta, 'cropped attachment should have size data'); $this->assertArrayHasKey('medium', $media_meta['sizes'], 'cropped attachment should have data for medium size'); } + + /** + * @ticket 32171 + */ + public function testImageEditOverwriteConstant() { + define( 'IMAGE_EDIT_OVERWRITE', true ); + + include_once( ABSPATH . 'wp-admin/includes/image-edit.php' ); + + $filename = DIR_TESTDATA . '/images/canola.jpg'; + $contents = file_get_contents( $filename ); + + $upload = wp_upload_bits( basename( $filename ), null, $contents ); + $id = $this->_make_attachment( $upload ); + + $_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}}]'; + + $ret = wp_save_image( $id ); + + $media_meta = wp_get_attachment_metadata( $id ); + $sizes1 = $media_meta['sizes']; + + $_REQUEST['history'] = '[{"c":{"x":5,"y":8,"w":189,"h":322}}]'; + + $ret = wp_save_image( $id ); + + $media_meta = wp_get_attachment_metadata( $id ); + $sizes2 = $media_meta['sizes']; + + $file_path = dirname( get_attached_file( $id ) ); + + foreach ( $sizes1 as $key => $size ) { + if ( $sizes2[ $key ]['file'] !== $size['file'] ) { + $files_that_shouldnt_exist[] = $file_path . '/' . $size['file']; + } + } + + foreach ( $files_that_shouldnt_exist as $file ) { + $this->assertFalse( file_exists( $file ), 'IMAGE_EDIT_OVERWRITE is leaving garbage image files behind.' ); + } + } }