Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions src/admin/class-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ public function register_settings() {
'optimize_all_media' => [
'type' => 'integer',
],
'show_optimization_toggle' => [
'type' => 'integer',
],
'show_optimization_toggle_frontend' => [
'type' => 'integer',
],
'persist_optimization_toggle' => [
'type' => 'integer',
],
'disable_wp_scaling' => [
'type' => 'integer',
],
Expand Down Expand Up @@ -307,6 +316,21 @@ public function sanitize_options( $options ) {
$sanitized['optimize_all_media'] = $options['optimize_all_media'] ? 1 : 0;
}

// Sanitize show_optimization_toggle
if ( isset( $options['show_optimization_toggle'] ) ) {
$sanitized['show_optimization_toggle'] = $options['show_optimization_toggle'] ? 1 : 0;
}

// Sanitize show_optimization_toggle_frontend
if ( isset( $options['show_optimization_toggle_frontend'] ) ) {
$sanitized['show_optimization_toggle_frontend'] = $options['show_optimization_toggle_frontend'] ? 1 : 0;
}

// Sanitize persist_optimization_toggle
if ( isset( $options['persist_optimization_toggle'] ) ) {
$sanitized['persist_optimization_toggle'] = $options['persist_optimization_toggle'] ? 1 : 0;
}

// Sanitize disable_wp_scaling
if ( isset( $options['disable_wp_scaling'] ) ) {
$sanitized['disable_wp_scaling'] = $options['disable_wp_scaling'] ? 1 : 0;
Expand Down
4 changes: 4 additions & 0 deletions src/admin/class-script-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ public static function enqueue_cimo_assets() {
'canManageOptions' => current_user_can( 'manage_options' ),
'optimizeAllMedia' => isset( $settings['optimize_all_media'] ) ? (int) $settings['optimize_all_media'] : 0,
'isPremium' => CIMO_BUILD === 'premium',
'optimizeAllMedia' => isset( $settings['optimize_all_media'] ) ? (int) $settings['optimize_all_media'] : 0,
'showOptimizationToggle' => isset( $settings['show_optimization_toggle'] ) ? (int) $settings['show_optimization_toggle'] : 0,
'showOptimizationToggleFrontend' => isset( $settings['show_optimization_toggle_frontend'] ) ? (int) $settings['show_optimization_toggle_frontend'] : 0,
'persistOptimizationToggle' => isset( $settings['persist_optimization_toggle'] ) ? (int) $settings['persist_optimization_toggle'] : 0,
'webpQuality' => ! empty( $settings['webp_quality'] ) ? (int) $settings['webp_quality'] : 80,
'maxImageDimension' => ! empty( $settings['max_image_dimension'] ) ? (int) $settings['max_image_dimension'] : 0,
'videoOptimizationEnabled' => isset( $settings['video_optimization_enabled'] ) ? (int) $settings['video_optimization_enabled'] : 1,
Expand Down
5 changes: 5 additions & 0 deletions src/admin/css/admin-page.css
Original file line number Diff line number Diff line change
Expand Up @@ -926,3 +926,8 @@
.cimo-bulk-optimize-button.is-optimizing {
animation: cimo-strobe 1.5s linear infinite;
}

.cimo-divider {
border-top: 1px solid rgba(0, 0, 0, 0.1);
margin: 0 0 24px 0;
}
76 changes: 76 additions & 0 deletions src/admin/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,80 @@

#cimo-data-meta-box.postbox .inside {
padding-top: 12px;
}

.cimo-optimization-toggle-container {
position: fixed;
bottom: 16px;
right: 16px;
z-index: 99999;
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
border-radius: 999px;

background-color: rgba(0, 0, 0, 0.65);
backdrop-filter: blur(6px);

color: #fff;
font-size: 12px;
font-family: system-ui, -apple-system, sans-serif;

box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.cimo-optimization-toggle-label {
white-space: nowrap;
opacity: 0.9;
}

.cimo-optimization-toggle-switch {
position: relative;
display: inline-block;
width: 34px;
height: 18px;
}

/* Hide default checkbox */
.cimo-optimization-toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}

/* Slider */
.cimo-optimization-toggle-slider {
position: absolute;
inset: 0;
background-color: #888;
border-radius: 34px;
transition: background-color 0.2s ease;
cursor: pointer;
}

.cimo-optimization-toggle-slider::before {
content: "";
position: absolute;
height: 14px;
width: 14px;
left: 2px;
bottom: 2px;

background-color: #fff;
border-radius: 50%;

transition: transform 0.2s ease;
}

.cimo-optimization-toggle-switch input:checked + .cimo-optimization-toggle-slider {
background-color: #0EBA35;
}

.cimo-optimization-toggle-switch input:checked + .cimo-optimization-toggle-slider::before {
transform: translateX(16px);
}

.cimo-optimization-toggle-container:hover {
background: rgba(0, 0, 0, 0.7);
}
4 changes: 4 additions & 0 deletions src/admin/js/media-manager/drop-zone.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ function addDropZoneListenerToMediaManager( targetDocument ) {
}

const customDropHandler = async event => {
if ( window.cimoSettings?.disableOptimization ) {
return
}
Comment on lines +42 to +44
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Find every read/write of disableOptimization:"
rg -n -C2 --type=js --type=php '\bdisableOptimization\b'

echo
echo "2) Inspect cimoSettings localization payload(s):"
rg -n -C6 --type=php "wp_localize_script\\(|['\"]cimoSettings['\"]"

echo
echo "Expected:"
echo "- At least one initialization/assignment path for window.cimoSettings.disableOptimization"
echo "  that runs before drop/select listeners are attached."

Repository: gambitph/Cimo

Length of output: 2782


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Searching for dynamic assignments to cimoSettings or disableOptimization ==="
rg -n 'cimoSettings\s*=|cimoSettings\[|window\.cimoSettings' --type=js --type=php

echo ""
echo "=== Checking admin settings page for disable optimization toggle ==="
rg -n -i 'disable.*optim|optim.*disable|toggle.*disable' --type=js --type=php

echo ""
echo "=== Searching for any REST endpoint that might set this state ==="
rg -n -i 'disableOptimization|disable_optimization' --type=php

Repository: gambitph/Cimo

Length of output: 3007


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Search for floating toggle implementation ==="
rg -n -i 'floating.*toggle|toggle.*optim|showOptimizationToggle' --type=js -A5 -B5

echo ""
echo "=== Search for files in admin/js that might contain toggle logic ==="
fd -e js --path 'admin/js' | head -20

echo ""
echo "=== Check if there's a separate toggle component or widget ==="
rg -n 'class.*Toggle|function.*[Tt]oggle|const.*Toggle' --type=js --path 'admin' | head -30

Repository: gambitph/Cimo

Length of output: 8480


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Search for toggle widget or component ==="
fd -e js -e jsx --path 'admin' | xargs rg -l -i 'toggle.*widget|toggle.*component|floating.*toggle' | head -10

echo ""
echo "=== List all files in admin/js to understand structure ==="
find src/admin/js -type f -name '*.js' -o -name '*.jsx' | sort

echo ""
echo "=== Search for any localStorage or sessionStorage writes related to optimize ==="
rg -n 'localStorage|sessionStorage' --type=js --path 'admin' -B2 -A2

echo ""
echo "=== Check for window mutation patterns on cimoSettings ==="
rg -n 'window\.' --type=js --path 'admin/js' | grep -i 'optim\|disable' | head -20

Repository: gambitph/Cimo

Length of output: 389


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== List all files in admin/js ==="
find src/admin/js -type f \( -name '*.js' -o -name '*.jsx' \) | sort

echo ""
echo "=== Search for localStorage or sessionStorage ==="
rg -n 'localStorage|sessionStorage' --type=js | grep -v node_modules

echo ""
echo "=== Search for any toggle or optimization-related JS files ==="
find src -type f \( -name '*toggle*' -o -name '*optimize*' \) | grep -E '\.(js|jsx)$'

echo ""
echo "=== Check if toggle state is managed inline in drop-zone or select-files ==="
cat src/admin/js/media-manager/drop-zone.js

Repository: gambitph/Cimo

Length of output: 501


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Read full drop-zone.js to understand context ==="
wc -l src/admin/js/media-manager/drop-zone.js

echo ""
echo "=== Read the file ==="
cat -n src/admin/js/media-manager/drop-zone.js

echo ""
echo "=== Read full select-files.js ==="
cat -n src/admin/js/media-manager/select-files.js

Repository: gambitph/Cimo

Length of output: 17353


disableOptimization guard will never activate — property is never initialized

The guards at Lines 42 (drop-zone.js) and 34–37 (select-files.js) check window.cimoSettings?.disableOptimization, but this property is never added to the localization payload in src/admin/class-script-loader.php. Since nothing initializes or sets this value, the guards remain inert and the intended disable-optimization behavior is non-functional.

Suggested fix
--- a/src/admin/class-script-loader.php
+++ b/src/admin/class-script-loader.php
@@ -84,6 +84,7 @@ public function enqueue_scripts() {
 				'restUrl' => rest_url( 'cimo/v1/' ),
 				'nonce'   => wp_create_nonce( 'wp_rest' ),
 				'isFrontend' => ! is_admin(),
+				'disableOptimization' => 0,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/admin/js/media-manager/drop-zone.js` around lines 42 - 44, The front-end
guard window.cimoSettings?.disableOptimization never triggers because the
localization payload built in src/admin/class-script-loader.php doesn't include
a disableOptimization key; update the payload generator in that file (the method
that builds/localizes cimoSettings) to add a boolean "disableOptimization"
property (derived from the plugin/config option or default false) so that
drop-zone.js and select-files.js can read
window.cimoSettings.disableOptimization and correctly disable optimization when
true.


// If this is a synthetic change event dispatched by us after conversion, skip conversion.
if ( event.__cimo_converted ) {
return
Expand Down
4 changes: 4 additions & 0 deletions src/admin/js/media-manager/select-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ function addSelectFilesListenerToFileUploads( targetDocument ) {
}

const selectFilesListener = async event => {
if ( window.cimoSettings?.disableOptimization ) {
return
}

// Check if it's a file select.
if ( event.target.type !== 'file' ) {
return
Expand Down
90 changes: 88 additions & 2 deletions src/admin/js/page/admin-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const AdminSettings = () => {
const [ settings, setSettings ] = useState( {
// General settings
optimizeAllMedia: 0,
showOptimizationToggle: 0,
showOptimizationToggleFrontend: 0,
persistOptimizationToggle: 0,
disableWpScaling: 1,
disableThumbnailGeneration: 0,
thumbnailSizes: [], // Stores DISABLED thumbnail sizes
Expand Down Expand Up @@ -85,6 +88,9 @@ const AdminSettings = () => {
const fetchedSettings = {
// General Settings
optimizeAllMedia: cimoOptions.optimize_all_media !== undefined ? cimoOptions.optimize_all_media : 0,
showOptimizationToggle: cimoOptions.show_optimization_toggle !== undefined ? cimoOptions.show_optimization_toggle : 0,
showOptimizationToggleFrontend: cimoOptions.show_optimization_toggle_frontend !== undefined ? cimoOptions.show_optimization_toggle_frontend : 0,
persistOptimizationToggle: cimoOptions.persist_optimization_toggle !== undefined ? cimoOptions.persist_optimization_toggle : 0,
disableWpScaling: cimoOptions.disable_wp_scaling !== undefined ? cimoOptions.disable_wp_scaling : 1,
disableThumbnailGeneration: cimoOptions.disable_thumbnail_generation !== undefined ? cimoOptions.disable_thumbnail_generation : 0,
thumbnailSizes: cimoOptions.thumbnail_sizes || [],
Expand Down Expand Up @@ -156,6 +162,9 @@ const AdminSettings = () => {
return {
...settings,
optimizeAllMedia: 0,
showOptimizationToggle: 0,
showOptimizationToggleFrontend: 0,
persistOptimizationToggle: 0,
disableWpScaling: 1,
disableThumbnailGeneration: 1,
thumbnailSizes: [],
Expand All @@ -168,6 +177,9 @@ const AdminSettings = () => {
return {
...settings,
optimizeAllMedia: 0,
showOptimizationToggle: 0,
showOptimizationToggleFrontend: 0,
persistOptimizationToggle: 0,
disableWpScaling: 1,
disableThumbnailGeneration: 0,
thumbnailSizes: [],
Expand Down Expand Up @@ -290,6 +302,9 @@ const AdminSettings = () => {
cimo_options: {
// General settings
optimize_all_media: settings.optimizeAllMedia,
show_optimization_toggle: settings.showOptimizationToggle,
show_optimization_toggle_frontend: settings.showOptimizationToggleFrontend,
persist_optimization_toggle: settings.persistOptimizationToggle,
disable_wp_scaling: settings.disableWpScaling,
disable_thumbnail_generation: settings.disableThumbnailGeneration,
thumbnail_sizes: settings.thumbnailSizes,
Expand Down Expand Up @@ -469,7 +484,7 @@ const AdminSettings = () => {
</Button>
</div>

{ /* Optimize All Media Uploads*/ }
{ /* Optimize All Media Uploads */ }
<div className="cimo-setting-field">
<ToggleControl
__nextHasNoMarginBottom
Expand All @@ -483,13 +498,84 @@ const AdminSettings = () => {
) }
</span>
}
checked={ settings.optimizeAllMedia === 1 }
checked={ buildType === 'premium' ? settings.optimizeAllMedia === 1 : 0 }
disabled={ buildType === 'free' }
onChange={ checked => handleInputChange( 'optimizeAllMedia', checked ? 1 : 0 ) }
help={ __( 'Enable to optimize all files uploaded via any input type="file" on your website, including those in the admin pages, plugin forms and custom HTML upload forms in the frontend of your stie. When disabled, only uploads handled by Cimo\'s official integrations will be optimized.', 'cimo-image-optimizer' ) }
/>
</div>

{ buildType === 'premium' && <hr className="cimo-divider" /> }

{ /* Show Optimization Toggle */ }
<div className="cimo-setting-field">
<ToggleControl
__nextHasNoMarginBottom
label={
<span>
{ __( 'Show Optimization Toggle', 'cimo-image-optimizer' ) }
{ buildType === 'free' && (
<span className="cimo-premium-tag">
{ __( 'Premium', 'cimo-image-optimizer' ) }
</span>
) }
</span>
}
checked={ buildType === 'premium' ? settings.showOptimizationToggle === 1 : 0 }
disabled={ buildType === 'free' }
onChange={ checked => handleInputChange( 'showOptimizationToggle', checked ? 1 : 0 ) }
help={ __( 'Enable to show a small floating toggle near the lower right-hand corner of your screen in the WordPress backend. This can be used to temporarily disable media optimization for the current tab.', 'cimo-image-optimizer' ) }
/>
</div>

{ /* Show in Frontend */ }
{ settings.showOptimizationToggle === 1 && buildType === 'premium' &&
<div className="cimo-setting-field">
<ToggleControl
__nextHasNoMarginBottom
label={
<span>
{ __( 'Show in Frontend', 'cimo-image-optimizer' ) }
{ buildType === 'free' && (
<span className="cimo-premium-tag">
{ __( 'Premium', 'cimo-image-optimizer' ) }
</span>
) }
</span>
}
checked={ buildType === 'premium' ? settings.showOptimizationToggleFrontend === 1 : 0 }
disabled={ buildType === 'free' }
onChange={ checked => handleInputChange( 'showOptimizationToggleFrontend', checked ? 1 : 0 ) }
help={ __( 'Enable to show the optimization toggle also in frontend. Website visitors will also be able to see the floating toggle for visitor-facing forms and whenever there is a file upload input.', 'cimo-image-optimizer' ) }
/>
</div>
}

{ /* Persist Optimization Toggle */ }
{ settings.showOptimizationToggle === 1 && buildType === 'premium' &&
<div className="cimo-setting-field">
<ToggleControl
__nextHasNoMarginBottom
label={
<span>
{ __( 'Remember Toggle On/Off After Page Reload', 'cimo-image-optimizer' ) }
{ buildType === 'free' && (
<span className="cimo-premium-tag">
{ __( 'Premium', 'cimo-image-optimizer' ) }
</span>
) }
</span>
}
checked={ buildType === 'premium' ? settings.persistOptimizationToggle === 1 : 0 }
disabled={ buildType === 'free' }
onChange={ checked => handleInputChange( 'persistOptimizationToggle', checked ? 1 : 0 ) }
help={ __( 'If enabled, your optimization toggle will remain the same even after you refresh the page or visit other pages. If disabled, the toggle will always reset to ON after reloading the page.', 'cimo-image-optimizer' ) }
/>
</div>
}

{ buildType === 'premium' && <hr className="cimo-divider" /> }

{ /* WordPress Auto-Scaling */ }
<div className="cimo-setting-field">
<ToggleControl
Expand Down
Loading