From ffb2db05218dd406ed8f0de49f5d6e3a14e1c13a Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Wed, 20 Jul 2016 07:34:54 +0000 Subject: [PATCH] Media: Clean up prior image edits if `IMAGE_EDIT_OVERWRITE` is true. When `IMAGE_EDIT_OVERWRITE` is set to true, edited image files are supposed to be deleted when an image is restored to the original. However, when an image was edited more than once, and then restored, files created during previous edits were left behind. Fixes this behavior by updating `wp_save_image()` to clean up leftover images after each edit when `IMAGE_EDIT_OVERWRITE` is true. Props bradt, chriscct7, joemcgill. Fixes #32171. git-svn-id: https://develop.svn.wordpress.org/trunk@38113 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/image-edit.php | 15 +++++++++ tests/phpunit/tests/ajax/MediaEdit.php | 46 ++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) 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.' ); + } + } }