-
Notifications
You must be signed in to change notification settings - Fork 40
create a backup of the original image #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
4680f5c
e154eb9
f53f00b
ba97e04
3933d3c
c91a855
7ea5ea3
2446827
24c7c0a
435823c
a522659
6882d97
9c5b056
b765371
1d86da6
43991bf
3a863f7
fd2bdc8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -221,8 +221,9 @@ public function compress() { | |||||||||||||
| if ( ! $size->is_duplicate() ) { | ||||||||||||||
| $size->add_tiny_meta_start(); | ||||||||||||||
| $this->update_tiny_post_meta(); | ||||||||||||||
| $resize = $this->settings->get_resize_options( $size_name ); | ||||||||||||||
| $preserve = $this->settings->get_preserve_options( $size_name ); | ||||||||||||||
| $backup_created = $this->create_backup( $size_name, $size->filename ); | ||||||||||||||
| $resize = $this->settings->get_resize_options( $size_name ); | ||||||||||||||
| $preserve = $this->settings->get_preserve_options( $size_name ); | ||||||||||||||
| Tiny_Logger::debug( | ||||||||||||||
| 'compress size', | ||||||||||||||
| array( | ||||||||||||||
|
|
@@ -238,6 +239,7 @@ public function compress() { | |||||||||||||
| 'has_been_compressed' => $size->has_been_compressed(), | ||||||||||||||
| 'filesize' => $size->filesize(), | ||||||||||||||
| 'mimetype' => $size->mimetype(), | ||||||||||||||
| 'backup' => $backup_created, | ||||||||||||||
| ) | ||||||||||||||
| ); | ||||||||||||||
| try { | ||||||||||||||
|
|
@@ -605,4 +607,39 @@ public function mark_as_compressed() { | |||||||||||||
|
|
||||||||||||||
| $this->update_tiny_post_meta(); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * creates a backup of the image as <originalfile>.bak.<extension> | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To not interfere with existing plugins and whatever watches the file upload folder. Maybe write the files to another folder? e.g TinifyBackups/{original_path} |
||||||||||||||
| * | ||||||||||||||
| * @param string $size_name name of the size | ||||||||||||||
| * @param string $filepath path to file that needs backup | ||||||||||||||
| * @return bool true when backup is created | ||||||||||||||
| */ | ||||||||||||||
| private function create_backup( $size_name, $filepath ) { | ||||||||||||||
| if ( ! $this->needs_backup( $size_name ) ) { | ||||||||||||||
| return false; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| $fileinfo = pathinfo( $filepath ); | ||||||||||||||
| $backup_file = sprintf( | ||||||||||||||
| '%s%s.bak.%s', | ||||||||||||||
| trailingslashit( $fileinfo['dirname'] ), | ||||||||||||||
| $fileinfo['filename'], | ||||||||||||||
| $fileinfo['extension'] | ||||||||||||||
| ); | ||||||||||||||
|
|
||||||||||||||
|
||||||||||||||
| if ( file_exists( $backup_file ) ) { | |
| // Backup already exists; keep the first backup (original upload) intact. | |
| return true; | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -123,6 +123,9 @@ public function admin_init() { | |||||||||||||||||
| $field = self::get_prefixed_name( 'resize_original' ); | ||||||||||||||||||
| register_setting( 'tinify', $field ); | ||||||||||||||||||
|
|
||||||||||||||||||
| $field = self::get_prefixed_name( 'backup' ); | ||||||||||||||||||
| register_setting( 'tinify', $field ); | ||||||||||||||||||
|
|
||||||||||||||||||
| $field = self::get_prefixed_name( 'preserve_data' ); | ||||||||||||||||||
| register_setting( 'tinify', $field ); | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -305,6 +308,16 @@ public function new_plugin_install() { | |||||||||||||||||
| return ! $compression_timing; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| public function get_backup_enabled() { | ||||||||||||||||||
| $sizes = $this->get_sizes(); | ||||||||||||||||||
| if ( ! $sizes[ Tiny_Image::ORIGINAL ]['tinify'] ) { | ||||||||||||||||||
| return false; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| $setting = get_option( self::get_prefixed_name( 'backup' ) ); | ||||||||||||||||||
| return isset( $setting['enabled'] ) && 'on' === $setting['enabled']; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| public function get_resize_enabled() { | ||||||||||||||||||
| /* This only applies if the original is being resized. */ | ||||||||||||||||||
| $sizes = $this->get_sizes(); | ||||||||||||||||||
|
|
@@ -343,6 +356,12 @@ public function get_preserve_enabled( $name ) { | |||||||||||||||||
| return isset( $setting[ $name ] ) && 'on' === $setting[ $name ]; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| /** | ||||||||||||||||||
| * Retrieves the preserve options for the original image | ||||||||||||||||||
| * | ||||||||||||||||||
| * @param string - size name | ||||||||||||||||||
| * @return false|array<string> false if size is not original, otherwise array of preserved keys | ||||||||||||||||||
|
Comment on lines
+360
to
+363
|
||||||||||||||||||
| * Retrieves the preserve options for the original image | |
| * | |
| * @param string - size name | |
| * @return false|array<string> false if size is not original, otherwise array of preserved keys | |
| * Retrieves the preserve options for the original image. | |
| * | |
| * @param string $size_name Size name. | |
| * @return array<string>|false Array of preserved keys if size is original, or false otherwise. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -282,6 +282,14 @@ public function createImage($file_size, $path, $name) | |||||
| ->at($dir); | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Creates images on the virtual disk for testing | ||||||
| * @param null|array $sizes Array of size => bytes to create, file will be named $name-$size.png | ||||||
|
||||||
| * @param null|array $sizes Array of size => bytes to create, file will be named $name-$size.png | |
| * @param null|array $sizes Array of size name (array key) => bytes to create; each file will be named "$name-<size name>.png" |
Copilot
AI
Mar 31, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docblock says "@return array object containing metadata", but getTestMetadata() returns a plain array. Consider updating the @return description to avoid confusion for test authors.
| * @return array object containing metadata | |
| * @return array metadata array |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -306,4 +306,94 @@ public function test_conversion_same_mimetype() | |
| // second call should be only with image/webp because first call was a image/webp | ||
| $this->assertEquals(array('image/webp'), $compress_calls[1]['convert_to']); | ||
| } | ||
|
|
||
| public function test_creates_backup_of_original_image() { | ||
| $this->wp->addOption('tinypng_backup', array( | ||
| 'enabled' => 'on', | ||
| )); | ||
| $this->wp->addOption('tinypng_sizes', array( | ||
| Tiny_Image::ORIGINAL => 'on', | ||
| )); | ||
| $this->wp->stub('get_post_mime_type', function () { | ||
| return 'image/png'; | ||
| }); | ||
|
|
||
| $input_dir = '26/03'; | ||
| $input_name = 'testforbackup'; | ||
| $this->wp->createImages(array(), 1000, $input_dir, $input_name); | ||
|
|
||
| $settings = new Tiny_Settings(); | ||
| $mock_compressor = $this->createMock(Tiny_Compress::class); | ||
| $settings->set_compressor($mock_compressor); | ||
|
|
||
| $metadata = $this->wp->getTestMetadata($input_dir, $input_name); | ||
|
Comment on lines
+325
to
+329
|
||
| $tinyimg = new Tiny_Image($settings, 999, $metadata); | ||
| $tinyimg->compress(); | ||
|
|
||
| $this->assertTrue( | ||
| file_exists( $this->vfs->url() . '/wp-content/uploads/' . $input_dir . '/' . $input_name . '.bak.png' ) , | ||
| 'backup of file should be created'); | ||
| } | ||
|
|
||
| public function test_will_not_backup_other_sizes() { | ||
| $this->wp->addOption('tinypng_backup', array( | ||
| 'enabled' => 'on', | ||
| )); | ||
| $this->wp->addOption('tinypng_sizes', array( | ||
| 'thumbnail' => 'on', | ||
| )); | ||
| $this->wp->stub('get_post_mime_type', function () { | ||
| return 'image/png'; | ||
| }); | ||
|
|
||
| $input_dir = '26/03'; | ||
| $input_name = 'testforbackup'; | ||
| $this->wp->createImages(array( | ||
| 'thumbnail' => 1000, | ||
| ), 1000, $input_dir, $input_name); | ||
|
|
||
| $settings = new Tiny_Settings(); | ||
| $mock_compressor = $this->createMock(Tiny_Compress::class); | ||
| $settings->set_compressor($mock_compressor); | ||
|
|
||
| $metadata = $this->wp->getTestMetadata($input_dir, $input_name); | ||
|
Comment on lines
+355
to
+359
|
||
| $tinyimg = new Tiny_Image($settings, 999, $metadata); | ||
| $tinyimg->compress(); | ||
|
|
||
| $this->assertFalse( | ||
| file_exists( $this->vfs->url() . '/wp-content/uploads/' . $input_dir . '/' . $input_name . '.bak.png' ) , | ||
| 'backup of original should not exist'); | ||
|
|
||
| $this->assertFalse( | ||
| file_exists( $this->vfs->url() . '/wp-content/uploads/' . $input_dir . '/' . $input_name . '-thumbnail.bak.png' ) , | ||
| 'backup of thumbnail should not exist'); | ||
| } | ||
|
|
||
| public function test_will_not_backup_when_disabled() { | ||
| $this->wp->addOption('tinypng_backup', array( | ||
| 'enabled' => false, | ||
| )); | ||
| $this->wp->addOption('tinypng_sizes', array( | ||
| Tiny_Image::ORIGINAL => 'on', | ||
| )); | ||
| $this->wp->stub('get_post_mime_type', function () { | ||
| return 'image/png'; | ||
| }); | ||
|
|
||
| $input_dir = '26/03'; | ||
| $input_name = 'testforbackup'; | ||
| $this->wp->createImages(array(), 1000, $input_dir, $input_name); | ||
|
|
||
| $settings = new Tiny_Settings(); | ||
| $mock_compressor = $this->createMock(Tiny_Compress::class); | ||
| $settings->set_compressor($mock_compressor); | ||
|
|
||
| $metadata = $this->wp->getTestMetadata($input_dir, $input_name); | ||
| $tinyimg = new Tiny_Image($settings, 999, $metadata); | ||
|
Comment on lines
+387
to
+392
|
||
| $tinyimg->compress(); | ||
|
|
||
| $this->assertFalse( | ||
| file_exists( $this->vfs->url() . '/wp-content/uploads/' . $input_dir . '/' . $input_name . '.bak.png' ) , | ||
| 'backup of original should not exist'); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Backup creation is triggered for every unprocessed size (including sizes that are only being processed for conversion). This can create/overwrite the .bak file from an already-compressed original, which defeats the goal of backing up the uncompressed upload. Consider only creating the backup when the original is actually uncompressed (e.g., gate on the Tiny_Image_Size::uncompressed() state) and avoid backing up during conversion-only runs.