PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / 3.1.1
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization v3.1.1
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 3.1.1, at inc/settings.php

563 lines 15.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class Optml_Settings.
5 */
6 class Optml_Settings {
7 use Optml_Normalizer;
8 const FILTER_EXT = 'extension';
9 const FILTER_URL = 'page_url';
10 const FILTER_FILENAME = 'filename';
11 const FILTER_CLASS = 'class';
12 const FILTER_TYPE_LAZYLOAD = 'lazyload';
13 const FILTER_TYPE_OPTIMIZE = 'optimize';
14 /**
15 * Holds an array of possible settings to alter via wp cli or wp-config constants.
16 *
17 * @var array Whitelisted settings.
18 */
19 public static $whitelisted_settings = [
20 'image_replacer' => 'bool',
21 'quality' => 'int',
22 'lazyload' => 'bool',
23 'lazyload_placeholder' => 'bool',
24 'network_optimization' => 'bool',
25 'img_to_video' => 'bool',
26 'resize_smart' => 'bool',
27 'retina_images' => 'bool',
28 'native_lazyload' => 'bool',
29 'video_lazyload' => 'bool',
30 'bg_replacer' => 'bool',
31 'scale' => 'bool',
32 'cdn' => 'bool',
33 ];
34 /**
35 * Default settings schema.
36 *
37 * @var array Settings schema.
38 */
39 private $default_schema = [
40 'api_key' => '',
41 'service_data' => '',
42 'cache_buster' => '',
43 'cdn' => 'disabled',
44 'max_height' => 1500,
45 'max_width' => 2000,
46 'admin_bar_item' => 'enabled',
47 'lazyload' => 'disabled',
48 'scale' => 'disabled',
49 'network_optimization' => 'disabled',
50 'lazyload_placeholder' => 'disabled',
51 'bg_replacer' => 'enabled',
52 'video_lazyload' => 'disabled',
53 'retina_images' => 'disabled',
54 'resize_smart' => 'disabled',
55 'filters' => [],
56 'cloud_sites' => [ 'all' => 'true' ],
57 'watchers' => '',
58 'quality' => 'auto',
59 'wm_id' => - 1,
60 'wm_opacity' => 1,
61 'wm_position' => Optml_Resize::GRAVITY_SOUTH_EAST,
62 'wm_x' => 0,
63 'wm_y' => 0,
64 'wm_scale' => 0,
65 'image_replacer' => 'enabled',
66 'img_to_video' => 'disabled',
67 'css_minify' => 'enabled',
68 'js_minify' => 'disabled',
69 'report_script' => 'disabled',
70 'native_lazyload' => 'disabled',
71 'offload_media' => 'disabled',
72 'cloud_images' => 'disabled',
73 'skip_lazyload_images' => 3,
74
75 ];
76 /**
77 * Option key.
78 *
79 * @var string Option name.
80 */
81 private $namespace;
82 /**
83 * Holds all options from db.
84 *
85 * @var array All options.
86 */
87 private $options;
88 /**
89 * Holds the status of the auto connect hook.
90 *
91 * @var boolean Whether or not the auto connect action is hooked.
92 */
93 private static $auto_connect_hooked = false;
94
95 /**
96 * Optml_Settings constructor.
97 */
98 public function __construct() {
99 $this->namespace = OPTML_NAMESPACE . '_settings';
100 $this->default_schema = apply_filters( 'optml_default_settings', $this->default_schema );
101 $this->options = wp_parse_args( get_option( $this->namespace, $this->default_schema ), $this->default_schema );
102
103 if ( defined( 'OPTIML_ENABLED_MU' ) && defined( 'OPTIML_MU_SITE_ID' ) && $this->to_boolean( constant( 'OPTIML_ENABLED_MU' ) ) && constant( 'OPTIML_MU_SITE_ID' ) ) {
104 switch_to_blog( constant( 'OPTIML_MU_SITE_ID' ) );
105 $this->options = wp_parse_args( get_option( $this->namespace, $this->default_schema ), $this->default_schema );
106 restore_current_blog();
107 }
108
109 if ( defined( 'OPTIML_USE_ENV' ) && constant( 'OPTIML_USE_ENV' ) && $this->to_boolean( constant( 'OPTIML_USE_ENV' ) ) ) {
110
111 if ( defined( 'OPTIML_API_KEY' )
112 && constant( 'OPTIML_API_KEY' ) !== ''
113 ) {
114 if ( ! $this->is_connected() && ! self::$auto_connect_hooked ) {
115 self::$auto_connect_hooked = true;
116 add_action(
117 'plugins_loaded',
118 [$this, 'auto_connect']
119 );
120 }
121 }
122
123 foreach ( self::$whitelisted_settings as $key => $type ) {
124 $env_key = 'OPTIML_' . strtoupper( $key );
125 if ( defined( $env_key ) && constant( $env_key ) ) {
126 $value = constant( $env_key );
127 if ( $type === 'bool' && ( $value === '' || ! in_array(
128 $value,
129 [
130 'on',
131 'off',
132 ],
133 true
134 ) ) ) {
135 continue;
136 }
137
138 if ( $type === 'int' && ( $value === '' || (int) $value > 100 || (int) $value < 0 ) ) {
139 continue;
140 }
141 $sanitized_value = ( $type === 'bool' ) ? ( $value === 'on' ? 'enabled' : 'disabled' ) : (int) $value;
142 $this->options[ $key ] = $sanitized_value;
143 }
144 }
145 }
146 }
147 /**
148 * Auto connect action.
149 */
150 public function auto_connect() {
151 $request = new WP_REST_Request( 'POST' );
152 $request->set_param( 'api_key', constant( 'OPTIML_API_KEY' ) );
153 Optml_Main::instance()->rest->connect( $request );
154
155 remove_action( 'plugins_loaded', [ $this, 'auto_connect' ] );
156 self::$auto_connect_hooked = false;
157 }
158 /**
159 * Return filter definitions.
160 *
161 * @return mixed|null Filter values.
162 */
163 public function get_watchers() {
164
165 return $this->get( 'watchers' );
166
167 }
168
169 /**
170 * Return filter definitions.
171 *
172 * @return mixed|null Filter values.
173 */
174 public function get_filters() {
175
176 $filters = $this->get( 'filters' );
177 if ( ! isset( $filters[ self::FILTER_TYPE_LAZYLOAD ] ) ) {
178 $filters[ self::FILTER_TYPE_LAZYLOAD ] = [];
179 }
180 if ( ! isset( $filters[ self::FILTER_TYPE_OPTIMIZE ] ) ) {
181 $filters[ self::FILTER_TYPE_OPTIMIZE ] = [];
182 }
183 foreach ( $filters as $filter_key => $filter_rules ) {
184 if ( ! isset( $filter_rules[ self::FILTER_EXT ] ) ) {
185 $filters[ $filter_key ][ self::FILTER_EXT ] = [];
186 }
187 if ( ! isset( $filter_rules[ self::FILTER_FILENAME ] ) ) {
188 $filters[ $filter_key ][ self::FILTER_FILENAME ] = [];
189 }
190 if ( ! isset( $filter_rules[ self::FILTER_URL ] ) ) {
191 $filters[ $filter_key ][ self::FILTER_URL ] = [];
192 }
193 if ( ! isset( $filter_rules[ self::FILTER_CLASS ] ) ) {
194 $filters[ $filter_key ][ self::FILTER_CLASS ] = [];
195 }
196 }
197
198 return $filters;
199 }
200
201 /**
202 * Process settings.
203 *
204 * @param array $new_settings List of settings.
205 *
206 * @return array
207 */
208 public function parse_settings( $new_settings ) {
209 $sanitized = [];
210 foreach ( $new_settings as $key => $value ) {
211 switch ( $key ) {
212 case 'admin_bar_item':
213 case 'lazyload':
214 case 'scale':
215 case 'image_replacer':
216 case 'cdn':
217 case 'network_optimization':
218 case 'lazyload_placeholder':
219 case 'retina_images':
220 case 'resize_smart':
221 case 'bg_replacer':
222 case 'video_lazyload':
223 case 'report_script':
224 case 'offload_media':
225 case 'cloud_images':
226 case 'img_to_video':
227 case 'css_minify':
228 case 'js_minify':
229 case 'native_lazyload':
230 $sanitized_value = $this->to_map_values( $value, [ 'enabled', 'disabled' ], 'enabled' );
231 break;
232 case 'max_width':
233 case 'max_height':
234 $sanitized_value = $this->to_bound_integer( $value, 100, 5000 );
235 break;
236 case 'quality':
237 $sanitized_value = $this->to_bound_integer( $value, 1, 100 );
238 break;
239 case 'wm_id':
240 $sanitized_value = intval( $value );
241 break;
242 case 'cache_buster':
243 $sanitized_value = is_string( $value ) ? $value : '';
244 break;
245 case 'cloud_sites':
246 $current_sites = $this->get( 'cloud_sites' );
247 $sanitized_value = array_replace_recursive( $current_sites, $value );
248 if ( isset( $value['all'] ) && $value['all'] === 'true' ) {
249 $sanitized_value = [ 'all' => 'true' ];
250 }
251 break;
252 case 'filters':
253 $current_filters = $this->get_filters();
254 $sanitized_value = array_replace_recursive( $current_filters, $value );
255 // Remove falsy vars.
256 foreach ( $sanitized_value as $filter_type => $filter_values ) {
257 foreach ( $filter_values as $filter_rule_type => $filter_rules_value ) {
258 $sanitized_value[ $filter_type ][ $filter_rule_type ] = array_filter(
259 $filter_rules_value,
260 function ( $value ) {
261 return ( $value !== 'false' && $value !== false );
262 }
263 );
264 }
265 }
266 break;
267 case 'watchers':
268 $sanitized_value = $value;
269 break;
270 case 'skip_lazyload_images':
271 $sanitized_value = $this->to_bound_integer( $value, 0, 100 );
272 break;
273 case 'wm_opacity':
274 case 'wm_scale':
275 case 'wm_x':
276 case 'wm_y':
277 $sanitized_value = floatval( $value );
278 break;
279 case 'wm_position':
280 $sanitized_value = $this->to_map_values(
281 $value,
282 [
283 Optml_Resize::GRAVITY_NORTH,
284 Optml_Resize::GRAVITY_NORTH_EAST,
285 Optml_Resize::GRAVITY_NORTH_WEST,
286 Optml_Resize::GRAVITY_CENTER,
287 Optml_Resize::GRAVITY_EAST,
288 Optml_Resize::GRAVITY_WEST,
289 Optml_Resize::GRAVITY_SOUTH_EAST,
290 Optml_Resize::GRAVITY_SOUTH,
291 Optml_Resize::GRAVITY_SOUTH_WEST,
292 ],
293 Optml_Resize::GRAVITY_SOUTH_EAST
294 );
295 break;
296 default:
297 $sanitized_value = '';
298 break;
299
300 }
301
302 $sanitized[ $key ] = $sanitized_value;
303 $this->update( $key, $sanitized_value );
304 }
305
306 return $sanitized;
307 }
308
309 /**
310 * Update settings.
311 *
312 * @param string $key Settings key.
313 * @param mixed $value Settings value.
314 *
315 * @return bool Update result.
316 */
317 public function update( $key, $value ) {
318 if ( ! $this->is_allowed( $key ) ) {
319 return false;
320 }
321 // If we try to update from a website which is not the main OPTML blog, bail.
322 if ( defined( 'OPTIML_ENABLED_MU' ) && constant( 'OPTIML_ENABLED_MU' ) && defined( 'OPTIML_MU_SITE_ID' ) && constant( 'OPTIML_MU_SITE_ID' ) &&
323 intval( constant( 'OPTIML_MU_SITE_ID' ) ) !== get_current_blog_id()
324 ) {
325 return false;
326 }
327 $opt = $this->options;
328 $opt[ $key ] = $value;
329 $update = update_option( $this->namespace, $opt, false );
330 if ( $update ) {
331 $this->options = $opt;
332 }
333
334 return $update;
335 }
336
337 /**
338 * Check if key is allowed.
339 *
340 * @param string $key Is key allowed or not.
341 *
342 * @return bool Is key allowed or not.
343 */
344 private function is_allowed( $key ) {
345 return isset( $this->default_schema[ $key ] );
346 }
347
348 /**
349 * Check if the user is connected to Optimole.
350 *
351 * @return bool Connection status.
352 */
353 public function is_connected() {
354 $service_data = $this->get( 'service_data' );
355 if ( ! isset( $service_data['cdn_key'] ) ) {
356 return false;
357 }
358 if ( empty( $service_data ['cdn_key'] ) || empty( $service_data['cdn_secret'] ) ) {
359 return false;
360 }
361
362 return true;
363 }
364
365 /**
366 * Get setting value by key.
367 *
368 * @param string $key Key to search against.
369 *
370 * @return mixed|null Setting value.
371 */
372 public function get( $key ) {
373 if ( ! $this->is_allowed( $key ) ) {
374 return null;
375 }
376
377 return isset( $this->options[ $key ] ) ? $this->options[ $key ] : '';
378 }
379
380 /**
381 * Return site settings.
382 *
383 * @return array Site settings.
384 */
385 public function get_site_settings() {
386 $service_data = $this->get( 'service_data' );
387 $whitelist = [];
388 if ( isset( $service_data['whitelist'] ) ) {
389 $whitelist = $service_data['whitelist'];
390 }
391 return [
392 'quality' => $this->get_quality(),
393 'admin_bar_item' => $this->get( 'admin_bar_item' ),
394 'lazyload' => $this->get( 'lazyload' ),
395 'network_optimization' => $this->get( 'network_optimization' ),
396 'retina_images' => $this->get( 'retina_images' ),
397 'lazyload_placeholder' => $this->get( 'lazyload_placeholder' ),
398 'skip_lazyload_images' => $this->get( 'skip_lazyload_images' ),
399 'bg_replacer' => $this->get( 'bg_replacer' ),
400 'video_lazyload' => $this->get( 'video_lazyload' ),
401 'resize_smart' => $this->get( 'resize_smart' ),
402 'image_replacer' => $this->get( 'image_replacer' ),
403 'cdn' => $this->get( 'cdn' ),
404 'max_width' => $this->get( 'max_width' ),
405 'max_height' => $this->get( 'max_height' ),
406 'filters' => $this->get_filters(),
407 'cloud_sites' => $this->get( 'cloud_sites' ),
408 'watchers' => $this->get_watchers(),
409 'watermark' => $this->get_watermark(),
410 'img_to_video' => $this->get( 'img_to_video' ),
411 'scale' => $this->get( 'scale' ),
412 'css_minify' => $this->get( 'css_minify' ),
413 'js_minify' => $this->get( 'js_minify' ),
414 'native_lazyload' => $this->get( 'native_lazyload' ),
415 'report_script' => $this->get( 'report_script' ),
416 'offload_media' => $this->get( 'offload_media' ),
417 'cloud_images' => $this->get( 'cloud_images' ),
418 'whitelist_domains' => $whitelist,
419 ];
420 }
421
422 /**
423 * Return quality factor.
424 *
425 * @return string Quality factor.
426 */
427 public function get_quality() {
428 $quality = $this->get( 'quality' );
429 // Legacy compat.
430 if ( $quality === 'low' ) {
431 return 'high_c';
432 }
433 if ( $quality === 'medium' ) {
434 return 'medium_c';
435 }
436
437 if ( $quality === 'high' ) {
438 return 'low_c';
439 }
440
441 return $quality;
442 }
443
444 /**
445 * Return an watermark array.
446 *
447 * @return array
448 */
449 public function get_watermark() {
450 return [
451 'id' => $this->get( 'wm_id' ),
452 'opacity' => $this->get( 'wm_opacity' ),
453 'position' => $this->get( 'wm_position' ),
454 'x_offset' => $this->get( 'wm_x' ),
455 'y_offset' => $this->get( 'wm_y' ),
456 'scale' => $this->get( 'wm_scale' ),
457 ];
458 }
459
460 /**
461 * Check if smart cropping is enabled.
462 *
463 * @return bool Is smart cropping enabled.
464 */
465 public function is_smart_cropping() {
466 return $this->get( 'resize_smart' ) === 'enabled';
467 }
468
469 /**
470 * Get numeric quality used by the service.
471 *
472 * @return int Numeric quality.
473 */
474 public function get_numeric_quality() {
475 $value = $this->get_quality();
476
477 return (int) $this->to_accepted_quality( $value );
478 }
479
480 /**
481 * Check if replacer is enabled.
482 *
483 * @return bool Replacer enabled
484 */
485 public function is_enabled() {
486 $status = $this->get( 'image_replacer' );
487 $service_data = $this->get( 'service_data' );
488 if ( empty( $service_data ) ) {
489 return false;
490 }
491 if ( isset( $service_data['status'] ) && $service_data['status'] === 'inactive' ) {
492 return false;
493 }
494 return $this->to_boolean( $status );
495 }
496
497 /**
498 * Check if lazyload is enabled.
499 *
500 * @return bool Lazyload enabled
501 */
502 public function use_lazyload() {
503 $status = $this->get( 'lazyload' );
504
505 return $this->to_boolean( $status );
506 }
507
508 /**
509 * Check if replacer is enabled.
510 *
511 * @return bool Replacer enabled
512 */
513 public function use_cdn() {
514 $status = $this->get( 'cdn' );
515
516 return $this->to_boolean( $status );
517 }
518
519 /**
520 * Return cdn url.
521 *
522 * @return string CDN url.
523 */
524 public function get_cdn_url() {
525 $service_data = $this->get( 'service_data' );
526 if ( ! isset( $service_data['cdn_key'] ) ) {
527 return '';
528 }
529
530 if ( isset( $service_data['is_cname_assigned'] ) && $service_data['is_cname_assigned'] === 'yes' && ! empty( $service_data['domain'] ) ) {
531 return strtolower( $service_data['domain'] );
532 }
533
534 if ( defined( 'OPTML_CUSTOM_DOMAIN' ) && constant( 'OPTML_CUSTOM_DOMAIN' ) ) {
535 return parse_url( strtolower( OPTML_CUSTOM_DOMAIN ), PHP_URL_HOST );
536 }
537
538 return sprintf(
539 '%s.%s',
540 strtolower( $service_data['cdn_key'] ),
541 Optml_Config::$base_domain
542 );
543 }
544
545 /**
546 * Reset options to defaults.
547 *
548 * @return bool Reset action status.
549 */
550 public function reset() {
551 $reset_schema = $this->default_schema;
552 $reset_schema['filters'] = $this->options['filters'];
553
554 $update = update_option( $this->namespace, $reset_schema );
555 if ( $update ) {
556 $this->options = $reset_schema;
557 }
558
559 return $update;
560 }
561
562 }
563