From 4680f5c69666368ec68e8fd7dfdc992ff7ce9768 Mon Sep 17 00:00:00 2001 From: Sertii <36940685+Sreini@users.noreply.github.com> Date: Mon, 16 Feb 2026 07:34:38 +0100 Subject: [PATCH 01/11] release: 3.6.10 --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 565e7c67..aa6e9ea1 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Donate link: https://tinypng.com/ Tags: compress images, compression, image size, page speed, performance Requires at least: 4.0 Tested up to: 6.9 -Stable tag: 3.6.9 +Stable tag: 3.6.10 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html From 7ea5ea37ba7cb089062318cadbc7bf83d4330cbf Mon Sep 17 00:00:00 2001 From: tijmen Date: Wed, 18 Mar 2026 09:32:05 +0100 Subject: [PATCH 02/11] add checkbox for backup --- src/views/settings-original-image.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/views/settings-original-image.php b/src/views/settings-original-image.php index 261dd8d9..9c2172fd 100644 --- a/src/views/settings-original-image.php +++ b/src/views/settings-original-image.php @@ -69,6 +69,13 @@ render_preserve_input( + 'image', + esc_html__( + 'Make a backup of the original image', + 'tiny-compress-images' + ) + ); $this->render_preserve_input( 'creation', esc_html__( From 244682739b1fb495ec9b50eae2dfce7663492a3f Mon Sep 17 00:00:00 2001 From: tijmen Date: Wed, 18 Mar 2026 10:49:17 +0100 Subject: [PATCH 03/11] seperate backup settings from preserve --- src/class-tiny-compress.php | 2 +- src/class-tiny-settings.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/class-tiny-compress.php b/src/class-tiny-compress.php index d17f55c9..236e8880 100644 --- a/src/class-tiny-compress.php +++ b/src/class-tiny-compress.php @@ -96,7 +96,7 @@ public function get_status() { /** * Compresses a single file * - * @param [type] $file + * @param string $file path to file * @param array $resize_opts * @param array $preserve_opts * @param array{ string } conversion options diff --git a/src/class-tiny-settings.php b/src/class-tiny-settings.php index 290b8b0d..7f1a61c6 100644 --- a/src/class-tiny-settings.php +++ b/src/class-tiny-settings.php @@ -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 false if size is not original, otherwise array of preserved keys + */ public function get_preserve_options( $size_name ) { if ( ! Tiny_Image::is_original( $size_name ) ) { return false; From 24c7c0a43b01da75a16a89a6d73dad59b1d52eb4 Mon Sep 17 00:00:00 2001 From: tijmen Date: Wed, 18 Mar 2026 10:49:28 +0100 Subject: [PATCH 04/11] seperate settings --- src/views/settings-original-image.php | 29 ++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/views/settings-original-image.php b/src/views/settings-original-image.php index 9c2172fd..872055a3 100644 --- a/src/views/settings-original-image.php +++ b/src/views/settings-original-image.php @@ -68,14 +68,29 @@ +

+ get_backup_enabled(); + ?> + /> + +

