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/15] 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 0c8216567d6d60e908cddabeabd5bc82bbb6ce8a Mon Sep 17 00:00:00 2001
From: tijmen
Date: Thu, 26 Mar 2026 16:28:38 +0100
Subject: [PATCH 02/15] allow delivery to be undefined, defaults to picture
---
test/integration/utils.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/integration/utils.ts b/test/integration/utils.ts
index 01640e24..e6f7a59f 100644
--- a/test/integration/utils.ts
+++ b/test/integration/utils.ts
@@ -214,7 +214,7 @@ export async function deactivatePlugin(page: Page, pluginSlug: string) {
await plugin.getByLabel('Deactivate').click();
}
-export async function setConversionSettings(page: Page, settings: { convert: boolean; output?: 'smallest' | 'webp' | 'avif'; delivery: 'picture' | 'htaccess' }) {
+export async function setConversionSettings(page: Page, settings: { convert: boolean; output?: 'smallest' | 'webp' | 'avif'; delivery?: 'picture' | 'htaccess' }) {
await page.goto('/wp-admin/options-general.php?page=tinify');
if (settings.convert) {
From c677d0f979f30723324ffead43256cd6c7946d2d Mon Sep 17 00:00:00 2001
From: tijmen
Date: Mon, 30 Mar 2026 08:56:49 +0200
Subject: [PATCH 03/15] add feedback notice
---
src/class-tiny-notices.php | 16 ++++++++++++++++
src/views/notice-feedback.php | 5 +++++
2 files changed, 21 insertions(+)
create mode 100644 src/views/notice-feedback.php
diff --git a/src/class-tiny-notices.php b/src/class-tiny-notices.php
index fce29796..28d1ff73 100644
--- a/src/class-tiny-notices.php
+++ b/src/class-tiny-notices.php
@@ -102,6 +102,7 @@ private function show_stored() {
public function show_notices() {
$this->incompatible_plugins_notice();
$this->outdated_platform_notice();
+ $this->feedback_notice();
}
public function add( $name, $message ) {
@@ -303,4 +304,19 @@ function () use ( $notice ) {
}
);
}
+
+ /**
+ * Checks if the feedback notice should be displayed and hooks it to admin_notices.
+ *
+ * @return void
+ */
+ function feedback_notice() {
+ if ( ! isset( $this->dismissals[ 'feedback' ] ) ) {
+ add_action('admin_notices', array( $this, 'feedback_notice_show' ) );
+ }
+ }
+
+ function feedback_notice_show() {
+ include __DIR__ . '/views/notice-feedback.php';
+ }
}
diff --git a/src/views/notice-feedback.php b/src/views/notice-feedback.php
new file mode 100644
index 00000000..099d5630
--- /dev/null
+++ b/src/views/notice-feedback.php
@@ -0,0 +1,5 @@
+
\ No newline at end of file
From 709257b05962db09e7246676d27a9e56506a7409 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Mon, 30 Mar 2026 09:24:01 +0200
Subject: [PATCH 04/15] show feedback notice on more than 5 compressions
---
src/class-tiny-notices.php | 30 ++++++++++++++++++++++++++++--
src/class-tiny-settings.php | 2 +-
src/views/notice-feedback.php | 17 ++++++++++++++---
3 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/src/class-tiny-notices.php b/src/class-tiny-notices.php
index 28d1ff73..b8714170 100644
--- a/src/class-tiny-notices.php
+++ b/src/class-tiny-notices.php
@@ -22,6 +22,30 @@ class Tiny_Notices extends Tiny_WP_Base {
private $notices;
private $dismissals;
+ /**
+ * Tiny_Settings instance.
+ *
+ * @var Tiny_Settings
+ */
+ private $settings;
+
+ /**
+ * The number of compressions required before showing the feedback notice.
+ *
+ * @var int
+ */
+ private $compressions_for_feedback = 5;
+
+ /**
+ * Tiny_Notices constructor.
+ *
+ * @param Tiny_Settings $settings The settings instance.
+ */
+ public function __construct( $settings ) {
+ parent::__construct();
+ $this->settings = $settings;
+ }
+
protected static $incompatible_plugins = array(
'CheetahO Image Optimizer' => 'cheetaho-image-optimizer/cheetaho.php',
'EWWW Image Optimizer' => 'ewww-image-optimizer/ewww-image-optimizer.php',
@@ -311,8 +335,10 @@ function () use ( $notice ) {
* @return void
*/
function feedback_notice() {
- if ( ! isset( $this->dismissals[ 'feedback' ] ) ) {
- add_action('admin_notices', array( $this, 'feedback_notice_show' ) );
+ if ( ! isset( $this->dismissals['feedback'] ) &&
+ $this->settings->get_compression_count() > $this->compressions_for_feedback
+ ) {
+ add_action( 'admin_notices', array( $this, 'feedback_notice_show' ) );
}
}
diff --git a/src/class-tiny-settings.php b/src/class-tiny-settings.php
index 290b8b0d..d19e8765 100644
--- a/src/class-tiny-settings.php
+++ b/src/class-tiny-settings.php
@@ -29,7 +29,7 @@ class Tiny_Settings extends Tiny_WP_Base {
public function __construct() {
parent::__construct();
- $this->notices = new Tiny_Notices();
+ $this->notices = new Tiny_Notices( $this );
new Tiny_Diagnostics( $this );
}
diff --git a/src/views/notice-feedback.php b/src/views/notice-feedback.php
index 099d5630..813a909e 100644
--- a/src/views/notice-feedback.php
+++ b/src/views/notice-feedback.php
@@ -1,5 +1,16 @@
+%s',
+ esc_url( $review_url ),
+ esc_html__( 'Leave a review', 'tiny-compress-images' )
+);
+?>
+
\ No newline at end of file
From d2b97fec6f2dc7a29ff309199254e3094dc4062b Mon Sep 17 00:00:00 2001
From: tijmen
Date: Mon, 30 Mar 2026 09:25:57 +0200
Subject: [PATCH 05/15] set visisiblity
---
src/class-tiny-notices.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/class-tiny-notices.php b/src/class-tiny-notices.php
index b8714170..f62391a3 100644
--- a/src/class-tiny-notices.php
+++ b/src/class-tiny-notices.php
@@ -34,7 +34,7 @@ class Tiny_Notices extends Tiny_WP_Base {
*
* @var int
*/
- private $compressions_for_feedback = 5;
+ private $compressions_for_feedback = 10;
/**
* Tiny_Notices constructor.
@@ -334,7 +334,7 @@ function () use ( $notice ) {
*
* @return void
*/
- function feedback_notice() {
+ private function feedback_notice() {
if ( ! isset( $this->dismissals['feedback'] ) &&
$this->settings->get_compression_count() > $this->compressions_for_feedback
) {
@@ -342,7 +342,7 @@ function feedback_notice() {
}
}
- function feedback_notice_show() {
+ private function feedback_notice_show() {
include __DIR__ . '/views/notice-feedback.php';
}
}
From 6b1149a209c66afc8f32c11596d56256d3f57bf4 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Mon, 30 Mar 2026 09:31:12 +0200
Subject: [PATCH 06/15] add constructor in test
---
test/unit/TinySettingsAjaxTest.php | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/test/unit/TinySettingsAjaxTest.php b/test/unit/TinySettingsAjaxTest.php
index 40fb44b4..1e05c810 100644
--- a/test/unit/TinySettingsAjaxTest.php
+++ b/test/unit/TinySettingsAjaxTest.php
@@ -4,6 +4,7 @@
class Tiny_Settings_Ajax_Test extends Tiny_TestCase {
protected $notices;
+ private $settings;
public function set_up() {
parent::set_up();
@@ -12,7 +13,8 @@ public function set_up() {
public function test_settings_ajax_init() {
$tiny_settings = new Tiny_Settings();
- $tiny_settings->ajax_init();
+ $this->settings = $tiny_settings;
+ $this->settings->ajax_init();
WordPressStubs::assertHook('wp_ajax_tiny_image_sizes_notice', array( $tiny_settings, 'image_sizes_notice' ));
WordPressStubs::assertHook('wp_ajax_tiny_account_status', array( $tiny_settings, 'account_status' ));
@@ -21,7 +23,7 @@ public function test_settings_ajax_init() {
}
public function test_notices_ajax_init() {
- $tiny_notices = new Tiny_Notices();
+ $tiny_notices = new Tiny_Notices( $this->settings );
$tiny_notices->ajax_init();
WordPressStubs::assertHook('wp_ajax_tiny_dismiss_notice', array( $tiny_notices, 'dismiss' ));
From 3126445c70963859e6718fde13de70af2683e8c5 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Mon, 30 Mar 2026 10:01:08 +0200
Subject: [PATCH 07/15] add assert to check if hook is not called
---
test/helpers/wordpress.php | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/test/helpers/wordpress.php b/test/helpers/wordpress.php
index ff1b2c0c..45e2406d 100644
--- a/test/helpers/wordpress.php
+++ b/test/helpers/wordpress.php
@@ -337,6 +337,34 @@ public function getTestMetadata($path = '14/01', $name = 'test')
* @param mixed $expected_args arguments to the hook
*/
public static function assertHook($hookname, $expected_args = null)
+ {
+ $found = self::findHook($hookname, $expected_args);
+
+ $message = is_null($expected_args)
+ ? sprintf('Expected hook "%s" to be called.', $hookname)
+ : sprintf('Expected hook "%s" to be called with the given arguments.', $hookname);
+
+ Assert::assertTrue($found, $message);
+ }
+
+ /**
+ * Testhelper to assert a hook has NOT been registered.
+ *
+ * @param string $hookname name of the filter or action
+ * @param mixed $expected_args arguments to the hook
+ */
+ public static function assertNotHook($hookname, $expected_args = null)
+ {
+ $found = self::findHook($hookname, $expected_args);
+
+ $message = is_null($expected_args)
+ ? sprintf('Expected hook "%s" NOT to be called.', $hookname)
+ : sprintf('Expected hook "%s" NOT to be called with the given arguments.', $hookname);
+
+ Assert::assertFalse($found, $message);
+ }
+
+ private static function findHook($hookname, $expected_args = null)
{
$hooks = array('add_action', 'add_filter');
$found = false;
@@ -363,11 +391,7 @@ public static function assertHook($hookname, $expected_args = null)
}
}
- $message = is_null($expected_args)
- ? sprintf('Expected hook "%s" to be called.', $hookname)
- : sprintf('Expected hook "%s" to be called with the given arguments.', $hookname);
-
- Assert::assertTrue($found, $message);
+ return $found;
}
}
From 8659390da904bceea76579eac7206316ced6c7a0 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Mon, 30 Mar 2026 10:01:19 +0200
Subject: [PATCH 08/15] assert when dismissed, do not show notice
---
test/unit/Tiny_Notices_Test.php | 86 +++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
create mode 100644 test/unit/Tiny_Notices_Test.php
diff --git a/test/unit/Tiny_Notices_Test.php b/test/unit/Tiny_Notices_Test.php
new file mode 100644
index 00000000..bccbc99f
--- /dev/null
+++ b/test/unit/Tiny_Notices_Test.php
@@ -0,0 +1,86 @@
+wp->addMethod( 'get_user_meta' );
+ $this->wp->addMethod( 'update_user_meta' );
+ $this->wp->addMethod( 'get_current_user_id' );
+
+ $this->settings = $this->createMock( Tiny_Settings::class );
+ $this->settings->method( 'get_compression_count' )->willReturn( 0 );
+
+ $this->wp->stub( 'current_user_can', function () {
+ return true;
+ } );
+
+ $this->subject = new Tiny_Notices( $this->settings );
+ }
+
+ /**
+ * Verifies that when the current user has the manage_options capability,
+ * calling admin_init() registers at least one admin_notices action.
+ */
+ public function test_registers_notices_when_user_can_manage_options() {
+ $this->subject->add( 'test', 'Test notice message' );
+
+ $this->subject->admin_init();
+
+ WordPressStubs::assertHook( 'admin_notices' );
+ }
+
+ /**
+ * Verifies that feedback_notice_show is hooked to admin_notices when the
+ * feedback notice has not been dismissed
+ */
+ public function test_registers_feedback_notice_when_not_dismissed() {
+ $this->settings = $this->createMock( Tiny_Settings::class );
+ $this->settings->method( 'get_compression_count' )->willReturn( 20 );
+ $this->subject = new Tiny_Notices( $this->settings );
+
+ $this->subject->show_notices();
+
+ WordPressStubs::assertHook( 'admin_notices', array( $this->subject, 'feedback_notice_show' ) );
+ }
+
+ /**
+ * Verifies that feedback_notice_show is hooked to admin_notices when the
+ * compression count is just above compressions_for_feedback
+ */
+ public function test_registers_feedback_notice_when_compressioncount_reached() {
+ $this->settings = $this->createMock( Tiny_Settings::class );
+ $this->settings->method( 'get_compression_count' )->willReturn( 11 );
+ $this->subject = new Tiny_Notices( $this->settings );
+
+ $this->subject->show_notices();
+
+ WordPressStubs::assertHook( 'admin_notices', array( $this->subject, 'feedback_notice_show' ) );
+ }
+
+
+ /**
+ * Verifies that feedback_notice_show is NOT hooked to admin_notices when
+ * the feedback notice has been dismissed by the user.
+ */
+ public function test_will_not_show_feedback_notice_when_dismissed() {
+ $this->settings = $this->createMock( Tiny_Settings::class );
+ $this->subject = new Tiny_Notices( $this->settings );
+
+ $this->wp->stub( 'get_user_meta', function () {
+ return array( 'feedback' => true );
+ } );
+
+ $this->subject->admin_init();
+
+ WordPressStubs::assertNotHook( 'admin_notices', array( $this->subject, 'feedback_notice_show' ) );
+ }
+
+}
From e78ec226cb2e3a430fd98d117512b2a94ad05bd5 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Tue, 31 Mar 2026 21:34:18 +0200
Subject: [PATCH 09/15] replace func with plain require
---
src/class-tiny-plugin.php | 12 ------------
src/views/dashboard-widget.php | 2 +-
src/views/request-review.php | 6 ++++++
src/views/settings.php | 4 ++--
4 files changed, 9 insertions(+), 15 deletions(-)
create mode 100644 src/views/request-review.php
diff --git a/src/class-tiny-plugin.php b/src/class-tiny-plugin.php
index 2236332d..facff188 100644
--- a/src/class-tiny-plugin.php
+++ b/src/class-tiny-plugin.php
@@ -861,18 +861,6 @@ public function clean_attachment( $post_id ) {
$tiny_image->delete_converted_image();
}
- public static function request_review() {
- $review_url =
- 'https://wordpress.org/support/plugin/tiny-compress-images/reviews/#new-post';
- $review_block = esc_html__( 'Enjoying TinyPNG?', 'tiny-compress-images' );
- $review_block .= ' ';
- $review_block .= sprintf(
- '%s',
- esc_url( $review_url ),
- esc_html__( 'Write a review', 'tiny-compress-images' )
- );
- return $review_block;
- }
public function mark_image_as_compressed() {
$response = $this->validate_ajax_attachment_request();
diff --git a/src/views/dashboard-widget.php b/src/views/dashboard-widget.php
index fadab1e3..24417574 100644
--- a/src/views/dashboard-widget.php
+++ b/src/views/dashboard-widget.php
@@ -72,7 +72,7 @@
/* translators: %s: friendly user name */
printf( esc_html__( '%s, this is great! Your entire library is optimized!', 'tiny-compress-images' ), $this->friendly_user_name() );
echo ' ';
- echo Tiny_Plugin::request_review();
+ require __DIR__ . '/request-review.php';
?>
diff --git a/src/views/request-review.php b/src/views/request-review.php
new file mode 100644
index 00000000..b6bd850a
--- /dev/null
+++ b/src/views/request-review.php
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/settings.php b/src/views/settings.php
index c12d4a6e..af788aed 100644
--- a/src/views/settings.php
+++ b/src/views/settings.php
@@ -56,8 +56,8 @@
-
-
+
+
From 853af5aca5980a465449504acb017e1cdc2c7000 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Tue, 31 Mar 2026 21:34:28 +0200
Subject: [PATCH 10/15] set hook func to public
---
src/class-tiny-notices.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/class-tiny-notices.php b/src/class-tiny-notices.php
index f62391a3..eae648dc 100644
--- a/src/class-tiny-notices.php
+++ b/src/class-tiny-notices.php
@@ -342,7 +342,7 @@ private function feedback_notice() {
}
}
- private function feedback_notice_show() {
+ public function feedback_notice_show() {
include __DIR__ . '/views/notice-feedback.php';
}
}
From eef7b4a8ca5da2399aa7172c693e32c2a0cf77c4 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Tue, 31 Mar 2026 21:37:13 +0200
Subject: [PATCH 11/15] Add review text on bulk page
---
src/views/bulk-optimization.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/views/bulk-optimization.php b/src/views/bulk-optimization.php
index 3ab5b62f..34507376 100644
--- a/src/views/bulk-optimization.php
+++ b/src/views/bulk-optimization.php
@@ -55,6 +55,7 @@
} elseif ( 0 == $stats['available-unoptimized-sizes'] ) {
/* translators: %s: friendly user name */
printf( esc_html__( '%s, this is great! Your entire library is optimized!', 'tiny-compress-images' ), $this->friendly_user_name() );
+ require __DIR__ . '/request-review.php';
} elseif ( $stats['optimized-image-sizes'] > 0 ) {
if ( $percentage_of_files > 75 ) {
/* translators: %s: friendly user name */
From df0bfbdd247edc5fa4031e78507a9d937b12ba86 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Tue, 31 Mar 2026 21:40:05 +0200
Subject: [PATCH 12/15] break line
---
src/views/bulk-optimization.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/views/bulk-optimization.php b/src/views/bulk-optimization.php
index 34507376..109afe38 100644
--- a/src/views/bulk-optimization.php
+++ b/src/views/bulk-optimization.php
@@ -55,6 +55,7 @@
} elseif ( 0 == $stats['available-unoptimized-sizes'] ) {
/* translators: %s: friendly user name */
printf( esc_html__( '%s, this is great! Your entire library is optimized!', 'tiny-compress-images' ), $this->friendly_user_name() );
+ echo '
';
require __DIR__ . '/request-review.php';
} elseif ( $stats['optimized-image-sizes'] > 0 ) {
if ( $percentage_of_files > 75 ) {
From b703d70d19b4473e3fa2950f44ddc7c2b365e687 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Wed, 1 Apr 2026 10:41:00 +0200
Subject: [PATCH 13/15] format
---
src/views/request-review.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/views/request-review.php b/src/views/request-review.php
index b6bd850a..0d43993f 100644
--- a/src/views/request-review.php
+++ b/src/views/request-review.php
@@ -1,6 +1,6 @@
-
+
-
+
\ No newline at end of file
From 584d54e3e6802dd901f5fb85da95c74a77748602 Mon Sep 17 00:00:00 2001
From: tijmen
Date: Wed, 1 Apr 2026 11:41:51 +0200
Subject: [PATCH 14/15] missing preslash
---
src/views/settings.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/views/settings.php b/src/views/settings.php
index af788aed..e240ac33 100644
--- a/src/views/settings.php
+++ b/src/views/settings.php
@@ -56,7 +56,7 @@
-
+
From ea8ccd48ed49c3be150f1876771e9cf5ccbb5d1c Mon Sep 17 00:00:00 2001
From: tijmen
Date: Tue, 7 Apr 2026 09:23:05 +0200
Subject: [PATCH 15/15] scope by error notice
---
test/integration/compression.spec.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/integration/compression.spec.ts b/test/integration/compression.spec.ts
index 140d7d09..711ef288 100644
--- a/test/integration/compression.spec.ts
+++ b/test/integration/compression.spec.ts
@@ -220,7 +220,7 @@ test.describe('compression', () => {
// Since 4.2 it is no longer a link but a button.
const isButton = WPVersion >= 4.2;
if (isButton) {
- await page.getByRole('button', { name: 'Dismiss this notice.' }).click();
+ await page.locator('.error.notice').getByRole('button', { name: 'Dismiss this notice.' }).click();
} else {
await page.getByRole('link', { name: 'Dismiss' }).click();
}