Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4680f5c
release: 3.6.10
Sreini Feb 16, 2026
e154eb9
Merge branch 'master' of https://github.com/tinify/wordpress-plugin
tijmenbruggeman Feb 16, 2026
f53f00b
Merge branch 'tinify:master' into master
tijmenbruggeman Feb 17, 2026
ba97e04
Merge branch 'master' of https://github.com/tinify/wordpress-plugin
tijmenbruggeman Mar 6, 2026
3933d3c
Merge branch 'master' of https://github.com/tinify/wordpress-plugin
tijmenbruggeman Mar 17, 2026
c91a855
Merge branch 'master' of https://github.com/tinify/wordpress-plugin
tijmenbruggeman Mar 18, 2026
0c82165
allow delivery to be undefined, defaults to picture
tijmenbruggeman Mar 26, 2026
c677d0f
add feedback notice
tijmenbruggeman Mar 30, 2026
709257b
show feedback notice on more than 5 compressions
tijmenbruggeman Mar 30, 2026
d2b97fe
set visisiblity
tijmenbruggeman Mar 30, 2026
6b1149a
add constructor in test
tijmenbruggeman Mar 30, 2026
3126445
add assert to check if hook is not called
tijmenbruggeman Mar 30, 2026
8659390
assert when dismissed, do not show notice
tijmenbruggeman Mar 30, 2026
82d66a6
Merge branch 'master' of https://github.com/tinify/wordpress-plugin i…
tijmenbruggeman Mar 31, 2026
e78ec22
replace func with plain require
tijmenbruggeman Mar 31, 2026
853af5a
set hook func to public
tijmenbruggeman Mar 31, 2026
eef7b4a
Add review text on bulk page
tijmenbruggeman Mar 31, 2026
df0bfbd
break line
tijmenbruggeman Mar 31, 2026
b703d70
format
tijmenbruggeman Apr 1, 2026
584d54e
missing preslash
tijmenbruggeman Apr 1, 2026
ea8ccd4
scope by error notice
tijmenbruggeman Apr 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/class-tiny-notices.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 10;

/**
* 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',
Expand Down Expand Up @@ -102,6 +126,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 ) {
Expand Down Expand Up @@ -303,4 +328,21 @@ function () use ( $notice ) {
}
);
}

/**
* Checks if the feedback notice should be displayed and hooks it to admin_notices.
*
* @return void
*/
private function feedback_notice() {
if ( ! isset( $this->dismissals['feedback'] ) &&
$this->settings->get_compression_count() > $this->compressions_for_feedback
) {
add_action( 'admin_notices', array( $this, 'feedback_notice_show' ) );
}
}

public function feedback_notice_show() {
include __DIR__ . '/views/notice-feedback.php';
}
}
12 changes: 0 additions & 12 deletions src/class-tiny-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
'<a href="%s" target="_blank">%s</a>',
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();
Expand Down
2 changes: 1 addition & 1 deletion src/class-tiny-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}

Expand Down
2 changes: 2 additions & 0 deletions src/views/bulk-optimization.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
} 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 '<br />';
require __DIR__ . '/request-review.php';
} elseif ( $stats['optimized-image-sizes'] > 0 ) {
if ( $percentage_of_files > 75 ) {
/* translators: %s: friendly user name */
Expand Down
2 changes: 1 addition & 1 deletion src/views/dashboard-widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
?>
</p>
</div>
Expand Down
16 changes: 16 additions & 0 deletions src/views/notice-feedback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
$review_url = 'https://wordpress.org/support/plugin/tiny-compress-images/reviews/#new-post';
$review_block = sprintf(
'<a href="%s" target="_blank">%s</span></a>',
esc_url( $review_url ),
esc_html__( 'Leave a review', 'tiny-compress-images' )
);
?>

<div class="notice notice-success is-dismissible tiny-notice" data-name="feedback">
<p>
<strong><?php _e( 'Enjoying TinyPNG?', 'tiny-compress-images' ); ?></strong>
<span><?php _e( 'Take 30 seconds to let us know what you think!', 'tiny-compress-images' ); ?></span>
<?php echo $review_block; ?>
<a href="#" class="tiny-dismiss"></a></p>
</div>
6 changes: 6 additions & 0 deletions src/views/request-review.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<span>
<?php esc_html_e( 'Enjoying TinyPNG?', 'tiny-compress-images' ); ?>
</span>
<a href="https://wordpress.org/support/plugin/tiny-compress-images/reviews/#new-post" target="_blank">
<?php esc_html_e( 'Leave a review', 'tiny-compress-images' ); ?>
</a>
4 changes: 2 additions & 2 deletions src/views/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
</table>

<?php require plugin_dir_path( __FILE__ ) . 'settings-diagnostics.php'; ?>

<p><?php echo Tiny_Plugin::request_review(); ?></p>
<?php require __DIR__ . '/request-review.php'; ?>

<p class="submit">
<input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_html_e( 'Save Changes', 'tiny-compress-images' ); ?>">
</p>
Expand Down
34 changes: 29 additions & 5 deletions test/helpers/wordpress.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/integration/compression.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,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) {
Expand Down
6 changes: 4 additions & 2 deletions test/unit/TinySettingsAjaxTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

class Tiny_Settings_Ajax_Test extends Tiny_TestCase {
protected $notices;
private $settings;

public function set_up() {
parent::set_up();
Expand All @@ -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' ));
Expand All @@ -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' ));
Expand Down
86 changes: 86 additions & 0 deletions test/unit/Tiny_Notices_Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

require_once dirname(__FILE__) . '/TinyTestCase.php';

class Tiny_Notices_Test extends Tiny_TestCase
{
protected $subject;
protected $settings;

public function set_up()
{
parent::set_up();

$this->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' ) );
}

}
Loading