From b9e2647a5c5341c8a9dd8255a3858e06e169015a Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 13:41:44 +0200 Subject: [PATCH 01/16] turn off NonceVerification --- phpcs.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/phpcs.xml b/phpcs.xml index 7a317ae..6725dab 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -10,9 +10,6 @@ - - - From 36cf591807de3acc503294c935ec2195028b7874 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 14:17:46 +0200 Subject: [PATCH 02/16] verify nonce when ids are in params --- src/class-tiny-plugin.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/class-tiny-plugin.php b/src/class-tiny-plugin.php index b68a10b..bc22fc8 100644 --- a/src/class-tiny-plugin.php +++ b/src/class-tiny-plugin.php @@ -703,6 +703,7 @@ public function media_library_bulk_action() { $location = 'upload.php?mode=list&ids=' . $ids; $location = add_query_arg( 'action', $action, $location ); + $location = add_query_arg( '_tiny_nonce', wp_create_nonce( 'tiny-bulk-ids' ), $location ); if ( ! empty( $_REQUEST['paged'] ) ) { $location = add_query_arg( 'paged', absint( $_REQUEST['paged'] ), $location ); @@ -758,6 +759,23 @@ public function show_media_info() { } private function render_compress_details( $tiny_image ) { + $images_to_compress = array(); + + if ( ! empty( $_REQUEST['ids'] ) ) { + if ( + ! isset( $_REQUEST['_tiny_nonce'] ) || + ! wp_verify_nonce( + sanitize_key( wp_unslash( $_REQUEST['_tiny_nonce'] ) ), + 'tiny-bulk-ids' + ) + ) { + return; + } + + $request_ids = sanitize_text_field( wp_unslash( $_REQUEST['ids'] ) ); + $images_to_compress = array_map( 'intval', explode( '-', $request_ids ) ); + } + $in_progress = $tiny_image->filter_image_sizes( 'in_progress' ); if ( count( $in_progress ) > 0 ) { include __DIR__ . '/views/compress-details-processing.php'; From d165b4c90d1947994dec657329553c0ada6c77bb Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 14:22:32 +0200 Subject: [PATCH 03/16] remove variable instance for parameter --- src/views/compress-details.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/views/compress-details.php b/src/views/compress-details.php index b3a0f58..7c3152f 100644 --- a/src/views/compress-details.php +++ b/src/views/compress-details.php @@ -2,8 +2,9 @@ /** * Compression details on media overview page. * - * @var Tiny_Plugin $this The plugin instance. - * @var Tiny_Image $tiny_image The image being compressed. + * @var Tiny_Plugin $this The plugin instance. + * @var Tiny_Image $tiny_image The image being compressed. + * @var int[] $images_to_compress The IDs that are being compressed */ $available_sizes = array_keys( $this->settings->get_sizes() ); @@ -22,11 +23,6 @@ $size_exists = array_fill_keys( $available_sizes, true ); ksort( $size_exists ); -$images_to_compress = array(); -if ( ! empty( $_REQUEST['ids'] ) ) { - $request_ids = sanitize_text_field( wp_unslash( $_REQUEST['ids'] ) ); - $images_to_compress = array_map( 'intval', explode( '-', $request_ids ) ); -} ?>
From ba5aec764d5bb229c65ab78c716af081ec547038 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 14:29:31 +0200 Subject: [PATCH 04/16] use core check_ajax_referer instead of inherited --- 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 d946d81..6ca2aac 100644 --- a/src/class-tiny-notices.php +++ b/src/class-tiny-notices.php @@ -148,7 +148,7 @@ public function remove( $name ) { } public function dismiss() { - if ( empty( $_POST['name'] ) || ! $this->check_ajax_referer() ) { + if ( ! check_ajax_referer( 'tiny-compress', '_nonce', false ) || empty( $_POST['name'] ) ) { echo json_encode( false ); exit(); } From 71866ff67169ff583e8fce95632a193a3f453c57 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 14:41:10 +0200 Subject: [PATCH 05/16] use filter_has_var to not access superglobal $_GET. --- src/class-tiny-helpers.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class-tiny-helpers.php b/src/class-tiny-helpers.php index 51c678c..7a54b25 100644 --- a/src/class-tiny-helpers.php +++ b/src/class-tiny-helpers.php @@ -133,7 +133,7 @@ public static function is_pagebuilder_request() { ); foreach ( $pagebuilder_keys as $key ) { - if ( isset( $_GET[ $key ] ) ) { + if ( filter_has_var(INPUT_GET, $key ) ) { return true; } } From 5680a87d0f08b3a6e0f2ceab822e511e91f91b31 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 14:53:21 +0200 Subject: [PATCH 06/16] ignore nonce verification due to limitation of phpcs --- src/class-tiny-helpers.php | 2 +- src/class-tiny-plugin.php | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/class-tiny-helpers.php b/src/class-tiny-helpers.php index 7a54b25..889821f 100644 --- a/src/class-tiny-helpers.php +++ b/src/class-tiny-helpers.php @@ -133,7 +133,7 @@ public static function is_pagebuilder_request() { ); foreach ( $pagebuilder_keys as $key ) { - if ( filter_has_var(INPUT_GET, $key ) ) { + if ( filter_has_var( INPUT_GET, $key ) ) { return true; } } diff --git a/src/class-tiny-plugin.php b/src/class-tiny-plugin.php index bc22fc8..723a36a 100644 --- a/src/class-tiny-plugin.php +++ b/src/class-tiny-plugin.php @@ -517,7 +517,7 @@ public function compress_on_upload() { * or success array ['data' => [$id, $metadata]] */ private function validate_ajax_attachment_request() { - if ( ! $this->check_ajax_referer() ) { + if ( ! check_ajax_referer( 'tiny-compress', '_nonce', false ) ) { exit(); } if ( ! current_user_can( 'upload_files' ) ) { @@ -614,11 +614,14 @@ public function compress_image_for_bulk() { ); wp_update_attachment_metadata( $id, $tiny_image->get_wp_metadata() ); + // Nonce verified in validate_ajax_attachment_request(). + // phpcs:disable WordPress.Security.NonceVerification.Missing $current_library_size = isset( $_POST['current_size'] ) ? intval( wp_unslash( $_POST['current_size'] ) ) : 0; - $size_after = $image_statistics['compressed_total_size']; - $new_library_size = $current_library_size + $size_after - $size_before; + // phpcs:enable WordPress.Security.NonceVerification.Missing + $size_after = $image_statistics['compressed_total_size']; + $new_library_size = $current_library_size + $size_after - $size_before; $result['message'] = $tiny_image->get_latest_error(); $result['image_sizes_compressed'] = $image_statistics['image_sizes_compressed']; From 747762bbb0b18d532c72ceee16053c67b7ce6121 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 15:24:21 +0200 Subject: [PATCH 07/16] add nonce check and modernize js --- src/class-tiny-settings.php | 2 +- src/js/admin.js | 31 ++++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/class-tiny-settings.php b/src/class-tiny-settings.php index 58d6049..9f96347 100644 --- a/src/class-tiny-settings.php +++ b/src/class-tiny-settings.php @@ -160,7 +160,7 @@ public function add_options_to_page() { } public function image_sizes_notice() { - if ( current_user_can( 'manage_options' ) ) { + if ( current_user_can( 'manage_options' ) && check_ajax_referer( 'tiny-compress' ) ) { $selected_sizes = isset( $_GET['image_sizes_selected'] ) ? intval( $_GET['image_sizes_selected'] ) : 0; $this->render_size_checkboxes_description( diff --git a/src/js/admin.js b/src/js/admin.js index 0ead0f4..a7ccd82 100644 --- a/src/js/admin.js +++ b/src/js/admin.js @@ -329,29 +329,30 @@ }); } - eventOn('click', 'input[name*=tinypng_sizes], #tinypng_resize_original_enabled', function() { - /* Unfortunately, we need some additional information to display - the correct notice. */ - var totalSelectedSizes = jQuery('input[name*=tinypng_sizes]:checked').length; - var compressWr2x = propOf('#tinypng_sizes_wr2x', 'checked'); - if (compressWr2x) { - totalSelectedSizes--; - } + async function refreshSizeDescriptionNotice() { + const totalSelectedSizes = document.querySelectorAll('input[name*=tinypng_sizes]:checked').length; + const compressWr2x = document.querySelector('#tinypng_sizes_wr2x')?.checked ?? false; + const selectedCount = compressWr2x ? totalSelectedSizes - 1 : totalSelectedSizes; - var image_count_url = ajaxurl + (ajaxurl.indexOf( '?' ) > 0 ? '&' : '?') + 'action=tiny_image_sizes_notice&image_sizes_selected=' + totalSelectedSizes; - if (propOf('#tinypng_resize_original_enabled', 'checked') && propOf('#tinypng_sizes_0', 'checked')) { + const separator = ajaxurl.includes('?') ? '&' : '?'; + let image_count_url = `${ajaxurl}${separator}action=tiny_image_sizes_notice&image_sizes_selected=${selectedCount}&_ajax_nonce=${tinyCompress.nonce}`; + + const resizeOriginalChecked = document.querySelector('#tinypng_resize_original_enabled')?.checked; + const compressOriginalChecked = document.querySelector('#tinypng_sizes_0')?.checked; + if (resizeOriginalChecked && compressOriginalChecked) { image_count_url += '&resize_original=true'; } if (compressWr2x) { image_count_url += '&compress_wr2x=true'; } - jQuery('#tiny-image-sizes-notice').load(image_count_url); - }); - eventOn('click', '#tinypng_auto_compress_enabled', function() { - updateSettings(); - }); + const sizeDescriptionHtml = await fetch(image_count_url).then(r => r.text()); + document.querySelector('#tiny-image-sizes-notice').innerHTML = sizeDescriptionHtml; + } + eventOn('click', 'input[name*=tinypng_sizes], #tinypng_resize_original_enabled', refreshSizeDescriptionNotice); + + eventOn('click', '#tinypng_auto_compress_enabled', updateSettings); jQuery('#tinypng_sizes_0, #tinypng_resize_original_enabled').click(updateSettings); updateSettings(); } From 58c2fd63637e1aa2b2b68dcec56cb1a7f5450290 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 15:26:04 +0200 Subject: [PATCH 08/16] add core nonce check --- src/class-tiny-settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class-tiny-settings.php b/src/class-tiny-settings.php index 9f96347..b4bfdf9 100644 --- a/src/class-tiny-settings.php +++ b/src/class-tiny-settings.php @@ -827,7 +827,7 @@ public function render_pending_status() { } public function create_api_key() { - if ( ! $this->check_ajax_referer() ) { + if ( ! check_ajax_referer( 'tiny-compress', '_nonce' ) ) { exit; } $compressor = $this->get_compressor(); From 9dd369a44358328e32a9967d6dae227133f2a4e8 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 15:27:16 +0200 Subject: [PATCH 09/16] use core nonce check --- src/class-tiny-settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class-tiny-settings.php b/src/class-tiny-settings.php index b4bfdf9..f28058a 100644 --- a/src/class-tiny-settings.php +++ b/src/class-tiny-settings.php @@ -905,7 +905,7 @@ public function create_api_key() { } public function update_api_key() { - if ( ! $this->check_ajax_referer() ) { + if ( ! check_ajax_referer( 'tiny-compress', '_nonce' ) ) { exit; } From f8d258088323cf4f9359299065d2bdf75817d1bc Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 15:31:15 +0200 Subject: [PATCH 10/16] remove unused ajax_referer on base --- src/class-tiny-wp-base.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/class-tiny-wp-base.php b/src/class-tiny-wp-base.php index fd08fb3..0e69bbd 100644 --- a/src/class-tiny-wp-base.php +++ b/src/class-tiny-wp-base.php @@ -87,10 +87,6 @@ protected function get_user_id() { return get_current_user_id(); } - protected function check_ajax_referer() { - return check_ajax_referer( 'tiny-compress', '_nonce', false ); - } - public function init() { } From ffb8909aafa9538f41f1ec5e870b24762976f60d Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 15:31:36 +0200 Subject: [PATCH 11/16] early return when possible --- src/class-tiny-plugin.php | 7 +++---- src/class-tiny-settings.php | 9 +++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/class-tiny-plugin.php b/src/class-tiny-plugin.php index 723a36a..0f219a9 100644 --- a/src/class-tiny-plugin.php +++ b/src/class-tiny-plugin.php @@ -517,9 +517,8 @@ public function compress_on_upload() { * or success array ['data' => [$id, $metadata]] */ private function validate_ajax_attachment_request() { - if ( ! check_ajax_referer( 'tiny-compress', '_nonce', false ) ) { - exit(); - } + check_ajax_referer( 'tiny-compress', '_nonce' ); + if ( ! current_user_can( 'upload_files' ) ) { return array( 'error' => esc_html__( @@ -658,7 +657,7 @@ public function compress_image_for_bulk() { } public function ajax_optimization_statistics() { - if ( $this->check_ajax_referer() && current_user_can( 'upload_files' ) ) { + if ( check_ajax_referer( 'tiny-compress', '_nonce', false ) && current_user_can( 'upload_files' ) ) { $stats = Tiny_Bulk_Optimization::get_optimization_statistics( $this->settings ); echo json_encode( $stats ); } diff --git a/src/class-tiny-settings.php b/src/class-tiny-settings.php index f28058a..a4256eb 100644 --- a/src/class-tiny-settings.php +++ b/src/class-tiny-settings.php @@ -827,9 +827,8 @@ public function render_pending_status() { } public function create_api_key() { - if ( ! check_ajax_referer( 'tiny-compress', '_nonce' ) ) { - exit; - } + check_ajax_referer( 'tiny-compress', '_nonce' ); + $compressor = $this->get_compressor(); if ( ! current_user_can( 'manage_options' ) ) { $status = (object) array( @@ -905,9 +904,7 @@ public function create_api_key() { } public function update_api_key() { - if ( ! check_ajax_referer( 'tiny-compress', '_nonce' ) ) { - exit; - } + check_ajax_referer( 'tiny-compress', '_nonce' ); $key = null; if ( ! current_user_can( 'manage_options' ) ) { From 948381ea3be048c55461c84488bbb3476b662eb7 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 15:41:59 +0200 Subject: [PATCH 12/16] return early on image_sizes_notice --- src/class-tiny-settings.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/class-tiny-settings.php b/src/class-tiny-settings.php index a4256eb..415a24a 100644 --- a/src/class-tiny-settings.php +++ b/src/class-tiny-settings.php @@ -160,7 +160,9 @@ public function add_options_to_page() { } public function image_sizes_notice() { - if ( current_user_can( 'manage_options' ) && check_ajax_referer( 'tiny-compress' ) ) { + check_ajax_referer( 'tiny-compress' ); + + if ( current_user_can( 'manage_options' ) ) { $selected_sizes = isset( $_GET['image_sizes_selected'] ) ? intval( $_GET['image_sizes_selected'] ) : 0; $this->render_size_checkboxes_description( From a67dfa7db251a94bee72290460b849083ff33770 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 15:44:04 +0200 Subject: [PATCH 13/16] handle error --- src/js/admin.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/js/admin.js b/src/js/admin.js index a7ccd82..a27c475 100644 --- a/src/js/admin.js +++ b/src/js/admin.js @@ -345,9 +345,13 @@ if (compressWr2x) { image_count_url += '&compress_wr2x=true'; } - - const sizeDescriptionHtml = await fetch(image_count_url).then(r => r.text()); - document.querySelector('#tiny-image-sizes-notice').innerHTML = sizeDescriptionHtml; + try { + const sizeDescriptionHtml = await fetch(image_count_url).then(r => r.text()); + document.querySelector('#tiny-image-sizes-notice').innerHTML = sizeDescriptionHtml; + } catch (err) { + document.querySelector('#tiny-image-sizes-notice').innerHTML = ''; + console.error(err); + } } eventOn('click', 'input[name*=tinypng_sizes], #tinypng_resize_original_enabled', refreshSizeDescriptionNotice); From 3ad482a37d1f0665f60b65dcd7183d278c53211c Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 15:46:37 +0200 Subject: [PATCH 14/16] camelcase --- src/js/admin.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/js/admin.js b/src/js/admin.js index a27c475..03312c0 100644 --- a/src/js/admin.js +++ b/src/js/admin.js @@ -301,7 +301,6 @@ eventOn('click', 'button.tiny-mark-as-compressed', onClickButtonMarkAsCompressed); setPropOf('button.tiny-compress', 'disabled', null); - compressImageSelection(); watchCompressingImages(); @@ -335,18 +334,18 @@ const selectedCount = compressWr2x ? totalSelectedSizes - 1 : totalSelectedSizes; const separator = ajaxurl.includes('?') ? '&' : '?'; - let image_count_url = `${ajaxurl}${separator}action=tiny_image_sizes_notice&image_sizes_selected=${selectedCount}&_ajax_nonce=${tinyCompress.nonce}`; + let imageCountUrl = `${ajaxurl}${separator}action=tiny_image_sizes_notice&image_sizes_selected=${selectedCount}&_ajax_nonce=${tinyCompress.nonce}`; const resizeOriginalChecked = document.querySelector('#tinypng_resize_original_enabled')?.checked; const compressOriginalChecked = document.querySelector('#tinypng_sizes_0')?.checked; if (resizeOriginalChecked && compressOriginalChecked) { - image_count_url += '&resize_original=true'; + imageCountUrl += '&resize_original=true'; } if (compressWr2x) { - image_count_url += '&compress_wr2x=true'; + imageCountUrl += '&compress_wr2x=true'; } try { - const sizeDescriptionHtml = await fetch(image_count_url).then(r => r.text()); + const sizeDescriptionHtml = await fetch(imageCountUrl).then(r => r.text()); document.querySelector('#tiny-image-sizes-notice').innerHTML = sizeDescriptionHtml; } catch (err) { document.querySelector('#tiny-image-sizes-notice').innerHTML = ''; @@ -355,7 +354,6 @@ } eventOn('click', 'input[name*=tinypng_sizes], #tinypng_resize_original_enabled', refreshSizeDescriptionNotice); - eventOn('click', '#tinypng_auto_compress_enabled', updateSettings); jQuery('#tinypng_sizes_0, #tinypng_resize_original_enabled').click(updateSettings); updateSettings(); From 7e81fbc71fc20f0e92a2340e2c62defdabd75901 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 16:17:13 +0200 Subject: [PATCH 15/16] move pagebuilder check to picture and allow test to override behaviour --- src/class-tiny-helpers.php | 30 --------------------- src/class-tiny-picture.php | 51 ++++++++++++++++++++++++++++++++++- test/unit/TinyHelpersTest.php | 20 -------------- test/unit/TinyPictureTest.php | 15 ++++++++++- 4 files changed, 64 insertions(+), 52 deletions(-) diff --git a/src/class-tiny-helpers.php b/src/class-tiny-helpers.php index 889821f..dc4f41f 100644 --- a/src/class-tiny-helpers.php +++ b/src/class-tiny-helpers.php @@ -111,36 +111,6 @@ public static function get_mimetype( $input ) { } - /** - * Checks wether a user is viewing from a page builder - * - * @since 3.6.5 - */ - public static function is_pagebuilder_request() { - $pagebuilder_keys = array( - 'fl_builder', // Beaver Builder - 'et_fb', // Divi Builder - 'bricks', // Bricks Builder - 'breakdance', // Breakdance Builder - 'breakdance_browser', // Breakdance Builder - 'ct_builder', // Oxygen Builder - 'fb-edit', // Avada Live Builder - 'builder', // Avada Live Builder - 'spio_no_cdn', // Site Origin - 'tatsu', // Tatsu Builder - 'tve', // Thrive Architect - 'tcbf', // Thrive Architect - ); - - foreach ( $pagebuilder_keys as $key ) { - if ( filter_has_var( INPUT_GET, $key ) ) { - return true; - } - } - - return false; - } - /** * Gets or initializes the WordPress filesystem instance. * diff --git a/src/class-tiny-picture.php b/src/class-tiny-picture.php index ae3f5e4..f32e3d2 100644 --- a/src/class-tiny-picture.php +++ b/src/class-tiny-picture.php @@ -65,13 +65,62 @@ public function __construct( $settings, $base_dir = ABSPATH, $domains = array() return; } - if ( Tiny_Helpers::is_pagebuilder_request() ) { + if ( static::is_pagebuilder_request() ) { return; } add_action( 'template_redirect', array( $this, 'on_template_redirect' ) ); } + /** + * Checks whether the current request originates from a page builder. + * + * Detects known page builder query parameters to prevent picture-element + * injection from interfering with builder previews. + * + * @since 3.6.5 + * + * @return bool True if a page builder query parameter is present. + */ + protected static function is_pagebuilder_request() { + $pagebuilder_keys = array( + 'fl_builder', // Beaver Builder + 'et_fb', // Divi Builder + 'bricks', // Bricks Builder + 'breakdance', // Breakdance Builder + 'breakdance_browser', // Breakdance Builder + 'ct_builder', // Oxygen Builder + 'fb-edit', // Avada Live Builder + 'builder', // Avada Live Builder + 'spio_no_cdn', // Site Origin + 'tatsu', // Tatsu Builder + 'tve', // Thrive Architect + 'tcbf', // Thrive Architect + ); + + foreach ( $pagebuilder_keys as $key ) { + if ( static::has_get_var( $key ) ) { + return true; + } + } + + return false; + } + + /** + * Checks whether a GET variable exists in the original request. + * + * Wraps filter_has_var() to allow overriding in tests via late static binding. + * + * @since 3.6.5 + * + * @param string $key The query string key to check. + * @return bool True if the key exists in the original GET request. + */ + protected static function has_get_var( $key ) { + return filter_has_var( INPUT_GET, $key ); + } + public function on_template_redirect() { $conversion_enabled = $this->settings->get_conversion_enabled(); if ( apply_filters( 'tiny_replace_with_picture', $conversion_enabled ) ) { diff --git a/test/unit/TinyHelpersTest.php b/test/unit/TinyHelpersTest.php index 349a1af..98abdff 100644 --- a/test/unit/TinyHelpersTest.php +++ b/test/unit/TinyHelpersTest.php @@ -111,26 +111,6 @@ public function test_uppercase_extension_and_mimetype_case_insensitive() $this->assertEquals($expected, Tiny_Helpers::replace_file_extension('image/avif', $input)); } -public function test_is_pagebuilder_request_returns_false_when_no_pagebuilder_keys() -{ - $_GET = array(); - $this->assertFalse(Tiny_Helpers::is_pagebuilder_request()); -} - -public function test_is_pagebuilder_request_returns_true_for_beaver_builder() -{ - $_GET = array('fl_builder' => '1'); - $this->assertTrue(Tiny_Helpers::is_pagebuilder_request()); - $_GET = array(); -} - -public function test_is_pagebuilder_request_returns_false_for_non_pagebuilder_keys() -{ - $_GET = array('page' => 'settings', 'post_id' => '123'); - $this->assertFalse(Tiny_Helpers::is_pagebuilder_request()); - $_GET = array(); -} - public function test_str_starts_with_returns_true_when_haystack_starts_with_needle() { $this->assertTrue(Tiny_Helpers::str_starts_with('hello world', 'hello')); diff --git a/test/unit/TinyPictureTest.php b/test/unit/TinyPictureTest.php index 95298d2..7c24abc 100644 --- a/test/unit/TinyPictureTest.php +++ b/test/unit/TinyPictureTest.php @@ -2,6 +2,19 @@ require_once dirname(__FILE__) . '/TinyTestCase.php'; +class Tiny_Picture_Overrides extends Tiny_Picture { + /** + * filter_has_var looks for immutable $_GET + * so unit tests cannot set the $_GET. + * + * isset( $_GET ) is similar to filter_has_var + * but allows us to mutate. + */ + protected static function has_get_var( $key ) { + return isset( $_GET[ $key ] ); + } +} + class Tiny_Picture_Test extends Tiny_TestCase { @@ -337,7 +350,7 @@ public function test_does_not_register_hooks_when_pagebuilder_request() }); $settings = new Tiny_Settings(); - $tiny_picture = new Tiny_Picture($settings, $this->vfs->url(), array('https://www.tinifytest.com')); + $tiny_picture = new Tiny_Picture_Overrides($settings, $this->vfs->url(), array('https://www.tinifytest.com')); $template_redirect_registered = false; foreach ($this->wp->getCalls('add_action') as $call) { From fd02a6d83560c2368306a83269f807a65cb5a764 Mon Sep 17 00:00:00 2001 From: tijmen Date: Thu, 4 Jun 2026 16:26:10 +0200 Subject: [PATCH 16/16] format --- src/class-tiny-plugin.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/class-tiny-plugin.php b/src/class-tiny-plugin.php index 0f219a9..e9e23ec 100644 --- a/src/class-tiny-plugin.php +++ b/src/class-tiny-plugin.php @@ -657,7 +657,8 @@ public function compress_image_for_bulk() { } public function ajax_optimization_statistics() { - if ( check_ajax_referer( 'tiny-compress', '_nonce', false ) && current_user_can( 'upload_files' ) ) { + if ( check_ajax_referer( 'tiny-compress', '_nonce', false ) && + current_user_can( 'upload_files' ) ) { $stats = Tiny_Bulk_Optimization::get_optimization_statistics( $this->settings ); echo json_encode( $stats ); }