From 3be01968ecc1ddbe98b89b6ab19593511bfdddb4 Mon Sep 17 00:00:00 2001 From: Stephen Holdaway Date: Wed, 2 Apr 2014 13:30:12 +1300 Subject: [PATCH] Delete formatted images after image upload This change fixes an issue where old/existing formatted images are used when a filename is reused (by overwrite or by coincidence), regardless of if the file contents have changed. To users this mainly manifests as a file overwrite appearing not to work; the thumbnails in the CMS show the original image until regeneration is forced. Calling Image::deleteFormattedImages() after image upload ensures that no stagnant formatted images will be used. --- filesystem/Upload.php | 1 + model/Image.php | 5 ++++ tests/filesystem/UploadTest.php | 42 +++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/filesystem/Upload.php b/filesystem/Upload.php index ec8b7ca12..f02904baa 100644 --- a/filesystem/Upload.php +++ b/filesystem/Upload.php @@ -186,6 +186,7 @@ class Upload extends Controller { // This is to prevent it from trying to rename the file $this->file->Name = basename($relativeFilePath); $this->file->write(); + $this->file->onAfterUpload(); $this->extend('onAfterLoad', $this->file); //to allow extensions to e.g. create a version after an upload return true; } else { diff --git a/model/Image.php b/model/Image.php index 07214b736..b9b28bc93 100644 --- a/model/Image.php +++ b/model/Image.php @@ -640,6 +640,11 @@ class Image extends File { return self::ORIENTATION_SQUARE; } } + + public function onAfterUpload() { + $this->deleteFormattedImages(); + parent::onAfterUpload(); + } protected function onBeforeDelete() { parent::onBeforeDelete(); diff --git a/tests/filesystem/UploadTest.php b/tests/filesystem/UploadTest.php index 48a833027..2649e36a3 100644 --- a/tests/filesystem/UploadTest.php +++ b/tests/filesystem/UploadTest.php @@ -465,6 +465,48 @@ class UploadTest extends SapphireTest { $file3->delete(); } + public function testDeleteResampledImagesOnUpload() { + $tmpFileName = 'UploadTest-testUpload.jpg'; + $tmpFilePath = TEMP_FOLDER . '/' . $tmpFileName; + + $uploadImage = function() use ($tmpFileName, $tmpFilePath) { + copy(__DIR__ . '/gdtest/test_jpg.jpg', $tmpFilePath); + + // emulates the $_FILES array + $tmpFile = array( + 'name' => $tmpFileName, + 'type' => 'text/plaintext', + 'size' => filesize($tmpFilePath), + 'tmp_name' => $tmpFilePath, + 'extension' => 'jpg', + 'error' => UPLOAD_ERR_OK, + ); + + $v = new UploadTest_Validator(); + + // test upload into default folder + $u = new Upload(); + $u->setReplaceFile(true); + $u->setValidator($v); + $u->load($tmpFile); + return $u->getFile(); + }; + + // Image upload and generate a resampled image + $image = $uploadImage(); + $resampled = $image->ResizedImage(123, 456); + $resampledPath = $resampled->getFullPath(); + $this->assertTrue(file_exists($resampledPath)); + + // Re-upload the image, overwriting the original + // Resampled images should removed when their parent file is overwritten + $image = $uploadImage(); + $this->assertFalse(file_exists($resampledPath)); + + unlink($tmpFilePath); + $image->delete(); + } + } class UploadTest_Validator extends Upload_Validator implements TestOnly {