PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / trunk
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization vtrunk
4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 2.5.5 2.5.6 2.5.7 3.0.0 3.0.1 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.11.0 3.11.1 3.11.2 3.11.3 3.12.0 All 135 releases
← All changes | inc/settings.php +299 -150 3.11.1 → trunk View file →
@@ -1,6 +1,8 @@
1 1 <?php
2 2
3 +use Optimole\Sdk\ValueObject\Position;
4 +
3 5 /**
4 6 * Class Optml_Settings.
5 7 */
6 8 class Optml_Settings {
@@ -13,8 +15,9 @@
13 15 const FILTER_CLASS = 'class';
14 16 const FILTER_TYPE_LAZYLOAD = 'lazyload';
15 17 const FILTER_TYPE_OPTIMIZE = 'optimize';
16 18 const OPTML_USER_EMAIL = 'optml_user_email';
19 + const INDIVIDUAL_CACHE_TOKENS_KEY = '_optml_cache_tokens_individual';
17 20 /**
18 21 * Holds an array of possible settings to alter via wp cli or wp-config constants.
19 22 *
20 23 * @var array Whitelisted settings.
@@ -47,55 +50,62 @@
47 50 *
48 51 * @var array Settings schema.
49 52 */
50 53 private $default_schema = [
51 - 'api_key' => '',
52 - 'service_data' => '',
53 - 'cache_buster' => '',
54 - 'cache_buster_assets' => '',
55 - 'cache_buster_images' => '',
56 - 'cdn' => 'disabled',
57 - 'admin_bar_item' => 'enabled',
58 - 'lazyload' => 'disabled',
59 - 'scale' => 'disabled',
60 - 'network_optimization' => 'disabled',
61 - 'lazyload_placeholder' => 'enabled',
62 - 'bg_replacer' => 'enabled',
63 - 'video_lazyload' => 'enabled',
64 - 'retina_images' => 'disabled',
65 - 'limit_dimensions' => 'enabled',
66 - 'limit_height' => 1080,
67 - 'limit_width' => 1920,
68 - 'resize_smart' => 'disabled',
69 - 'no_script' => 'disabled',
70 - 'filters' => [],
71 - 'cloud_sites' => [ 'all' => 'true' ],
72 - 'watchers' => '',
73 - 'quality' => 'auto',
74 - 'wm_id' => - 1,
75 - 'wm_opacity' => 1,
76 - 'wm_position' => Optml_Resize::GRAVITY_SOUTH_EAST,
77 - 'wm_x' => 0,
78 - 'wm_y' => 0,
79 - 'wm_scale' => 0,
80 - 'image_replacer' => 'enabled',
81 - 'img_to_video' => 'disabled',
82 - 'css_minify' => 'enabled',
83 - 'js_minify' => 'disabled',
84 - 'report_script' => 'disabled',
85 - 'avif' => 'enabled',
86 - 'autoquality' => 'enabled',
87 - 'native_lazyload' => 'disabled',
88 - 'offload_media' => 'disabled',
89 - 'cloud_images' => 'disabled',
90 - 'strip_metadata' => 'enabled',
91 - 'skip_lazyload_images' => 3,
92 - 'defined_image_sizes' => [ ],
93 - 'banner_frontend' => 'disabled',
94 - 'offloading_status' => 'disabled',
95 - 'rollback_status' => 'disabled',
96 - 'best_format' => 'enabled',
97 - 'placeholder_color' => '',
54 + 'api_key' => '',
55 + 'service_data' => '',
56 + 'cache_buster' => '',
57 + 'cache_buster_assets' => '',
58 + 'cache_buster_images' => '',
59 + 'cdn' => 'disabled',
60 + 'admin_bar_item' => 'enabled',
61 + 'lazyload' => 'disabled',
62 + 'scale' => 'disabled', // Due to legacy reasons the disabled state means that the scale is enabled and the enabled state means that the scale is disabled.
63 + 'network_optimization' => 'enabled',
64 + 'lazyload_placeholder' => 'enabled',
65 + 'bg_replacer' => 'enabled',
66 + 'video_lazyload' => 'enabled',
67 + 'retina_images' => 'disabled',
68 + 'lazyload_type' => 'fixed|viewport',
69 + 'limit_dimensions' => 'enabled',
70 + 'limit_height' => 4000,
71 + 'limit_width' => 1920,
72 + 'resize_smart' => 'disabled',
73 + 'no_script' => 'disabled',
74 + 'filters' => [],
75 + 'compression_mode' => 'custom',
76 + 'cloud_sites' => [ 'all' => 'true' ],
77 + 'watchers' => '',
78 + 'quality' => 80,
79 + 'wm_id' => - 1,
80 + 'wm_opacity' => 1,
81 + 'wm_position' => Position::SOUTH_EAST,
82 + 'wm_x' => 0,
83 + 'wm_y' => 0,
84 + 'wm_scale' => 0,
85 + 'image_replacer' => 'enabled',
86 + 'img_to_video' => 'disabled',
87 + 'css_minify' => 'enabled',
88 + 'js_minify' => 'disabled',
89 + 'avif' => 'enabled', // legacy setting, is no longer used in the UI
90 + 'autoquality' => 'enabled',
91 + 'native_lazyload' => 'disabled',
92 + 'offload_media' => 'disabled',
93 + 'transfer_status' => 'disabled',
94 + 'cloud_images' => 'enabled',
95 + 'strip_metadata' => 'enabled',
96 + 'skip_lazyload_images' => 2,
97 + 'defined_image_sizes' => [],
98 + 'banner_frontend' => 'disabled',
99 + 'offloading_status' => 'disabled',
100 + 'rollback_status' => 'disabled',
101 + 'best_format' => 'enabled',
102 + 'offload_limit_reached' => 'disabled',
103 + 'offload_limit' => 50000,
104 + 'placeholder_color' => '',
105 + 'show_offload_finish_notice' => '',
106 + 'show_badge_icon' => 'disabled',
107 + 'badge_position' => 'left',
98 108 ];
99 109 /**
100 110 * Option key.
101 111 *
@@ -106,22 +116,30 @@
106 116 * Holds all options from db.
107 117 *
108 118 * @var array All options.
109 119 */
110 - private $options;
120 + private static $options;
111 121
112 122 /**
123 + * Cache for site settings to avoid multiple calls to get_option on the same request.
124 + *
125 + * @var array<string, mixed>|null Cached site settings.
126 + */
127 + private static $site_settings_cache = null;
128 +
129 + /**
113 130 * Optml_Settings constructor.
114 131 */
115 132 public function __construct() {
133 + $this->default_schema['cloud_sites'] = $this->get_cloud_sites_whitelist_default();
116 134
117 135 $this->namespace = OPTML_NAMESPACE . '_settings';
118 136 $this->default_schema = apply_filters( 'optml_default_settings', $this->default_schema );
119 - $this->options = wp_parse_args( get_option( $this->namespace, $this->default_schema ), $this->default_schema );
137 + self::$options = wp_parse_args( get_option( $this->namespace, $this->default_schema ), $this->default_schema );
120 138
121 139 if ( defined( 'OPTIML_ENABLED_MU' ) && defined( 'OPTIML_MU_SITE_ID' ) && $this->to_boolean( constant( 'OPTIML_ENABLED_MU' ) ) && constant( 'OPTIML_MU_SITE_ID' ) ) {
122 140 switch_to_blog( constant( 'OPTIML_MU_SITE_ID' ) );
123 - $this->options = wp_parse_args( get_option( $this->namespace, $this->default_schema ), $this->default_schema );
141 + self::$options = wp_parse_args( get_option( $this->namespace, $this->default_schema ), $this->default_schema );
124 142 restore_current_blog();
125 143 }
126 144
127 145 if ( defined( 'OPTIML_USE_ENV' ) && constant( 'OPTIML_USE_ENV' ) && $this->to_boolean( constant( 'OPTIML_USE_ENV' ) ) ) {
@@ -126,9 +144,9 @@
126 144
127 145 if ( defined( 'OPTIML_USE_ENV' ) && constant( 'OPTIML_USE_ENV' ) && $this->to_boolean( constant( 'OPTIML_USE_ENV' ) ) ) {
128 146
129 147 if ( defined( 'OPTIML_API_KEY' )
130 - && constant( 'OPTIML_API_KEY' ) !== ''
148 + && constant( 'OPTIML_API_KEY' ) !== ''
131 149 ) {
132 150 if ( ! $this->is_connected() && ! self::$auto_connect_hooked ) {
133 151 self::$auto_connect_hooked = true;
134 152 add_action(
@@ -156,14 +174,12 @@
156 174 if ( $type === 'int' && ( (string) $value === '' || (int) $value > 100 || (int) $value < 0 ) ) {
157 175 continue;
158 176 }
159 177 $sanitized_value = ( $type === 'bool' ) ? ( $value === 'on' ? 'enabled' : 'disabled' ) : (int) $value;
160 - $this->options[ $key ] = $sanitized_value;
178 + self::$options[ $key ] = $sanitized_value;
161 179 }
162 180 }
163 181 }
164 -
165 - add_action( 'init', [ $this, 'register_settings' ] );
166 182 }
167 183
168 184 /**
169 185 * Check if the user is connected to Optimole.
@@ -193,9 +209,9 @@
193 209 if ( ! $this->is_allowed( $key ) ) {
194 210 return null;
195 211 }
196 212
197 - return isset( $this->options[ $key ] ) ? $this->options[ $key ] : '';
213 + return isset( self::$options[ $key ] ) ? self::$options[ $key ] : '';
198 214 }
199 215
200 216 /**
201 217 * Check if key is allowed.
@@ -211,8 +227,14 @@
211 227 /**
212 228 * Auto connect action.
213 229 */
214 230 public function auto_connect() {
231 +
232 + /**
233 + * Connect rest request.
234 + *
235 + * @var WP_REST_Request<array{api_key: string, application?: string}>
236 + */
215 237 $request = new WP_REST_Request( 'POST' );
216 238 $request->set_param( 'api_key', constant( 'OPTIML_API_KEY' ) );
217 239 Optml_Main::instance()->rest->connect( $request );
218 240
@@ -227,9 +249,11 @@
227 249 *
228 250 * @return array
229 251 */
230 252 public function parse_settings( $new_settings ) {
231 - $sanitized = [];
253 + $sanitized = [];
254 + $sanitized_value = '';
255 +
232 256 foreach ( $new_settings as $key => $value ) {
233 257 switch ( $key ) {
234 258 case 'admin_bar_item':
235 259 case 'lazyload':
@@ -242,9 +266,8 @@
242 266 case 'limit_dimensions':
243 267 case 'resize_smart':
244 268 case 'bg_replacer':
245 269 case 'video_lazyload':
246 - case 'report_script':
247 270 case 'avif':
248 271 case 'offload_media':
249 272 case 'cloud_images':
250 273 case 'autoquality':
@@ -257,25 +280,41 @@
257 280 case 'banner_frontend':
258 281 case 'offloading_status':
259 282 case 'rollback_status':
260 283 case 'best_format':
284 + case 'offload_limit_reached':
285 + case 'show_badge_icon':
261 286 $sanitized_value = $this->to_map_values( $value, [ 'enabled', 'disabled' ], 'enabled' );
262 287 break;
288 + case 'offload_limit':
289 + $sanitized_value = absint( $value );
290 + break;
263 291 case 'limit_height':
264 292 case 'limit_width':
265 293 $sanitized_value = $this->to_bound_integer( $value, 100, 5000 );
266 294 break;
267 295 case 'quality':
268 - $sanitized_value = $this->to_bound_integer( $value, 1, 100 );
296 + if ( 'mauto' !== $value ) {
297 + $sanitized_value = $this->to_bound_integer( $value, 50, 100 );
298 + }
269 299 break;
270 300 case 'wm_id':
271 301 $sanitized_value = intval( $value );
272 302 break;
303 + case 'show_offload_finish_notice':
304 + $sanitized_value = $this->to_map_values( $value, [ 'offload', 'rollback' ], '' );
305 + break;
273 306 case 'cache_buster_assets':
274 307 case 'cache_buster_images':
275 308 case 'cache_buster':
276 309 $sanitized_value = is_string( $value ) ? sanitize_text_field( $value ) : '';
277 310 break;
311 + case 'lazyload_type':
312 + $sanitized_value = $this->to_map_values( $value, [ 'fixed', 'viewport', 'all', 'fixed|viewport' ], 'fixed' );
313 + break;
314 + case 'compression_mode':
315 + $sanitized_value = $this->to_map_values( $value, [ 'speed_optimized', 'quality_optimized', 'custom' ], 'custom' );
316 + break;
278 317 case 'cloud_sites':
279 318 $current_sites = $this->get( 'cloud_sites' );
280 319 $sanitized_value = array_replace_recursive( $current_sites, $value );
281 320 if ( isset( $value['all'] ) && $value['all'] === 'true' ) {
@@ -282,9 +321,9 @@
282 321 $sanitized_value = [ 'all' => 'true' ];
283 322 }
284 323 break;
285 324 case 'defined_image_sizes':
286 - $current_sizes = $this->get( 'defined_image_sizes' );
325 + $current_sizes = $this->get( 'defined_image_sizes' );
287 326 foreach ( $value as $size_name => $size_value ) {
288 327 if ( $size_value === 'remove' ) {
289 328 unset( $current_sizes[ $size_name ] );
290 329 unset( $value[ $size_name ] );
@@ -308,8 +347,9 @@
308 347 }
309 348 break;
310 349 case 'watchers':
311 350 case 'placeholder_color':
351 + case 'transfer_status':
312 352 $sanitized_value = sanitize_text_field( $value );
313 353 break;
314 354 case 'skip_lazyload_images':
315 355 $sanitized_value = $this->to_bound_integer( $value, 0, 100 );
@@ -323,21 +363,24 @@
323 363 case 'wm_position':
324 364 $sanitized_value = $this->to_map_values(
325 365 $value,
326 366 [
327 - Optml_Resize::GRAVITY_NORTH,
328 - Optml_Resize::GRAVITY_NORTH_EAST,
329 - Optml_Resize::GRAVITY_NORTH_WEST,
330 - Optml_Resize::GRAVITY_CENTER,
331 - Optml_Resize::GRAVITY_EAST,
332 - Optml_Resize::GRAVITY_WEST,
333 - Optml_Resize::GRAVITY_SOUTH_EAST,
334 - Optml_Resize::GRAVITY_SOUTH,
335 - Optml_Resize::GRAVITY_SOUTH_WEST,
367 + Position::NORTH,
368 + Position::NORTH_EAST,
369 + Position::NORTH_WEST,
370 + Position::CENTER,
371 + Position::EAST,
372 + Position::WEST,
373 + Position::SOUTH_EAST,
374 + Position::SOUTH,
375 + Position::SOUTH_WEST,
336 376 ],
337 - Optml_Resize::GRAVITY_SOUTH_EAST
377 + Position::SOUTH_EAST
338 378 );
339 379 break;
380 + case 'badge_position':
381 + $sanitized_value = $this->to_map_values( $value, [ 'left', 'right' ], 'right' );
382 + break;
340 383 default:
341 384 $sanitized_value = '';
342 385 break;
343 386
@@ -396,15 +439,16 @@
396 439 if ( ! $this->is_main_mu_site() ) {
397 440 return false;
398 441 }
399 442
400 - $opts = $this->options;
443 + $opts = self::$options;
401 444 $opts['banner_frontend'] = $value ? 'enabled' : 'disabled';
402 445
403 446 $update = update_option( $this->namespace, $opts, false );
404 447
405 448 if ( $update ) {
406 - $this->options = $opts;
449 + self::$options = $opts;
450 + $this->set_settings_cache( 'banner_frontend', $opts['banner_frontend'] );
407 451 }
408 452
409 453 return $update;
410 454 }
@@ -424,9 +468,9 @@
424 468
425 469 if ( ! $this->is_main_mu_site() ) {
426 470 return false;
427 471 }
428 - $opt = $this->options;
472 + $opt = self::$options;
429 473
430 474 if ( $key === 'banner_frontend' ) {
431 475 $api = new Optml_Api();
432 476 $service_data = $this->get( 'service_data' );
@@ -434,14 +478,39 @@
434 478 $response = $api->update_extra_visits( $opt['api_key'], $value, $application );
435 479 }
436 480
437 481 $opt[ $key ] = $value;
482 +
438 483 $update = update_option( $this->namespace, $opt, false );
484 +
439 485 if ( $update ) {
440 - $this->options = $opt;
486 + self::$options = $opt;
487 + $this->set_settings_cache( $key, $value );
441 488 }
442 489 if ( apply_filters( 'optml_dont_trigger_settings_updated', false ) === false ) {
490 + /**
491 + * Fires when Optimole settings are updated.
492 + *
493 + * This action is triggered after settings have been successfully updated
494 + * and provides an opportunity for other plugins or themes to react to
495 + * Optimole configuration changes.
496 + */
443 497 do_action( 'optml_settings_updated' );
498 + static $cleared = false;
499 + if ( $cleared ) {
500 + return $update;
501 + }
502 + $cleared = true;
503 + /**
504 + * Fires when Optimole cache needs to be cleared after settings update.
505 + *
506 + * This action is triggered after settings are updated to ensure that
507 + * any cached data is refreshed with the new configuration.
508 + *
509 + * @param bool|string $location Whether to clear the cache globally or just for a particular request.
510 + * You can pass a string with the URL to clear the cache for a particular URL only.
511 + */
512 + do_action( 'optml_clear_cache', true );
444 513 }
445 514 return $update;
446 515 }
447 516
@@ -452,9 +521,9 @@
452 521 */
453 522 private function is_main_mu_site() {
454 523 // If we try to update from a website which is not the main OPTML blog, bail.
455 524 if ( defined( 'OPTIML_ENABLED_MU' ) && constant( 'OPTIML_ENABLED_MU' ) && defined( 'OPTIML_MU_SITE_ID' ) && constant( 'OPTIML_MU_SITE_ID' ) &&
456 - intval( constant( 'OPTIML_MU_SITE_ID' ) ) !== get_current_blog_id()
525 + intval( constant( 'OPTIML_MU_SITE_ID' ) ) !== get_current_blog_id()
457 526 ) {
458 527 return false;
459 528 }
460 529
@@ -466,8 +535,12 @@
466 535 *
467 536 * @return array Site settings.
468 537 */
469 538 public function get_site_settings() {
539 + if ( self::$site_settings_cache !== null ) {
540 + return self::$site_settings_cache;
541 + }
542 +
470 543 $service_data = $this->get( 'service_data' );
471 544 $whitelist = [];
472 545 if ( isset( $service_data['whitelist'] ) ) {
473 546 $whitelist = $service_data['whitelist'];
@@ -472,48 +545,54 @@
472 545 if ( isset( $service_data['whitelist'] ) ) {
473 546 $whitelist = $service_data['whitelist'];
474 547 }
475 548
476 - return [
477 - 'quality' => $this->get_quality(),
478 - 'admin_bar_item' => $this->get( 'admin_bar_item' ),
479 - 'lazyload' => $this->get( 'lazyload' ),
480 - 'network_optimization' => $this->get( 'network_optimization' ),
481 - 'retina_images' => $this->get( 'retina_images' ),
482 - 'limit_dimensions' => $this->get( 'limit_dimensions' ),
483 - 'limit_height' => $this->get( 'limit_height' ),
484 - 'limit_width' => $this->get( 'limit_width' ),
485 - 'lazyload_placeholder' => $this->get( 'lazyload_placeholder' ),
486 - 'skip_lazyload_images' => $this->get( 'skip_lazyload_images' ),
487 - 'bg_replacer' => $this->get( 'bg_replacer' ),
488 - 'video_lazyload' => $this->get( 'video_lazyload' ),
489 - 'resize_smart' => $this->get( 'resize_smart' ),
490 - 'no_script' => $this->get( 'no_script' ),
491 - 'image_replacer' => $this->get( 'image_replacer' ),
492 - 'cdn' => $this->get( 'cdn' ),
493 - 'filters' => $this->get_filters(),
494 - 'cloud_sites' => $this->get( 'cloud_sites' ),
495 - 'defined_image_sizes' => $this->get( 'defined_image_sizes' ),
496 - 'watchers' => $this->get_watchers(),
497 - 'watermark' => $this->get_watermark(),
498 - 'img_to_video' => $this->get( 'img_to_video' ),
499 - 'scale' => $this->get( 'scale' ),
500 - 'css_minify' => $this->get( 'css_minify' ),
501 - 'js_minify' => $this->get( 'js_minify' ),
502 - 'native_lazyload' => $this->get( 'native_lazyload' ),
503 - 'report_script' => $this->get( 'report_script' ),
504 - 'avif' => $this->get( 'avif' ),
505 - 'autoquality' => $this->get( 'autoquality' ),
506 - 'offload_media' => $this->get( 'offload_media' ),
507 - 'cloud_images' => $this->get( 'cloud_images' ),
508 - 'strip_metadata' => $this->get( 'strip_metadata' ),
509 - 'whitelist_domains' => $whitelist,
510 - 'banner_frontend' => $this->get( 'banner_frontend' ),
511 - 'offloading_status' => $this->get( 'offloading_status' ),
512 - 'rollback_status' => $this->get( 'rollback_status' ),
513 - 'best_format' => $this->get( 'best_format' ),
514 - 'placeholder_color' => $this->get( 'placeholder_color' ),
549 + self::$site_settings_cache = [
550 + 'quality' => $this->get_quality(),
551 + 'admin_bar_item' => $this->get( 'admin_bar_item' ),
552 + 'lazyload' => $this->get( 'lazyload' ),
553 + 'network_optimization' => $this->get( 'network_optimization' ),
554 + 'retina_images' => $this->get( 'retina_images' ),
555 + 'limit_dimensions' => $this->get( 'limit_dimensions' ),
556 + 'limit_height' => $this->get( 'limit_height' ),
557 + 'limit_width' => $this->get( 'limit_width' ),
558 + 'lazyload_placeholder' => $this->get( 'lazyload_placeholder' ),
559 + 'skip_lazyload_images' => $this->get( 'skip_lazyload_images' ),
560 + 'bg_replacer' => $this->get( 'bg_replacer' ),
561 + 'video_lazyload' => $this->get( 'video_lazyload' ),
562 + 'resize_smart' => $this->get( 'resize_smart' ),
563 + 'no_script' => $this->get( 'no_script' ),
564 + 'lazyload_type' => $this->get( 'lazyload_type' ),
565 + 'compression_mode' => $this->get( 'compression_mode' ),
566 + 'image_replacer' => $this->get( 'image_replacer' ),
567 + 'cdn' => $this->get( 'cdn' ),
568 + 'filters' => $this->get_filters(),
569 + 'cloud_sites' => $this->get( 'cloud_sites' ),
570 + 'defined_image_sizes' => $this->get( 'defined_image_sizes' ),
571 + 'watchers' => $this->get_watchers(),
572 + 'watermark' => $this->get_watermark(),
573 + 'img_to_video' => $this->get( 'img_to_video' ), // @deprecated
574 + 'scale' => $this->get( 'scale' ),
575 + 'css_minify' => $this->get( 'css_minify' ),
576 + 'js_minify' => $this->get( 'js_minify' ),
577 + 'native_lazyload' => $this->get( 'native_lazyload' ),
578 + 'avif' => $this->get( 'avif' ),
579 + 'autoquality' => $this->get( 'autoquality' ),
580 + 'offload_media' => $this->get( 'offload_media' ),
581 + 'cloud_images' => $this->get( 'cloud_images' ),
582 + 'strip_metadata' => $this->get( 'strip_metadata' ),
583 + 'whitelist_domains' => $whitelist,
584 + 'banner_frontend' => $this->get( 'banner_frontend' ),
585 + 'offloading_status' => $this->get( 'offloading_status' ),
586 + 'rollback_status' => $this->get( 'rollback_status' ),
587 + 'best_format' => $this->get( 'best_format' ),
588 + 'offload_limit_reached' => $this->get( 'offload_limit_reached' ),
589 + 'placeholder_color' => $this->get( 'placeholder_color' ),
590 + 'show_offload_finish_notice' => $this->get( 'show_offload_finish_notice' ),
591 + 'show_badge_icon' => $this->get( 'show_badge_icon' ),
592 + 'badge_position' => $this->get( 'badge_position' ),
515 593 ];
594 + return self::$site_settings_cache;
516 595 }
517 596
518 597 /**
519 598 * Return quality factor.
@@ -547,9 +626,8 @@
547 626 */
548 627 public function get_watchers() {
549 628
550 629 return $this->get( 'watchers' );
551 -
552 630 }
553 631
554 632 /**
555 633 * Return an watermark array.
@@ -583,10 +661,27 @@
583 661 */
584 662 public function is_best_format() {
585 663 return $this->get( 'best_format' ) === 'enabled';
586 664 }
665 + /**
666 + * Check if scale is enabled.
667 + *
668 + * @return bool Scale enabled
669 + */
670 + public function is_scale_enabled() {
671 + return $this->get( 'scale' ) === 'disabled'; // Due to legacy reasons the disabled state means that the scale is enabled and the enabled state means that the scale is disabled.
672 + }
587 673
588 674 /**
675 + * Check if offload limit was reached.
676 + *
677 + * @return bool
678 + */
679 + public function is_offload_limit_reached() {
680 + return $this->get( 'offload_limit_reached' ) === 'enabled';
681 + }
682 +
683 + /**
589 684 * Get numeric quality used by the service.
590 685 *
591 686 * @return int Numeric quality.
592 687 */
@@ -646,16 +741,16 @@
646 741 if ( ! isset( $service_data['cdn_key'] ) ) {
647 742 return '';
648 743 }
649 744
745 + if ( defined( 'OPTML_CUSTOM_DOMAIN' ) && constant( 'OPTML_CUSTOM_DOMAIN' ) ) {
746 + return parse_url( strtolower( OPTML_CUSTOM_DOMAIN ), PHP_URL_HOST );
747 + }
748 +
650 749 if ( isset( $service_data['is_cname_assigned'] ) && $service_data['is_cname_assigned'] === 'yes' && ! empty( $service_data['domain'] ) ) {
651 750 return strtolower( $service_data['domain'] );
652 751 }
653 752
654 - if ( defined( 'OPTML_CUSTOM_DOMAIN' ) && constant( 'OPTML_CUSTOM_DOMAIN' ) ) {
655 - return parse_url( strtolower( OPTML_CUSTOM_DOMAIN ), PHP_URL_HOST );
656 - }
657 -
658 753 return sprintf(
659 754 '%s.%s',
660 755 strtolower( $service_data['cdn_key'] ),
661 756 Optml_Config::$base_domain
@@ -668,17 +763,21 @@
668 763 * @return bool Reset action status.
669 764 */
670 765 public function reset() {
671 766 $reset_schema = $this->default_schema;
672 - $reset_schema['filters'] = $this->options['filters'];
767 + $reset_schema['filters'] = self::$options['filters'];
673 768
674 769 $update = update_option( $this->namespace, $reset_schema );
675 770 if ( $update ) {
676 - $this->options = $reset_schema;
771 + self::$options = $reset_schema;
772 + $this->set_settings_cache( 'filters', $reset_schema['filters'] );
677 773 }
774 + wp_unschedule_hook( Optml_Admin::SYNC_CRON );
775 + wp_unschedule_hook( Optml_Admin::ENRICH_CRON );
678 776
679 777 return $update;
680 778 }
779 +
681 780 /**
682 781 * Get raw settings value.
683 782 *
684 783 * @return array
@@ -683,28 +782,13 @@
683 782 *
684 783 * @return array
685 784 */
686 785 public function get_raw_settings() {
687 - return get_option( $this->namespace, false );
786 + $raw_settings = get_option( $this->namespace, [] );
787 +
788 + return is_array( $raw_settings ) ? $raw_settings : [];
688 789 }
689 790
690 - /**
691 - * Get settings for CSAT.
692 - *
693 - * @return void
694 - */
695 - public function register_settings() {
696 - register_setting(
697 - 'optml_settings',
698 - 'optml_csat',
699 - [
700 - 'type' => 'string',
701 - 'sanitize_callback' => 'sanitize_text_field',
702 - 'show_in_rest' => true,
703 - 'default' => '{}',
704 - ]
705 - );
706 - }
707 791
708 792 /**
709 793 * Clear cache.
710 794 *
@@ -712,21 +796,25 @@
712 796 *
713 797 * @return string|WP_Error
714 798 */
715 799 public function clear_cache( $type = '' ) {
716 - $token = $this->get( 'cache_buster' );
800 + $token = $this->get( 'cache_buster' );
717 801 $token_images = $this->get( 'cache_buster_images' );
718 802
719 - if ( ! empty( $token_images ) ) {
720 - $token = $token_images;
721 - }
722 -
723 - if ( ! empty( $type ) && $type === 'assets' ) {
803 + // here is an individual cache tokens
804 + $individual = get_transient( self::INDIVIDUAL_CACHE_TOKENS_KEY ) ?: [];
805 + if ( ( empty( $type ) || $type === 'images' ) ) {
806 + if ( ! empty( $token_images ) ) {
807 + $token = $token_images;
808 + }
809 + } elseif ( $type === 'assets' ) {
724 810 $token = $this->get( 'cache_buster_assets' );
811 + } else {
812 + $token = $individual[ crc32( $type ) ] ?? $token_images ?: $token;
725 813 }
726 814
727 - $request = new Optml_Api();
728 - $data = $request->get_cache_token( $token, $type );
815 + $request = new Optml_Api();
816 + $data = $request->get_cache_token( $token, $type );
729 817
730 818 if ( $data === false || is_wp_error( $data ) || empty( $data ) || ! isset( $data['token'] ) ) {
731 819 $extra = '';
732 820
@@ -735,20 +823,25 @@
735 823 * Error from api.
736 824 *
737 825 * @var WP_Error $data Error object.
738 826 */
739 - $extra = sprintf( __( '. ERROR details: %s', 'optimole-wp' ), $data->get_error_message() );
827 + $extra = sprintf( /* translators: Error details */ __( '. ERROR details: %s', 'optimole-wp' ), $data->get_error_message() );
740 828 }
741 829
742 830 return new WP_Error( 'optimole_cache_buster_error', __( 'Can not get new token from Optimole service', 'optimole-wp' ) . $extra );
743 831 }
744 832
745 - if ( ! empty( $type ) && $type === 'assets' ) {
833 + if ( empty( $type ) || $type === 'images' ) {
834 + set_transient( 'optml_cache_lock', 'yes', 5 * MINUTE_IN_SECONDS );
835 + $this->update( 'cache_buster_images', $data['token'] );
836 + // we delete individual cache tokens since this is a global cache clear.
837 + delete_transient( self::INDIVIDUAL_CACHE_TOKENS_KEY );
838 + } elseif ( $type === 'assets' ) {
746 839 set_transient( 'optml_cache_lock_assets', 'yes', 5 * MINUTE_IN_SECONDS );
747 840 $this->update( 'cache_buster_assets', $data['token'] );
748 841 } else {
749 - set_transient( 'optml_cache_lock', 'yes', 5 * MINUTE_IN_SECONDS );
750 - $this->update( 'cache_buster_images', $data['token'] );
842 + $individual[ crc32( $type ) ] = $data['token'];
843 + set_transient( self::INDIVIDUAL_CACHE_TOKENS_KEY, $individual, 6 * HOUR_IN_SECONDS );
751 844 }
752 845
753 846 return $data['token'];
754 847 }
@@ -753,8 +846,34 @@
753 846 return $data['token'];
754 847 }
755 848
756 849 /**
850 + * Check if lazyload type is viewport.
851 + *
852 + * @return bool
853 + */
854 + public function is_lazyload_type_viewport() {
855 + return false !== strpos( $this->get( 'lazyload_type' ), 'viewport' );
856 + }
857 +
858 + /**
859 + * Check if lazyload type is all.
860 + *
861 + * @return bool
862 + */
863 + public function is_lazyload_type_all() {
864 + return $this->get( 'lazyload_type' ) === 'all';
865 + }
866 +
867 + /**
868 + * Check if lazyload type is fixed.
869 + *
870 + * @return bool
871 + */
872 + public function is_lazyload_type_fixed() {
873 + return false !== strpos( $this->get( 'lazyload_type' ), 'fixed' );
874 + }
875 + /**
757 876 * Utility to check if offload is enabled.
758 877 *
759 878 * @return bool
760 879 */
@@ -759,6 +878,36 @@
759 878 * @return bool
760 879 */
761 880 public function is_offload_enabled() {
762 881 return $this->get( 'offload_media' ) === 'enabled' || $this->get( 'rollback_status' ) !== 'disabled';
882 + }
883 +
884 + /**
885 + * Get cloud sites whitelist for current domain only.
886 + *
887 + * @return array
888 + */
889 + public function get_cloud_sites_whitelist_default() {
890 + $site_url = get_site_url();
891 +
892 + $site_url = preg_replace( '/^https?:\/\//', '', $site_url );
893 + $site_url = trim( $site_url, '/' );
894 +
895 + return [
896 + 'all' => 'false',
897 + $site_url => 'true',
898 + ];
899 + }
900 +
901 + /**
902 + * Set settings cache value.
903 + *
904 + * @param string $key Cache key.
905 + * @param mixed $value Cache value.
906 + * @return void
907 + */
908 + private function set_settings_cache( $key, $value ) {
909 + if ( self::$site_settings_cache !== null && isset( self::$site_settings_cache[ $key ] ) ) {
910 + self::$site_settings_cache[ $key ] = $value;
911 + }
763 912 }
764 913 }