+ render_preserve_input( - 'image', - esc_html__( - 'Make a backup of the original image', - 'tiny-compress-images' - ) - ); $this->render_preserve_input( 'creation', esc_html__( From 435823cdbe4031e8958845d047c5302e25b30afd Mon Sep 17 00:00:00 2001 From: tijmen Date: Wed, 18 Mar 2026 11:40:08 +0100 Subject: [PATCH 05/11] create backup of original image --- src/class-tiny-image.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/class-tiny-image.php b/src/class-tiny-image.php index a586f430..ec7a731c 100644 --- a/src/class-tiny-image.php +++ b/src/class-tiny-image.php @@ -221,6 +221,7 @@ public function compress() { if ( ! $size->is_duplicate() ) { $size->add_tiny_meta_start(); $this->update_tiny_post_meta(); + $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( @@ -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,34 @@ public function mark_as_compressed() { $this->update_tiny_post_meta(); } + + /** + * creates a backup of the image as .bak. + * + * @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 = $fileinfo['dirname'] . '/' . $fileinfo['filename'] . '.bak.' . $fileinfo['extension']; + + return copy( $filepath, $backup_file ); + } + + /** + * @param string $size_name name of the size + * @return bool true when backup needs to be created + */ + private function needs_backup( $size_name ) { + if ( ! self::is_original( $size_name ) ) { + return false; + } + + return $this->settings->get_backup_enabled(); + } } From a5226592bf1766a0eef8203d623243e33ad057de Mon Sep 17 00:00:00 2001 From: tijmen Date: Wed, 18 Mar 2026 11:52:06 +0100 Subject: [PATCH 06/11] add docs for tests --- test/unit/TinyTestCase.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/unit/TinyTestCase.php b/test/unit/TinyTestCase.php index 4838a404..c64f22d6 100644 --- a/test/unit/TinyTestCase.php +++ b/test/unit/TinyTestCase.php @@ -40,6 +40,11 @@ public static function client_supported() { } abstract class Tiny_TestCase extends TestCase { + /** + * WordPress stubs + * + * @var \WordPressStubs + */ protected $wp; protected $vfs; From 6882d97e995e9a05b413d8f6e1aeafa6ee13d216 Mon Sep 17 00:00:00 2001 From: tijmen Date: Wed, 18 Mar 2026 11:52:14 +0100 Subject: [PATCH 07/11] add docs for stubs --- test/helpers/wordpress.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/helpers/wordpress.php b/test/helpers/wordpress.php index ff1b2c0c..282ba4d9 100644 --- a/test/helpers/wordpress.php +++ b/test/helpers/wordpress.php @@ -282,6 +282,14 @@ public function createImage($file_size, $path, $name) ->at($dir); } + /** + * Creates images on the virtual disk for testing + * @param null|array array of size => bytes to create, file will be named $name-$size.png + * @param int bytes of image + * @param string path to image + * @param string name of the image + * @return void + */ public function createImages($sizes = null, $original_size = 12345, $path = '14/01', $name = 'test') { vfsStream::newDirectory(self::UPLOAD_DIR . "/$path")->at($this->vfs); @@ -309,6 +317,13 @@ public function createImagesFromJSON($virtual_images) } } + /** + * creates image meta data for testing + * + * @param string $path directory of the file in UPLOAD_DIR + * @param string $name name of the file without extension + * @return array object containing metadata + */ public function getTestMetadata($path = '14/01', $name = 'test') { $metadata = array( From 9c5b0568bdead4bbb6b4bb249cb0e7b76c7e7ded Mon Sep 17 00:00:00 2001 From: tijmen Date: Wed, 18 Mar 2026 15:35:36 +0100 Subject: [PATCH 08/11] add test --- src/class-tiny-image.php | 21 +++++++++++++-------- src/class-tiny-settings.php | 2 +- test/unit/TinyImageTest.php | 28 ++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/class-tiny-image.php b/src/class-tiny-image.php index ec7a731c..21837586 100644 --- a/src/class-tiny-image.php +++ b/src/class-tiny-image.php @@ -222,8 +222,8 @@ public function compress() { $size->add_tiny_meta_start(); $this->update_tiny_post_meta(); $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 ); + $resize = $this->settings->get_resize_options( $size_name ); + $preserve = $this->settings->get_preserve_options( $size_name ); Tiny_Logger::debug( 'compress size', array( @@ -239,7 +239,7 @@ public function compress() { 'has_been_compressed' => $size->has_been_compressed(), 'filesize' => $size->filesize(), 'mimetype' => $size->mimetype(), - 'backup' => $backup_created, + 'backup' => $backup_created, ) ); try { @@ -610,7 +610,7 @@ public function mark_as_compressed() { /** * creates a backup of the image as .bak. - * + * * @param string $size_name name of the size * @param string $filepath path to file that needs backup * @return bool true when backup is created @@ -619,10 +619,15 @@ private function create_backup( $size_name, $filepath ) { if ( ! $this->needs_backup( $size_name ) ) { return false; } - - $fileinfo = pathinfo($filepath); - $backup_file = $fileinfo['dirname'] . '/' . $fileinfo['filename'] . '.bak.' . $fileinfo['extension']; - + + $fileinfo = pathinfo( $filepath ); + $backup_file = sprintf( + '%s/%s.bak%s', + $fileinfo['dirname'], + $fileinfo['filename'], + $fileinfo['extension'] + ); + return copy( $filepath, $backup_file ); } diff --git a/src/class-tiny-settings.php b/src/class-tiny-settings.php index 7f1a61c6..fa5bbe49 100644 --- a/src/class-tiny-settings.php +++ b/src/class-tiny-settings.php @@ -358,7 +358,7 @@ public function get_preserve_enabled( $name ) { /** * Retrieves the preserve options for the original image - * + * * @param string - size name * @return false|array false if size is not original, otherwise array of preserved keys */ diff --git a/test/unit/TinyImageTest.php b/test/unit/TinyImageTest.php index f70f3b4a..537e183d 100644 --- a/test/unit/TinyImageTest.php +++ b/test/unit/TinyImageTest.php @@ -306,4 +306,32 @@ 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); + $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'); + } } From b765371a6c3e76353045f1d8b9f3920c6bf22176 Mon Sep 17 00:00:00 2001 From: tijmen Date: Wed, 18 Mar 2026 15:56:44 +0100 Subject: [PATCH 09/11] Add more tests --- src/class-tiny-image.php | 2 +- test/helpers/wordpress.php | 8 ++--- test/unit/TinyImageTest.php | 62 +++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/class-tiny-image.php b/src/class-tiny-image.php index 21837586..5626a75f 100644 --- a/src/class-tiny-image.php +++ b/src/class-tiny-image.php @@ -622,7 +622,7 @@ private function create_backup( $size_name, $filepath ) { $fileinfo = pathinfo( $filepath ); $backup_file = sprintf( - '%s/%s.bak%s', + '%s/%s.bak.%s', $fileinfo['dirname'], $fileinfo['filename'], $fileinfo['extension'] diff --git a/test/helpers/wordpress.php b/test/helpers/wordpress.php index 282ba4d9..50c0b32a 100644 --- a/test/helpers/wordpress.php +++ b/test/helpers/wordpress.php @@ -284,10 +284,10 @@ public function createImage($file_size, $path, $name) /** * Creates images on the virtual disk for testing - * @param null|array array of size => bytes to create, file will be named $name-$size.png - * @param int bytes of image - * @param string path to image - * @param string name of the image + * @param null|array $sizes Array of size => bytes to create, file will be named $name-$size.png + * @param int $original_size Bytes of image + * @param string $path Path to image + * @param string $name Name of the image * @return void */ public function createImages($sizes = null, $original_size = 12345, $path = '14/01', $name = 'test') diff --git a/test/unit/TinyImageTest.php b/test/unit/TinyImageTest.php index 537e183d..6f73c39f 100644 --- a/test/unit/TinyImageTest.php +++ b/test/unit/TinyImageTest.php @@ -334,4 +334,66 @@ public function test_creates_backup_of_original_image() { 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); + $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); + $tinyimg->compress(); + + $this->assertFalse( + file_exists( $this->vfs->url() . '/wp-content/uploads/' . $input_dir . '/' . $input_name . '.bak.png' ) , + 'backup of original should not exist'); + } } From 1d86da66005433b97f5f69d14af19bdf4d732684 Mon Sep 17 00:00:00 2001 From: tijmen Date: Wed, 18 Mar 2026 16:06:44 +0100 Subject: [PATCH 10/11] ensure trailing slash on dir --- src/class-tiny-image.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class-tiny-image.php b/src/class-tiny-image.php index 5626a75f..6109517d 100644 --- a/src/class-tiny-image.php +++ b/src/class-tiny-image.php @@ -622,8 +622,8 @@ private function create_backup( $size_name, $filepath ) { $fileinfo = pathinfo( $filepath ); $backup_file = sprintf( - '%s/%s.bak.%s', - $fileinfo['dirname'], + '%s%s.bak.%s', + trailingslashit($fileinfo['dirname']), $fileinfo['filename'], $fileinfo['extension'] ); From 43991bf578b83bcc40368a6e1082c1074f48ce74 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 19 Mar 2026 08:54:48 +0100 Subject: [PATCH 11/11] format --- src/class-tiny-image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class-tiny-image.php b/src/class-tiny-image.php index 6109517d..99e62384 100644 --- a/src/class-tiny-image.php +++ b/src/class-tiny-image.php @@ -623,7 +623,7 @@ private function create_backup( $size_name, $filepath ) { $fileinfo = pathinfo( $filepath ); $backup_file = sprintf( '%s%s.bak.%s', - trailingslashit($fileinfo['dirname']), + trailingslashit( $fileinfo['dirname'] ), $fileinfo['filename'], $fileinfo['extension'] );