PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / 4.2.15
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization v4.2.15
4.2.15 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 All 136 releases
← All changes | inc/settings.php +308 -156 3.10.0 → 4.2.15 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,57 +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 - 'max_height' => 1500,
58 - 'max_width' => 2000,
59 - 'admin_bar_item' => 'enabled',
60 - 'lazyload' => 'disabled',
61 - 'scale' => 'disabled',
62 - 'network_optimization' => 'disabled',
63 - 'lazyload_placeholder' => 'enabled',
64 - 'bg_replacer' => 'enabled',
65 - 'video_lazyload' => 'enabled',
66 - 'retina_images' => 'disabled',
67 - 'limit_dimensions' => 'disabled',
68 - 'limit_height' => 1080,
69 - 'limit_width' => 1920,
70 - 'resize_smart' => 'disabled',
71 - 'no_script' => 'disabled',
72 - 'filters' => [],
73 - 'cloud_sites' => [ 'all' => 'true' ],
74 - 'watchers' => '',
75 - 'quality' => 'auto',
76 - 'wm_id' => - 1,
77 - 'wm_opacity' => 1,
78 - 'wm_position' => Optml_Resize::GRAVITY_SOUTH_EAST,
79 - 'wm_x' => 0,
80 - 'wm_y' => 0,
81 - 'wm_scale' => 0,
82 - 'image_replacer' => 'enabled',
83 - 'img_to_video' => 'disabled',
84 - 'css_minify' => 'enabled',
85 - 'js_minify' => 'disabled',
86 - 'report_script' => 'disabled',
87 - 'avif' => 'enabled',
88 - 'autoquality' => 'enabled',
89 - 'native_lazyload' => 'disabled',
90 - 'offload_media' => 'disabled',
91 - 'cloud_images' => 'disabled',
92 - 'strip_metadata' => 'enabled',
93 - 'skip_lazyload_images' => 3,
94 - 'defined_image_sizes' => [ ],
95 - 'banner_frontend' => 'disabled',
96 - 'offloading_status' => 'disabled',
97 - 'rollback_status' => 'disabled',
98 - 'best_format' => 'enabled',
99 - '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',
100 108 ];
101 109 /**
102 110 * Option key.
103 111 *
@@ -108,22 +116,30 @@
108 116 * Holds all options from db.
109 117 *
110 118 * @var array All options.
111 119 */
112 - private $options;
120 + private static $options;
113 121
114 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 + /**
115 130 * Optml_Settings constructor.
116 131 */
117 132 public function __construct() {
133 + $this->default_schema['cloud_sites'] = $this->get_cloud_sites_whitelist_default();
118 134
119 135 $this->namespace = OPTML_NAMESPACE . '_settings';
120 136 $this->default_schema = apply_filters( 'optml_default_settings', $this->default_schema );
121 - $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 );
122 138
123 139 if ( defined( 'OPTIML_ENABLED_MU' ) && defined( 'OPTIML_MU_SITE_ID' ) && $this->to_boolean( constant( 'OPTIML_ENABLED_MU' ) ) && constant( 'OPTIML_MU_SITE_ID' ) ) {
124 140 switch_to_blog( constant( 'OPTIML_MU_SITE_ID' ) );
125 - $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 );
126 142 restore_current_blog();
127 143 }
128 144
129 145 if ( defined( 'OPTIML_USE_ENV' ) && constant( 'OPTIML_USE_ENV' ) && $this->to_boolean( constant( 'OPTIML_USE_ENV' ) ) ) {
@@ -128,9 +144,9 @@
128 144
129 145 if ( defined( 'OPTIML_USE_ENV' ) && constant( 'OPTIML_USE_ENV' ) && $this->to_boolean( constant( 'OPTIML_USE_ENV' ) ) ) {
130 146
131 147 if ( defined( 'OPTIML_API_KEY' )
132 - && constant( 'OPTIML_API_KEY' ) !== ''
148 + && constant( 'OPTIML_API_KEY' ) !== ''
133 149 ) {
134 150 if ( ! $this->is_connected() && ! self::$auto_connect_hooked ) {
135 151 self::$auto_connect_hooked = true;
136 152 add_action(
@@ -158,14 +174,12 @@
158 174 if ( $type === 'int' && ( (string) $value === '' || (int) $value > 100 || (int) $value < 0 ) ) {
159 175 continue;
160 176 }
161 177 $sanitized_value = ( $type === 'bool' ) ? ( $value === 'on' ? 'enabled' : 'disabled' ) : (int) $value;
162 - $this->options[ $key ] = $sanitized_value;
178 + self::$options[ $key ] = $sanitized_value;
163 179 }
164 180 }
165 181 }
166 -
167 - add_action( 'init', [ $this, 'register_settings' ] );
168 182 }
169 183
170 184 /**
171 185 * Check if the user is connected to Optimole.
@@ -195,9 +209,9 @@
195 209 if ( ! $this->is_allowed( $key ) ) {
196 210 return null;
197 211 }
198 212
199 - return isset( $this->options[ $key ] ) ? $this->options[ $key ] : '';
213 + return isset( self::$options[ $key ] ) ? self::$options[ $key ] : '';
200 214 }
201 215
202 216 /**
203 217 * Check if key is allowed.
@@ -213,8 +227,14 @@
213 227 /**
214 228 * Auto connect action.
215 229 */
216 230 public function auto_connect() {
231 +
232 + /**
233 + * Connect rest request.
234 + *
235 + * @var WP_REST_Request<array{api_key: string, application?: string}>
236 + */
217 237 $request = new WP_REST_Request( 'POST' );
218 238 $request->set_param( 'api_key', constant( 'OPTIML_API_KEY' ) );
219 239 Optml_Main::instance()->rest->connect( $request );
220 240
@@ -229,9 +249,11 @@
229 249 *
230 250 * @return array
231 251 */
232 252 public function parse_settings( $new_settings ) {
233 - $sanitized = [];
253 + $sanitized = [];
254 + $sanitized_value = '';
255 +
234 256 foreach ( $new_settings as $key => $value ) {
235 257 switch ( $key ) {
236 258 case 'admin_bar_item':
237 259 case 'lazyload':
@@ -244,9 +266,8 @@
244 266 case 'limit_dimensions':
245 267 case 'resize_smart':
246 268 case 'bg_replacer':
247 269 case 'video_lazyload':
248 - case 'report_script':
249 270 case 'avif':
250 271 case 'offload_media':
251 272 case 'cloud_images':
252 273 case 'autoquality':
@@ -259,27 +280,41 @@
259 280 case 'banner_frontend':
260 281 case 'offloading_status':
261 282 case 'rollback_status':
262 283 case 'best_format':
284 + case 'offload_limit_reached':
285 + case 'show_badge_icon':
263 286 $sanitized_value = $this->to_map_values( $value, [ 'enabled', 'disabled' ], 'enabled' );
264 287 break;
265 - case 'max_width':
266 - case 'max_height':
288 + case 'offload_limit':
289 + $sanitized_value = absint( $value );
290 + break;
267 291 case 'limit_height':
268 292 case 'limit_width':
269 293 $sanitized_value = $this->to_bound_integer( $value, 100, 5000 );
270 294 break;
271 295 case 'quality':
272 - $sanitized_value = $this->to_bound_integer( $value, 1, 100 );
296 + if ( 'mauto' !== $value ) {
297 + $sanitized_value = $this->to_bound_integer( $value, 50, 100 );
298 + }
273 299 break;
274 300 case 'wm_id':
275 301 $sanitized_value = intval( $value );
276 302 break;
303 + case 'show_offload_finish_notice':
304 + $sanitized_value = $this->to_map_values( $value, [ 'offload', 'rollback' ], '' );
305 + break;
277 306 case 'cache_buster_assets':
278 307 case 'cache_buster_images':
279 308 case 'cache_buster':
280 309 $sanitized_value = is_string( $value ) ? sanitize_text_field( $value ) : '';
281 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;
282 317 case 'cloud_sites':
283 318 $current_sites = $this->get( 'cloud_sites' );
284 319 $sanitized_value = array_replace_recursive( $current_sites, $value );
285 320 if ( isset( $value['all'] ) && $value['all'] === 'true' ) {
@@ -286,9 +321,9 @@
286 321 $sanitized_value = [ 'all' => 'true' ];
287 322 }
288 323 break;
289 324 case 'defined_image_sizes':
290 - $current_sizes = $this->get( 'defined_image_sizes' );
325 + $current_sizes = $this->get( 'defined_image_sizes' );
291 326 foreach ( $value as $size_name => $size_value ) {
292 327 if ( $size_value === 'remove' ) {
293 328 unset( $current_sizes[ $size_name ] );
294 329 unset( $value[ $size_name ] );
@@ -312,8 +347,9 @@
312 347 }
313 348 break;
314 349 case 'watchers':
315 350 case 'placeholder_color':
351 + case 'transfer_status':
316 352 $sanitized_value = sanitize_text_field( $value );
317 353 break;
318 354 case 'skip_lazyload_images':
319 355 $sanitized_value = $this->to_bound_integer( $value, 0, 100 );
@@ -327,21 +363,24 @@
327 363 case 'wm_position':
328 364 $sanitized_value = $this->to_map_values(
329 365 $value,
330 366 [
331 - Optml_Resize::GRAVITY_NORTH,
332 - Optml_Resize::GRAVITY_NORTH_EAST,
333 - Optml_Resize::GRAVITY_NORTH_WEST,
334 - Optml_Resize::GRAVITY_CENTER,
335 - Optml_Resize::GRAVITY_EAST,
336 - Optml_Resize::GRAVITY_WEST,
337 - Optml_Resize::GRAVITY_SOUTH_EAST,
338 - Optml_Resize::GRAVITY_SOUTH,
339 - 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,
340 376 ],
341 - Optml_Resize::GRAVITY_SOUTH_EAST
377 + Position::SOUTH_EAST
342 378 );
343 379 break;
380 + case 'badge_position':
381 + $sanitized_value = $this->to_map_values( $value, [ 'left', 'right' ], 'right' );
382 + break;
344 383 default:
345 384 $sanitized_value = '';
346 385 break;
347 386
@@ -400,15 +439,16 @@
400 439 if ( ! $this->is_main_mu_site() ) {
401 440 return false;
402 441 }
403 442
404 - $opts = $this->options;
443 + $opts = self::$options;
405 444 $opts['banner_frontend'] = $value ? 'enabled' : 'disabled';
406 445
407 446 $update = update_option( $this->namespace, $opts, false );
408 447
409 448 if ( $update ) {
410 - $this->options = $opts;
449 + self::$options = $opts;
450 + $this->set_settings_cache( 'banner_frontend', $opts['banner_frontend'] );
411 451 }
412 452
413 453 return $update;
414 454 }
@@ -428,9 +468,9 @@
428 468
429 469 if ( ! $this->is_main_mu_site() ) {
430 470 return false;
431 471 }
432 - $opt = $this->options;
472 + $opt = self::$options;
433 473
434 474 if ( $key === 'banner_frontend' ) {
435 475 $api = new Optml_Api();
436 476 $service_data = $this->get( 'service_data' );
@@ -438,14 +478,39 @@
438 478 $response = $api->update_extra_visits( $opt['api_key'], $value, $application );
439 479 }
440 480
441 481 $opt[ $key ] = $value;
482 +
442 483 $update = update_option( $this->namespace, $opt, false );
484 +
443 485 if ( $update ) {
444 - $this->options = $opt;
486 + self::$options = $opt;
487 + $this->set_settings_cache( $key, $value );
445 488 }
446 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 + */
447 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 );
448 513 }
449 514 return $update;
450 515 }
451 516
@@ -456,9 +521,9 @@
456 521 */
457 522 private function is_main_mu_site() {
458 523 // If we try to update from a website which is not the main OPTML blog, bail.
459 524 if ( defined( 'OPTIML_ENABLED_MU' ) && constant( 'OPTIML_ENABLED_MU' ) && defined( 'OPTIML_MU_SITE_ID' ) && constant( 'OPTIML_MU_SITE_ID' ) &&
460 - intval( constant( 'OPTIML_MU_SITE_ID' ) ) !== get_current_blog_id()
525 + intval( constant( 'OPTIML_MU_SITE_ID' ) ) !== get_current_blog_id()
461 526 ) {
462 527 return false;
463 528 }
464 529
@@ -470,8 +535,12 @@
470 535 *
471 536 * @return array Site settings.
472 537 */
473 538 public function get_site_settings() {
539 + if ( self::$site_settings_cache !== null ) {
540 + return self::$site_settings_cache;
541 + }
542 +
474 543 $service_data = $this->get( 'service_data' );
475 544 $whitelist = [];
476 545 if ( isset( $service_data['whitelist'] ) ) {
477 546 $whitelist = $service_data['whitelist'];
@@ -476,50 +545,54 @@
476 545 if ( isset( $service_data['whitelist'] ) ) {
477 546 $whitelist = $service_data['whitelist'];
478 547 }
479 548
480 - return [
481 - 'quality' => $this->get_quality(),
482 - 'admin_bar_item' => $this->get( 'admin_bar_item' ),
483 - 'lazyload' => $this->get( 'lazyload' ),
484 - 'network_optimization' => $this->get( 'network_optimization' ),
485 - 'retina_images' => $this->get( 'retina_images' ),
486 - 'limit_dimensions' => $this->get( 'limit_dimensions' ),
487 - 'limit_height' => $this->get( 'limit_height' ),
488 - 'limit_width' => $this->get( 'limit_width' ),
489 - 'lazyload_placeholder' => $this->get( 'lazyload_placeholder' ),
490 - 'skip_lazyload_images' => $this->get( 'skip_lazyload_images' ),
491 - 'bg_replacer' => $this->get( 'bg_replacer' ),
492 - 'video_lazyload' => $this->get( 'video_lazyload' ),
493 - 'resize_smart' => $this->get( 'resize_smart' ),
494 - 'no_script' => $this->get( 'no_script' ),
495 - 'image_replacer' => $this->get( 'image_replacer' ),
496 - 'cdn' => $this->get( 'cdn' ),
497 - 'max_width' => $this->get( 'max_width' ),
498 - 'max_height' => $this->get( 'max_height' ),
499 - 'filters' => $this->get_filters(),
500 - 'cloud_sites' => $this->get( 'cloud_sites' ),
501 - 'defined_image_sizes' => $this->get( 'defined_image_sizes' ),
502 - 'watchers' => $this->get_watchers(),
503 - 'watermark' => $this->get_watermark(),
504 - 'img_to_video' => $this->get( 'img_to_video' ),
505 - 'scale' => $this->get( 'scale' ),
506 - 'css_minify' => $this->get( 'css_minify' ),
507 - 'js_minify' => $this->get( 'js_minify' ),
508 - 'native_lazyload' => $this->get( 'native_lazyload' ),
509 - 'report_script' => $this->get( 'report_script' ),
510 - 'avif' => $this->get( 'avif' ),
511 - 'autoquality' => $this->get( 'autoquality' ),
512 - 'offload_media' => $this->get( 'offload_media' ),
513 - 'cloud_images' => $this->get( 'cloud_images' ),
514 - 'strip_metadata' => $this->get( 'strip_metadata' ),
515 - 'whitelist_domains' => $whitelist,
516 - 'banner_frontend' => $this->get( 'banner_frontend' ),
517 - 'offloading_status' => $this->get( 'offloading_status' ),
518 - 'rollback_status' => $this->get( 'rollback_status' ),
519 - 'best_format' => $this->get( 'best_format' ),
520 - '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' ),
521 593 ];
594 + return self::$site_settings_cache;
522 595 }
523 596
524 597 /**
525 598 * Return quality factor.
@@ -553,9 +626,8 @@
553 626 */
554 627 public function get_watchers() {
555 628
556 629 return $this->get( 'watchers' );
557 -
558 630 }
559 631
560 632 /**
561 633 * Return an watermark array.
@@ -589,10 +661,27 @@
589 661 */
590 662 public function is_best_format() {
591 663 return $this->get( 'best_format' ) === 'enabled';
592 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 + }
593 673
594 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 + /**
595 684 * Get numeric quality used by the service.
596 685 *
597 686 * @return int Numeric quality.
598 687 */
@@ -652,16 +741,16 @@
652 741 if ( ! isset( $service_data['cdn_key'] ) ) {
653 742 return '';
654 743 }
655 744
745 + if ( defined( 'OPTML_CUSTOM_DOMAIN' ) && constant( 'OPTML_CUSTOM_DOMAIN' ) ) {
746 + return parse_url( strtolower( OPTML_CUSTOM_DOMAIN ), PHP_URL_HOST );
747 + }
748 +
656 749 if ( isset( $service_data['is_cname_assigned'] ) && $service_data['is_cname_assigned'] === 'yes' && ! empty( $service_data['domain'] ) ) {
657 750 return strtolower( $service_data['domain'] );
658 751 }
659 752
660 - if ( defined( 'OPTML_CUSTOM_DOMAIN' ) && constant( 'OPTML_CUSTOM_DOMAIN' ) ) {
661 - return parse_url( strtolower( OPTML_CUSTOM_DOMAIN ), PHP_URL_HOST );
662 - }
663 -
664 753 return sprintf(
665 754 '%s.%s',
666 755 strtolower( $service_data['cdn_key'] ),
667 756 Optml_Config::$base_domain
@@ -674,17 +763,21 @@
674 763 * @return bool Reset action status.
675 764 */
676 765 public function reset() {
677 766 $reset_schema = $this->default_schema;
678 - $reset_schema['filters'] = $this->options['filters'];
767 + $reset_schema['filters'] = self::$options['filters'];
679 768
680 769 $update = update_option( $this->namespace, $reset_schema );
681 770 if ( $update ) {
682 - $this->options = $reset_schema;
771 + self::$options = $reset_schema;
772 + $this->set_settings_cache( 'filters', $reset_schema['filters'] );
683 773 }
774 + wp_unschedule_hook( Optml_Admin::SYNC_CRON );
775 + wp_unschedule_hook( Optml_Admin::ENRICH_CRON );
684 776
685 777 return $update;
686 778 }
779 +
687 780 /**
688 781 * Get raw settings value.
689 782 *
690 783 * @return array
@@ -689,28 +782,13 @@
689 782 *
690 783 * @return array
691 784 */
692 785 public function get_raw_settings() {
693 - return get_option( $this->namespace, false );
786 + $raw_settings = get_option( $this->namespace, [] );
787 +
788 + return is_array( $raw_settings ) ? $raw_settings : [];
694 789 }
695 790
696 - /**
697 - * Get settings for CSAT.
698 - *
699 - * @return void
700 - */
701 - public function register_settings() {
702 - register_setting(
703 - 'optml_settings',
704 - 'optml_csat',
705 - [
706 - 'type' => 'string',
707 - 'sanitize_callback' => 'sanitize_text_field',
708 - 'show_in_rest' => true,
709 - 'default' => '{}',
710 - ]
711 - );
712 - }
713 791
714 792 /**
715 793 * Clear cache.
716 794 *
@@ -718,21 +796,25 @@
718 796 *
719 797 * @return string|WP_Error
720 798 */
721 799 public function clear_cache( $type = '' ) {
722 - $token = $this->get( 'cache_buster' );
800 + $token = $this->get( 'cache_buster' );
723 801 $token_images = $this->get( 'cache_buster_images' );
724 802
725 - if ( ! empty( $token_images ) ) {
726 - $token = $token_images;
727 - }
728 -
729 - 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' ) {
730 810 $token = $this->get( 'cache_buster_assets' );
811 + } else {
812 + $token = $individual[ crc32( $type ) ] ?? $token_images ?: $token;
731 813 }
732 814
733 - $request = new Optml_Api();
734 - $data = $request->get_cache_token( $token, $type );
815 + $request = new Optml_Api();
816 + $data = $request->get_cache_token( $token, $type );
735 817
736 818 if ( $data === false || is_wp_error( $data ) || empty( $data ) || ! isset( $data['token'] ) ) {
737 819 $extra = '';
738 820
@@ -741,21 +823,91 @@
741 823 * Error from api.
742 824 *
743 825 * @var WP_Error $data Error object.
744 826 */
745 - $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() );
746 828 }
747 829
748 830 return new WP_Error( 'optimole_cache_buster_error', __( 'Can not get new token from Optimole service', 'optimole-wp' ) . $extra );
749 831 }
750 832
751 - 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' ) {
752 839 set_transient( 'optml_cache_lock_assets', 'yes', 5 * MINUTE_IN_SECONDS );
753 840 $this->update( 'cache_buster_assets', $data['token'] );
754 841 } else {
755 - set_transient( 'optml_cache_lock', 'yes', 5 * MINUTE_IN_SECONDS );
756 - $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 );
757 844 }
758 845
759 846 return $data['token'];
847 + }
848 +
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 + /**
876 + * Utility to check if offload is enabled.
877 + *
878 + * @return bool
879 + */
880 + public function is_offload_enabled() {
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 + }
760 912 }
761 913 }