PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / 4.2.13
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization v4.2.13
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 3.12.1 All 134 releases
optimole-wp / inc / settings.php

settings.php in Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization 4.2.13, at inc/settings.php

914 lines 26.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use Optimole\Sdk\ValueObject\Position;
4
5 /**
6 * Class Optml_Settings.
7 */
8 class Optml_Settings {
9 use Optml_Normalizer;
10
11 const FILTER_EXT = 'extension';
12 const FILTER_URL = 'page_url';
13 const FILTER_URL_MATCH = 'page_url_match';
14 const FILTER_FILENAME = 'filename';
15 const FILTER_CLASS = 'class';
16 const FILTER_TYPE_LAZYLOAD = 'lazyload';
17 const FILTER_TYPE_OPTIMIZE = 'optimize';
18 const OPTML_USER_EMAIL = 'optml_user_email';
19 const INDIVIDUAL_CACHE_TOKENS_KEY = '_optml_cache_tokens_individual';
20 /**
21 * Holds an array of possible settings to alter via wp cli or wp-config constants.
22 *
23 * @var array Whitelisted settings.
24 */
25 public static $whitelisted_settings = [
26 'image_replacer' => 'bool',
27 'quality' => 'int',
28 'lazyload' => 'bool',
29 'lazyload_placeholder' => 'bool',
30 'network_optimization' => 'bool',
31 'autoquality' => 'bool',
32 'img_to_video' => 'bool',
33 'resize_smart' => 'bool',
34 'retina_images' => 'bool',
35 'native_lazyload' => 'bool',
36 'video_lazyload' => 'bool',
37 'bg_replacer' => 'bool',
38 'scale' => 'bool',
39 'cdn' => 'bool',
40 ];
41 /**
42 * Holds the status of the auto connect hook.
43 *
44 * @var boolean Whether or not the auto connect action is hooked.
45 */
46 private static $auto_connect_hooked = false;
47
48 /**
49 * Default settings schema.
50 *
51 * @var array Settings schema.
52 */
53 private $default_schema = [
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',
108 ];
109 /**
110 * Option key.
111 *
112 * @var string Option name.
113 */
114 private $namespace;
115 /**
116 * Holds all options from db.
117 *
118 * @var array All options.
119 */
120 private static $options;
121
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 /**
130 * Optml_Settings constructor.
131 */
132 public function __construct() {
133 $this->default_schema['cloud_sites'] = $this->get_cloud_sites_whitelist_default();
134
135 $this->namespace = OPTML_NAMESPACE . '_settings';
136 $this->default_schema = apply_filters( 'optml_default_settings', $this->default_schema );
137 self::$options = wp_parse_args( get_option( $this->namespace, $this->default_schema ), $this->default_schema );
138
139 if ( defined( 'OPTIML_ENABLED_MU' ) && defined( 'OPTIML_MU_SITE_ID' ) && $this->to_boolean( constant( 'OPTIML_ENABLED_MU' ) ) && constant( 'OPTIML_MU_SITE_ID' ) ) {
140 switch_to_blog( constant( 'OPTIML_MU_SITE_ID' ) );
141 self::$options = wp_parse_args( get_option( $this->namespace, $this->default_schema ), $this->default_schema );
142 restore_current_blog();
143 }
144
145 if ( defined( 'OPTIML_USE_ENV' ) && constant( 'OPTIML_USE_ENV' ) && $this->to_boolean( constant( 'OPTIML_USE_ENV' ) ) ) {
146
147 if ( defined( 'OPTIML_API_KEY' )
148 && constant( 'OPTIML_API_KEY' ) !== ''
149 ) {
150 if ( ! $this->is_connected() && ! self::$auto_connect_hooked ) {
151 self::$auto_connect_hooked = true;
152 add_action(
153 'plugins_loaded',
154 [ $this, 'auto_connect' ]
155 );
156 }
157 }
158
159 foreach ( self::$whitelisted_settings as $key => $type ) {
160 $env_key = 'OPTIML_' . strtoupper( $key );
161 if ( defined( $env_key ) && constant( $env_key ) ) {
162 $value = constant( $env_key );
163 if ( $type === 'bool' && ( (string) $value === '' || ! in_array(
164 $value,
165 [
166 'on',
167 'off',
168 ],
169 true
170 ) ) ) {
171 continue;
172 }
173
174 if ( $type === 'int' && ( (string) $value === '' || (int) $value > 100 || (int) $value < 0 ) ) {
175 continue;
176 }
177 $sanitized_value = ( $type === 'bool' ) ? ( $value === 'on' ? 'enabled' : 'disabled' ) : (int) $value;
178 self::$options[ $key ] = $sanitized_value;
179 }
180 }
181 }
182 }
183
184 /**
185 * Check if the user is connected to Optimole.
186 *
187 * @return bool Connection status.
188 */
189 public function is_connected() {
190 $service_data = $this->get( 'service_data' );
191 if ( ! isset( $service_data['cdn_key'] ) ) {
192 return false;
193 }
194 if ( empty( $service_data ['cdn_key'] ) || empty( $service_data['cdn_secret'] ) ) {
195 return false;
196 }
197
198 return true;
199 }
200
201 /**
202 * Get setting value by key.
203 *
204 * @param string $key Key to search against.
205 *
206 * @return mixed|null Setting value.
207 */
208 public function get( $key ) {
209 if ( ! $this->is_allowed( $key ) ) {
210 return null;
211 }
212
213 return isset( self::$options[ $key ] ) ? self::$options[ $key ] : '';
214 }
215
216 /**
217 * Check if key is allowed.
218 *
219 * @param string $key Is key allowed or not.
220 *
221 * @return bool Is key allowed or not.
222 */
223 private function is_allowed( $key ) {
224 return isset( $this->default_schema[ $key ] );
225 }
226
227 /**
228 * Auto connect action.
229 */
230 public function auto_connect() {
231
232 /**
233 * Connect rest request.
234 *
235 * @var WP_REST_Request<array{api_key: string, application?: string}>
236 */
237 $request = new WP_REST_Request( 'POST' );
238 $request->set_param( 'api_key', constant( 'OPTIML_API_KEY' ) );
239 Optml_Main::instance()->rest->connect( $request );
240
241 remove_action( 'plugins_loaded', [ $this, 'auto_connect' ] );
242 self::$auto_connect_hooked = false;
243 }
244
245 /**
246 * Process settings.
247 *
248 * @param array $new_settings List of settings.
249 *
250 * @return array
251 */
252 public function parse_settings( $new_settings ) {
253 $sanitized = [];
254 $sanitized_value = '';
255
256 foreach ( $new_settings as $key => $value ) {
257 switch ( $key ) {
258 case 'admin_bar_item':
259 case 'lazyload':
260 case 'scale':
261 case 'image_replacer':
262 case 'cdn':
263 case 'network_optimization':
264 case 'lazyload_placeholder':
265 case 'retina_images':
266 case 'limit_dimensions':
267 case 'resize_smart':
268 case 'bg_replacer':
269 case 'video_lazyload':
270 case 'avif':
271 case 'offload_media':
272 case 'cloud_images':
273 case 'autoquality':
274 case 'img_to_video':
275 case 'css_minify':
276 case 'js_minify':
277 case 'native_lazyload':
278 case 'strip_metadata':
279 case 'no_script':
280 case 'banner_frontend':
281 case 'offloading_status':
282 case 'rollback_status':
283 case 'best_format':
284 case 'offload_limit_reached':
285 case 'show_badge_icon':
286 $sanitized_value = $this->to_map_values( $value, [ 'enabled', 'disabled' ], 'enabled' );
287 break;
288 case 'offload_limit':
289 $sanitized_value = absint( $value );
290 break;
291 case 'limit_height':
292 case 'limit_width':
293 $sanitized_value = $this->to_bound_integer( $value, 100, 5000 );
294 break;
295 case 'quality':
296 if ( 'mauto' !== $value ) {
297 $sanitized_value = $this->to_bound_integer( $value, 50, 100 );
298 }
299 break;
300 case 'wm_id':
301 $sanitized_value = intval( $value );
302 break;
303 case 'show_offload_finish_notice':
304 $sanitized_value = $this->to_map_values( $value, [ 'offload', 'rollback' ], '' );
305 break;
306 case 'cache_buster_assets':
307 case 'cache_buster_images':
308 case 'cache_buster':
309 $sanitized_value = is_string( $value ) ? sanitize_text_field( $value ) : '';
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;
317 case 'cloud_sites':
318 $current_sites = $this->get( 'cloud_sites' );
319 $sanitized_value = array_replace_recursive( $current_sites, $value );
320 if ( isset( $value['all'] ) && $value['all'] === 'true' ) {
321 $sanitized_value = [ 'all' => 'true' ];
322 }
323 break;
324 case 'defined_image_sizes':
325 $current_sizes = $this->get( 'defined_image_sizes' );
326 foreach ( $value as $size_name => $size_value ) {
327 if ( $size_value === 'remove' ) {
328 unset( $current_sizes[ $size_name ] );
329 unset( $value[ $size_name ] );
330 }
331 }
332 $sanitized_value = array_replace_recursive( $current_sizes, $value );
333 break;
334 case 'filters':
335 $current_filters = $this->get_filters();
336 $sanitized_value = array_replace_recursive( $current_filters, $value );
337 // Remove falsy vars.
338 foreach ( $sanitized_value as $filter_type => $filter_values ) {
339 foreach ( $filter_values as $filter_rule_type => $filter_rules_value ) {
340 $sanitized_value[ $filter_type ][ $filter_rule_type ] = array_filter(
341 $filter_rules_value,
342 function ( $value ) {
343 return ( $value !== 'false' && $value !== false );
344 }
345 );
346 }
347 }
348 break;
349 case 'watchers':
350 case 'placeholder_color':
351 case 'transfer_status':
352 $sanitized_value = sanitize_text_field( $value );
353 break;
354 case 'skip_lazyload_images':
355 $sanitized_value = $this->to_bound_integer( $value, 0, 100 );
356 break;
357 case 'wm_opacity':
358 case 'wm_scale':
359 case 'wm_x':
360 case 'wm_y':
361 $sanitized_value = floatval( $value );
362 break;
363 case 'wm_position':
364 $sanitized_value = $this->to_map_values(
365 $value,
366 [
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,
376 ],
377 Position::SOUTH_EAST
378 );
379 break;
380 case 'badge_position':
381 $sanitized_value = $this->to_map_values( $value, [ 'left', 'right' ], 'right' );
382 break;
383 default:
384 $sanitized_value = '';
385 break;
386
387 }
388
389 $sanitized[ $key ] = $sanitized_value;
390 $this->update( $key, $sanitized_value );
391 }
392
393 return $sanitized;
394 }
395
396 /**
397 * Return filter definitions.
398 *
399 * @return mixed|null Filter values.
400 */
401 public function get_filters() {
402
403 $filters = $this->get( 'filters' );
404 if ( ! isset( $filters[ self::FILTER_TYPE_LAZYLOAD ] ) ) {
405 $filters[ self::FILTER_TYPE_LAZYLOAD ] = [];
406 }
407 if ( ! isset( $filters[ self::FILTER_TYPE_OPTIMIZE ] ) ) {
408 $filters[ self::FILTER_TYPE_OPTIMIZE ] = [];
409 }
410 foreach ( $filters as $filter_key => $filter_rules ) {
411 if ( ! isset( $filter_rules[ self::FILTER_EXT ] ) ) {
412 $filters[ $filter_key ][ self::FILTER_EXT ] = [];
413 }
414 if ( ! isset( $filter_rules[ self::FILTER_FILENAME ] ) ) {
415 $filters[ $filter_key ][ self::FILTER_FILENAME ] = [];
416 }
417 if ( ! isset( $filter_rules[ self::FILTER_URL ] ) ) {
418 $filters[ $filter_key ][ self::FILTER_URL ] = [];
419 }
420 if ( ! isset( $filter_rules[ self::FILTER_URL_MATCH ] ) ) {
421 $filters[ $filter_key ][ self::FILTER_URL_MATCH ] = [];
422 }
423 if ( ! isset( $filter_rules[ self::FILTER_CLASS ] ) ) {
424 $filters[ $filter_key ][ self::FILTER_CLASS ] = [];
425 }
426 }
427
428 return $filters;
429 }
430
431 /**
432 * Update frontend banner setting from remote.
433 *
434 * @param bool $value Value.
435 *
436 * @return bool
437 */
438 public function update_frontend_banner_from_remote( $value ) {
439 if ( ! $this->is_main_mu_site() ) {
440 return false;
441 }
442
443 $opts = self::$options;
444 $opts['banner_frontend'] = $value ? 'enabled' : 'disabled';
445
446 $update = update_option( $this->namespace, $opts, false );
447
448 if ( $update ) {
449 self::$options = $opts;
450 $this->set_settings_cache( 'banner_frontend', $opts['banner_frontend'] );
451 }
452
453 return $update;
454 }
455
456 /**
457 * Update settings.
458 *
459 * @param string $key Settings key.
460 * @param mixed $value Settings value.
461 *
462 * @return bool Update result.
463 */
464 public function update( $key, $value ) {
465 if ( ! $this->is_allowed( $key ) ) {
466 return false;
467 }
468
469 if ( ! $this->is_main_mu_site() ) {
470 return false;
471 }
472 $opt = self::$options;
473
474 if ( $key === 'banner_frontend' ) {
475 $api = new Optml_Api();
476 $service_data = $this->get( 'service_data' );
477 $application = isset( $service_data['cdn_key'] ) ? $service_data['cdn_key'] : '';
478 $response = $api->update_extra_visits( $opt['api_key'], $value, $application );
479 }
480
481 $opt[ $key ] = $value;
482
483 $update = update_option( $this->namespace, $opt, false );
484
485 if ( $update ) {
486 self::$options = $opt;
487 $this->set_settings_cache( $key, $value );
488 }
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 */
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 );
513 }
514 return $update;
515 }
516
517 /**
518 * Check that we're on the main OPTML blog.
519 *
520 * @return bool
521 */
522 private function is_main_mu_site() {
523 // If we try to update from a website which is not the main OPTML blog, bail.
524 if ( defined( 'OPTIML_ENABLED_MU' ) && constant( 'OPTIML_ENABLED_MU' ) && defined( 'OPTIML_MU_SITE_ID' ) && constant( 'OPTIML_MU_SITE_ID' ) &&
525 intval( constant( 'OPTIML_MU_SITE_ID' ) ) !== get_current_blog_id()
526 ) {
527 return false;
528 }
529
530 return true;
531 }
532
533 /**
534 * Return site settings.
535 *
536 * @return array Site settings.
537 */
538 public function get_site_settings() {
539 if ( self::$site_settings_cache !== null ) {
540 return self::$site_settings_cache;
541 }
542
543 $service_data = $this->get( 'service_data' );
544 $whitelist = [];
545 if ( isset( $service_data['whitelist'] ) ) {
546 $whitelist = $service_data['whitelist'];
547 }
548
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' ),
593 ];
594 return self::$site_settings_cache;
595 }
596
597 /**
598 * Return quality factor.
599 *
600 * @return string Quality factor.
601 */
602 public function get_quality() {
603 $quality = $this->get( 'quality' );
604 if ( $this->get( 'autoquality' ) === 'enabled' ) {
605 return 'mauto';
606 }
607 // Legacy compat.
608 if ( $quality === 'low' ) {
609 return 'high_c';
610 }
611 if ( $quality === 'medium' ) {
612 return 'medium_c';
613 }
614
615 if ( $quality === 'high' ) {
616 return 'low_c';
617 }
618
619 return $quality;
620 }
621
622 /**
623 * Return filter definitions.
624 *
625 * @return mixed|null Filter values.
626 */
627 public function get_watchers() {
628
629 return $this->get( 'watchers' );
630 }
631
632 /**
633 * Return an watermark array.
634 *
635 * @return array
636 */
637 public function get_watermark() {
638 return [
639 'id' => $this->get( 'wm_id' ),
640 'opacity' => $this->get( 'wm_opacity' ),
641 'position' => $this->get( 'wm_position' ),
642 'x_offset' => $this->get( 'wm_x' ),
643 'y_offset' => $this->get( 'wm_y' ),
644 'scale' => $this->get( 'wm_scale' ),
645 ];
646 }
647
648 /**
649 * Check if smart cropping is enabled.
650 *
651 * @return bool Is smart cropping enabled.
652 */
653 public function is_smart_cropping() {
654 return $this->get( 'resize_smart' ) === 'enabled';
655 }
656
657 /**
658 * Check if best format is enabled.
659 *
660 * @return bool
661 */
662 public function is_best_format() {
663 return $this->get( 'best_format' ) === 'enabled';
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 }
673
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 /**
684 * Get numeric quality used by the service.
685 *
686 * @return int Numeric quality.
687 */
688 public function get_numeric_quality() {
689 $value = $this->get_quality();
690
691 return (int) $this->to_accepted_quality( $value );
692 }
693
694 /**
695 * Check if replacer is enabled.
696 *
697 * @return bool Replacer enabled
698 */
699 public function is_enabled() {
700 $status = $this->get( 'image_replacer' );
701 $service_data = $this->get( 'service_data' );
702 if ( empty( $service_data ) ) {
703 return false;
704 }
705 if ( isset( $service_data['status'] ) && $service_data['status'] === 'inactive' ) {
706 return false;
707 }
708
709 return $this->to_boolean( $status );
710 }
711
712 /**
713 * Check if lazyload is enabled.
714 *
715 * @return bool Lazyload enabled
716 */
717 public function use_lazyload() {
718 $status = $this->get( 'lazyload' );
719
720 return $this->to_boolean( $status );
721 }
722
723 /**
724 * Check if replacer is enabled.
725 *
726 * @return bool Replacer enabled
727 */
728 public function use_cdn() {
729 $status = $this->get( 'cdn' );
730
731 return $this->to_boolean( $status );
732 }
733
734 /**
735 * Return cdn url.
736 *
737 * @return string CDN url.
738 */
739 public function get_cdn_url() {
740 $service_data = $this->get( 'service_data' );
741 if ( ! isset( $service_data['cdn_key'] ) ) {
742 return '';
743 }
744
745 if ( defined( 'OPTML_CUSTOM_DOMAIN' ) && constant( 'OPTML_CUSTOM_DOMAIN' ) ) {
746 return parse_url( strtolower( OPTML_CUSTOM_DOMAIN ), PHP_URL_HOST );
747 }
748
749 if ( isset( $service_data['is_cname_assigned'] ) && $service_data['is_cname_assigned'] === 'yes' && ! empty( $service_data['domain'] ) ) {
750 return strtolower( $service_data['domain'] );
751 }
752
753 return sprintf(
754 '%s.%s',
755 strtolower( $service_data['cdn_key'] ),
756 Optml_Config::$base_domain
757 );
758 }
759
760 /**
761 * Reset options to defaults.
762 *
763 * @return bool Reset action status.
764 */
765 public function reset() {
766 $reset_schema = $this->default_schema;
767 $reset_schema['filters'] = self::$options['filters'];
768
769 $update = update_option( $this->namespace, $reset_schema );
770 if ( $update ) {
771 self::$options = $reset_schema;
772 $this->set_settings_cache( 'filters', $reset_schema['filters'] );
773 }
774 wp_unschedule_hook( Optml_Admin::SYNC_CRON );
775 wp_unschedule_hook( Optml_Admin::ENRICH_CRON );
776
777 return $update;
778 }
779
780 /**
781 * Get raw settings value.
782 *
783 * @return array
784 */
785 public function get_raw_settings() {
786 $raw_settings = get_option( $this->namespace, [] );
787
788 return is_array( $raw_settings ) ? $raw_settings : [];
789 }
790
791
792 /**
793 * Clear cache.
794 *
795 * @param string $type Cache type.
796 *
797 * @return string|WP_Error
798 */
799 public function clear_cache( $type = '' ) {
800 $token = $this->get( 'cache_buster' );
801 $token_images = $this->get( 'cache_buster_images' );
802
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' ) {
810 $token = $this->get( 'cache_buster_assets' );
811 } else {
812 $token = $individual[ crc32( $type ) ] ?? $token_images ?: $token;
813 }
814
815 $request = new Optml_Api();
816 $data = $request->get_cache_token( $token, $type );
817
818 if ( $data === false || is_wp_error( $data ) || empty( $data ) || ! isset( $data['token'] ) ) {
819 $extra = '';
820
821 if ( is_wp_error( $data ) ) {
822 /**
823 * Error from api.
824 *
825 * @var WP_Error $data Error object.
826 */
827 $extra = sprintf( /* translators: Error details */ __( '. ERROR details: %s', 'optimole-wp' ), $data->get_error_message() );
828 }
829
830 return new WP_Error( 'optimole_cache_buster_error', __( 'Can not get new token from Optimole service', 'optimole-wp' ) . $extra );
831 }
832
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' ) {
839 set_transient( 'optml_cache_lock_assets', 'yes', 5 * MINUTE_IN_SECONDS );
840 $this->update( 'cache_buster_assets', $data['token'] );
841 } else {
842 $individual[ crc32( $type ) ] = $data['token'];
843 set_transient( self::INDIVIDUAL_CACHE_TOKENS_KEY, $individual, 6 * HOUR_IN_SECONDS );
844 }
845
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 }
912 }
913 }
914