PluginProbe ʕ •ᴥ•ʔ
LiteSpeed Cache / 7.8.1
LiteSpeed Cache v7.8.1
trunk 1.0.15 1.9.1.1 2.9.9.2 3.6.4 4.6 5.7.0.1 6.5.4 7.0.0.1 7.0.1 7.1 7.2 7.3 7.3.0.1 7.4 7.5 7.5.0.1 7.6 7.6.1 7.6.2 7.7 7.8 7.8.0.1 7.8.1
litespeed-cache / src / conf.cls.php
litespeed-cache / src Last commit date
cdn 2 months ago data_structure 2 months ago activation.cls.php 2 months ago admin-display.cls.php 2 months ago admin-settings.cls.php 2 months ago admin.cls.php 2 months ago api.cls.php 2 months ago avatar.cls.php 2 months ago base.cls.php 2 months ago cdn.cls.php 2 months ago cloud-auth-callback.trait.php 2 months ago cloud-auth-ip.trait.php 2 months ago cloud-auth.trait.php 2 months ago cloud-misc.trait.php 2 months ago cloud-node.trait.php 2 months ago cloud-request.trait.php 2 months ago cloud.cls.php 2 months ago conf.cls.php 2 months ago control.cls.php 2 months ago core.cls.php 2 months ago crawler-map.cls.php 2 months ago crawler.cls.php 2 months ago css.cls.php 2 months ago data.cls.php 2 months ago data.upgrade.func.php 2 months ago db-optm.cls.php 2 months ago debug2.cls.php 2 months ago doc.cls.php 2 months ago error.cls.php 2 months ago esi.cls.php 2 months ago file.cls.php 2 months ago guest.cls.php 2 months ago gui.cls.php 2 months ago health.cls.php 2 months ago htaccess.cls.php 2 months ago img-optm-manage.trait.php 2 months ago img-optm-pull.trait.php 2 months ago img-optm-send.trait.php 2 months ago img-optm.cls.php 2 months ago import.cls.php 2 months ago import.preset.cls.php 2 months ago lang.cls.php 2 months ago localization.cls.php 2 months ago media.cls.php 2 months ago metabox.cls.php 2 months ago object-cache-wp.cls.php 2 months ago object-cache.cls.php 2 months ago object.lib.php 2 months ago optimize.cls.php 2 months ago optimizer.cls.php 2 months ago placeholder.cls.php 2 months ago purge.cls.php 2 months ago report.cls.php 2 months ago rest.cls.php 2 months ago root.cls.php 2 months ago router.cls.php 2 months ago str.cls.php 2 months ago tag.cls.php 2 months ago task.cls.php 2 months ago tool.cls.php 2 months ago ucss.cls.php 2 months ago utility.cls.php 2 months ago vary.cls.php 2 months ago vpi.cls.php 2 months ago
conf.cls.php
776 lines
1 <?php
2 /**
3 * The core plugin config class.
4 *
5 * This maintains all the options and settings for this plugin.
6 *
7 * @since 1.0.0
8 * @package LiteSpeed
9 */
10
11 namespace LiteSpeed;
12
13 defined('WPINC') || exit();
14
15 /**
16 * Class Conf
17 *
18 * Maintains all LiteSpeed plugin configuration, including CRUD for single-site
19 * and multisite options, upgrade flows, and side effects like purging/cron.
20 */
21 class Conf extends Base {
22
23 const TYPE_SET = 'set';
24
25 /**
26 * IDs that were updated during a save cycle.
27 *
28 * @var array<string|int,mixed>
29 */
30 private $_updated_ids = [];
31
32 /**
33 * Whether current blog is the network primary site.
34 *
35 * @var bool
36 */
37 private $_is_primary = false;
38
39 /**
40 * Specify init logic to avoid infinite loop when calling conf.cls instance
41 *
42 * @since 3.0
43 * @access public
44 * @return void
45 */
46 public function init() {
47 // Check if conf exists or not. If not, create them in DB (won't change version if is converting v2.9- data)
48 // Conf may be stale, upgrade later
49 $this->_conf_db_init();
50
51 /**
52 * Detect if has quic.cloud set
53 *
54 * @since 2.9.7
55 */
56 if ( $this->conf( self::O_CDN_QUIC ) ) {
57 if ( ! defined( 'LITESPEED_ALLOWED' ) ) {
58 define( 'LITESPEED_ALLOWED', true );
59 }
60 }
61
62 add_action( 'litespeed_conf_append', [ $this, 'option_append' ], 10, 2 );
63 add_action( 'litespeed_conf_force', [ $this, 'force_option' ], 10, 2 );
64
65 $this->define_cache();
66 }
67
68 /**
69 * Init conf related data
70 *
71 * @since 3.0
72 * @access private
73 * @return void
74 */
75 private function _conf_db_init() {
76 /**
77 * Try to load options first, network sites can override this later
78 *
79 * NOTE: Load before run `conf_upgrade()` to avoid infinite loop when getting conf in `conf_upgrade()`
80 */
81 $this->load_options();
82
83 // Check if debug is on
84 // Init debug as early as possible
85 if ( $this->conf( Base::O_DEBUG ) ) {
86 $this->cls( 'Debug2' )->init();
87 }
88
89 $ver = $this->conf( self::_VER );
90
91 /**
92 * Version is less than v3.0, or, is a new installation
93 */
94 $ver_check_tag = 'new';
95 if ( $ver ) {
96 if ( ! defined( 'LSCWP_CUR_V' ) ) {
97 define( 'LSCWP_CUR_V', $ver );
98 }
99
100 /**
101 * Upgrade conf
102 */
103 if ( Core::VER !== $ver ) {
104 // Plugin version will be set inside
105 // Site plugin upgrade & version change will do in load_site_conf
106 $ver_check_tag = Data::cls()->conf_upgrade( $ver );
107 }
108 }
109
110 /**
111 * Sync latest new options
112 */
113 if ( ! $ver || Core::VER !== $ver ) {
114 // Load default values
115 $this->load_default_vals();
116
117 if ( ! $ver ) {
118 // New install
119 $this->set_conf( self::$_default_options );
120
121 $ver_check_tag .= ' activate' . ( defined( 'LSCWP_REF' ) ? '_' . constant( 'LSCWP_REF' ) : '' );
122 }
123
124 // Init new default/missing options
125 foreach ( self::$_default_options as $k => $v ) {
126 // If the option existed, bypass updating
127 // Bcos we may ask clients to deactivate for debug temporarily, we need to keep the current cfg in deactivation, hence we need to only try adding default cfg when activating.
128 self::add_option( $k, $v );
129 }
130
131 // Force correct version in case a rare unexpected case that `_ver` exists but empty
132 self::update_option( Base::_VER, Core::VER );
133
134 if ( $ver_check_tag ) {
135 Cloud::version_check( $ver_check_tag );
136 }
137 }
138
139 /**
140 * Network sites only
141 *
142 * Override conf if is network subsites and chose `Use Primary Config`
143 */
144 $this->_try_load_site_options();
145
146 // Check if debug is on
147 // Init debug as early as possible
148 if ( $this->conf( Base::O_DEBUG ) ) {
149 $this->cls( 'Debug2' )->init();
150 }
151
152 // Mark as conf loaded
153 if ( ! defined( 'LITESPEED_CONF_LOADED' ) ) {
154 define( 'LITESPEED_CONF_LOADED', true );
155 }
156
157 if ( ! $ver || Core::VER !== $ver ) {
158 // Only trigger once in upgrade progress, don't run always
159 $this->update_confs(); // Files only get corrected in activation or saving settings actions.
160 }
161 }
162
163 /**
164 * Load all latest options from DB
165 *
166 * @since 3.0
167 * @access public
168 *
169 * @param int|null $blog_id Blog ID to load from. Null for current.
170 * @param bool $dry_run Return options instead of setting them.
171 * @return array<string,mixed>|void
172 */
173 public function load_options( $blog_id = null, $dry_run = false ) {
174 $options = [];
175 foreach ( self::$_default_options as $k => $v ) {
176 if ( null !== $blog_id ) {
177 $options[ $k ] = self::get_blog_option( $blog_id, $k, $v );
178 } else {
179 $options[ $k ] = self::get_option( $k, $v );
180 }
181
182 // Correct value type.
183 $options[ $k ] = $this->type_casting( $options[ $k ], $k );
184 }
185
186 if ( $dry_run ) {
187 return $options;
188 }
189
190 // Bypass site special settings
191 if ( null !== $blog_id ) {
192 // This is to load the primary settings ONLY
193 // These options are the ones that can be overwritten by primary
194 $options = array_diff_key( $options, array_flip( self::$single_site_options ) );
195
196 $this->set_primary_conf( $options );
197 } else {
198 $this->set_conf( $options );
199 }
200
201 // Append const options
202 if ( defined( 'LITESPEED_CONF' ) && LITESPEED_CONF ) {
203 foreach ( self::$_default_options as $k => $v ) {
204 $const = Base::conf_const( $k );
205 if ( defined( $const ) ) {
206 $this->set_const_conf( $k, $this->type_casting( constant( $const ), $k ) );
207 }
208 }
209 }
210 }
211
212 /**
213 * For multisite installations, the single site options need to be updated with the network wide options.
214 *
215 * @since 1.0.13
216 * @access private
217 * @return void
218 */
219 private function _try_load_site_options() {
220 if ( ! $this->_if_need_site_options() ) {
221 return;
222 }
223
224 $this->_conf_site_db_init();
225
226 $this->_is_primary = BLOG_ID_CURRENT_SITE === get_current_blog_id();
227
228 // If network set to use primary setting
229 if ( $this->network_conf( self::NETWORK_O_USE_PRIMARY ) && ! $this->_is_primary ) {
230 // subsites or network admin
231 // Get the primary site settings
232 // If it's just upgraded, 2nd blog is being visited before primary blog, can just load default config (won't hurt as this could only happen shortly)
233 $this->load_options( BLOG_ID_CURRENT_SITE );
234 }
235
236 // Overwrite single blog options with site options
237 foreach ( self::$_default_options as $k => $v ) {
238 if ( ! $this->has_network_conf( $k ) ) {
239 continue;
240 }
241 // $this->_options[ $k ] = $this->_network_options[ $k ];
242
243 // Special handler to `Enable Cache` option if the value is set to OFF
244 if ( self::O_CACHE === $k ) {
245 if ( $this->_is_primary ) {
246 if ( $this->conf( $k ) !== $this->network_conf( $k ) ) {
247 if ( self::VAL_ON2 !== $this->conf( $k ) ) {
248 continue;
249 }
250 }
251 } elseif ( $this->network_conf( self::NETWORK_O_USE_PRIMARY ) ) {
252 if ( $this->has_primary_conf( $k ) && self::VAL_ON2 !== $this->primary_conf( $k ) ) {
253 // This case will use primary_options override always
254 continue;
255 }
256 } elseif ( self::VAL_ON2 !== $this->conf( $k ) ) {
257 continue;
258 }
259 }
260
261 // primary_options will store primary settings + network settings, OR, store the network settings for subsites
262 $this->set_primary_conf( $k, $this->network_conf( $k ) );
263 }
264 // var_dump($this->_options);
265 }
266
267 /**
268 * Check if needs to load site_options for network sites
269 *
270 * @since 3.0
271 * @access private
272 * @return bool
273 */
274 private function _if_need_site_options() {
275 if ( ! is_multisite() ) {
276 return false;
277 }
278
279 // Check if needs to use site_options or not
280 // todo: check if site settings are separate bcos it will affect .htaccess
281
282 /**
283 * In case this is called outside the admin page
284 *
285 * @see https://codex.wordpress.org/Function_Reference/is_plugin_active_for_network
286 * @since 2.0
287 */
288 if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
289 require_once ABSPATH . '/wp-admin/includes/plugin.php';
290 }
291 // If is not activated on network, it will not have site options
292 if ( ! is_plugin_active_for_network( Core::PLUGIN_FILE ) ) {
293 if ( self::VAL_ON2 === (int) $this->conf( self::O_CACHE ) ) {
294 // Default to cache on
295 $this->set_conf( self::_CACHE, true );
296 }
297 return false;
298 }
299
300 return true;
301 }
302
303 /**
304 * Init site conf and upgrade if necessary
305 *
306 * @since 3.0
307 * @access private
308 * @return void
309 */
310 private function _conf_site_db_init() {
311 $this->load_site_options();
312
313 $ver = $this->network_conf( self::_VER );
314
315 /**
316 * Don't upgrade or run new installations other than from backend visit
317 * In this case, just use default conf
318 */
319 if ( ! $ver || Core::VER !== $ver ) {
320 if ( ! is_admin() && ! defined( 'LITESPEED_CLI' ) ) {
321 $this->set_network_conf( $this->load_default_site_vals() );
322 return;
323 }
324 }
325
326 /**
327 * Upgrade conf
328 */
329 if ( $ver && Core::VER !== $ver ) {
330 // Site plugin version will change inside
331 Data::cls()->conf_site_upgrade( $ver );
332 }
333
334 /**
335 * Is a new installation
336 */
337 if ( ! $ver || Core::VER !== $ver ) {
338 // Load default values
339 $this->load_default_site_vals();
340
341 // Init new default/missing options
342 foreach ( self::$_default_site_options as $k => $v ) {
343 // If the option existed, bypass updating
344 self::add_site_option( $k, $v );
345 }
346 }
347 }
348
349 /**
350 * Get the plugin's site wide options.
351 *
352 * If the site wide options are not set yet, set it to default.
353 *
354 * @since 1.0.2
355 * @access public
356 * @return null|void
357 */
358 public function load_site_options() {
359 if ( ! is_multisite() ) {
360 return null;
361 }
362
363 // Load all site options
364 foreach ( self::$_default_site_options as $k => $v ) {
365 $val = self::get_site_option( $k, $v );
366 $val = $this->type_casting( $val, $k, true );
367 $this->set_network_conf( $k, $val );
368 }
369 }
370
371 /**
372 * Append a 3rd party option to default options
373 *
374 * This will not be affected by network use primary site setting.
375 *
376 * NOTE: If it is a multi switch option, need to call `_conf_multi_switch()` first
377 *
378 * @since 3.0
379 * @access public
380 *
381 * @param string $name Option name.
382 * @param mixed $default_val Default value.
383 * @return void
384 */
385 public function option_append( $name, $default_val ) {
386 self::$_default_options[ $name ] = $default_val;
387 $this->set_conf( $name, self::get_option( $name, $default_val ) );
388 $this->set_conf( $name, $this->type_casting( $this->conf( $name ), $name ) );
389 }
390
391 /**
392 * Force an option to a certain value
393 *
394 * @since 2.6
395 * @access public
396 *
397 * @param string $k Option key.
398 * @param mixed $v Option value.
399 * @return void
400 */
401 public function force_option( $k, $v ) {
402 if ( ! $this->has_conf( $k ) ) {
403 return;
404 }
405
406 $v = $this->type_casting( $v, $k );
407
408 if ( $this->conf( $k ) === $v ) {
409 return;
410 }
411
412 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
413 Debug2::debug( '[Conf] ** ' . $k . ' forced from ' . var_export( $this->conf( $k ), true ) . ' to ' . var_export( $v, true ) );
414
415 $this->set_conf( $k, $v );
416 }
417
418 /**
419 * Define `_CACHE` const in options ( for both single and network )
420 *
421 * @since 3.0
422 * @access public
423 * @return void
424 */
425 public function define_cache() {
426 // Init global const cache on setting
427 $this->set_conf( self::_CACHE, false );
428 if ( self::VAL_ON === (int) $this->conf( self::O_CACHE ) || $this->conf( self::O_CDN_QUIC ) ) {
429 $this->set_conf( self::_CACHE, true );
430 }
431
432 // Check network
433 if ( ! $this->_if_need_site_options() ) {
434 // Set cache on
435 $this->_define_cache_on();
436 return;
437 }
438
439 // If use network setting
440 if ( self::VAL_ON2 === (int) $this->conf( self::O_CACHE ) && $this->network_conf( self::O_CACHE ) ) {
441 $this->set_conf( self::_CACHE, true );
442 }
443
444 $this->_define_cache_on();
445 }
446
447 /**
448 * Define `LITESPEED_ON`
449 *
450 * @since 2.1
451 * @access private
452 * @return void
453 */
454 private function _define_cache_on() {
455 if ( ! $this->conf( self::_CACHE ) ) {
456 return;
457 }
458
459 if ( defined( 'LITESPEED_ALLOWED' ) && ! defined( 'LITESPEED_ON' ) ) {
460 define( 'LITESPEED_ON', true );
461 }
462 }
463
464 /**
465 * Save option
466 *
467 * @since 3.0
468 * @access public
469 *
470 * @param array<string,mixed> $the_matrix Option-value map.
471 * @return void
472 */
473 public function update_confs( $the_matrix = [] ) {
474 if ( $the_matrix ) {
475 foreach ( $the_matrix as $id => $val ) {
476 $this->update( $id, $val );
477 }
478 }
479
480 if ( $this->_updated_ids ) {
481 foreach ( $this->_updated_ids as $id ) {
482 // Check if need to do a purge all or not
483 if ( $this->_conf_purge_all( $id ) ) {
484 Purge::purge_all( 'conf changed [id] ' . $id );
485 }
486
487 // Check if need to purge a tag
488 $tag = $this->_conf_purge_tag( $id );
489 if ( $tag ) {
490 Purge::add( $tag );
491 }
492
493 // Update cron
494 if ( $this->_conf_cron( $id ) ) {
495 $this->cls( 'Task' )->try_clean( $id );
496 }
497
498 // Reset crawler bypassed list when any of the options WebP replace, guest mode, or cache mobile got changed
499 if ( self::O_IMG_OPTM_WEBP === $id || self::O_GUEST === $id || self::O_CACHE_MOBILE === $id ) {
500 $this->cls( 'Crawler' )->clear_disabled_list();
501 }
502 }
503 }
504
505 do_action( 'litespeed_update_confs', $the_matrix );
506
507 // Update related tables
508 $this->cls( 'Data' )->correct_tb_existence();
509
510 // Update related files
511 $this->cls( 'Activation' )->update_files();
512
513 /**
514 * CDN related actions - Cloudflare
515 */
516 $this->cls( 'CDN\Cloudflare' )->try_refresh_zone();
517
518 // If Server IP changed, must test echo
519 if ( in_array( self::O_SERVER_IP, $this->_updated_ids, true ) ) {
520 $this->cls( 'Cloud' )->init_qc_cli();
521 }
522
523 // CDN related actions - QUIC.cloud
524 $this->cls( 'CDN\Quic' )->try_sync_conf();
525 }
526
527 /**
528 * Save option
529 *
530 * Note: this is direct save, won't trigger corresponding file update or data sync. To save settings normally, always use `Conf->update_confs()`
531 *
532 * @since 3.0
533 * @access public
534 *
535 * @param string $id Option ID.
536 * @param mixed $val Option value.
537 * @return void
538 */
539 public function update( $id, $val ) {
540 // Bypassed this bcos $this->_options could be changed by force_option()
541 // if ( $this->_options[ $id ] === $val ) {
542 // return;
543 // }
544
545 if ( self::_VER === $id ) {
546 return;
547 }
548
549 if ( self::O_SERVER_IP === $id ) {
550 if ( $val && ! Utility::valid_ipv4( $val ) ) {
551 $msg = sprintf( __( 'Saving option failed. IPv4 only for %s.', 'litespeed-cache' ), Lang::title( Base::O_SERVER_IP ) );
552 Admin_Display::error( $msg );
553 return;
554 }
555 }
556
557 if ( ! array_key_exists( $id, self::$_default_options ) ) {
558 if ( defined( 'LSCWP_LOG' ) ) {
559 Debug2::debug( '[Conf] Invalid option ID ' . $id );
560 }
561 return;
562 }
563
564 if ( $val && $this->_conf_pswd( $id ) && ! preg_match( '/[^\*]/', (string) $val ) ) {
565 return;
566 }
567
568 // Special handler for CDN Original URLs
569 if ( self::O_CDN_ORI === $id && ! $val ) {
570 $site_url = site_url( '/' );
571 $parsed = wp_parse_url( $site_url );
572 if ( !empty( $parsed['scheme'] ) ) {
573 $site_url = str_replace( $parsed['scheme'] . ':', '', $site_url );
574 }
575
576 $val = $site_url;
577 }
578
579 // Validate type
580 $val = $this->type_casting( $val, $id );
581
582 // Save data
583 self::update_option( $id, $val );
584
585 // Handle purge if setting changed
586 if ( $this->conf( $id ) !== $val ) {
587 $this->_updated_ids[] = $id;
588
589 // Check if need to fire a purge or not (Here has to stay inside `update()` bcos need comparing old value)
590 if ( $this->_conf_purge( $id ) ) {
591 $old = (array) $this->conf( $id );
592 $new = (array) $val;
593 $diff = array_merge( array_diff( $new, $old ), array_diff( $old, $new ) );
594 // If has difference
595 foreach ( $diff as $v ) {
596 $v = ltrim( (string) $v, '^' );
597 $v = rtrim( (string) $v, '$' );
598 $this->cls( 'Purge' )->purge_url( $v );
599 }
600 }
601 }
602
603 // Update in-memory data
604 $this->set_conf( $id, $val );
605 }
606
607 /**
608 * Save network option
609 *
610 * @since 3.0
611 * @access public
612 *
613 * @param string $id Option ID.
614 * @param mixed $val Option value.
615 * @return void
616 */
617 public function network_update( $id, $val ) {
618 if ( ! array_key_exists( $id, self::$_default_site_options ) ) {
619 if ( defined( 'LSCWP_LOG' ) ) {
620 Debug2::debug( '[Conf] Invalid network option ID ' . $id );
621 }
622 return;
623 }
624
625 if ( $val && $this->_conf_pswd( $id ) && ! preg_match( '/[^\*]/', (string) $val ) ) {
626 return;
627 }
628
629 // Validate type
630 if ( is_bool( self::$_default_site_options[ $id ] ) ) {
631 $max = $this->_conf_multi_switch( $id );
632 if ( $max && $val > 1 ) {
633 $val %= ( $max + 1 );
634 } else {
635 $val = (bool) $val;
636 }
637 } elseif ( is_array( self::$_default_site_options[ $id ] ) ) {
638 // from textarea input
639 if ( ! is_array( $val ) ) {
640 $val = Utility::sanitize_lines( $val, $this->_conf_filter( $id ) );
641 }
642 } elseif ( ! is_string( self::$_default_site_options[ $id ] ) ) {
643 $val = (int) $val;
644 } else {
645 // Check if the string has a limit set
646 $val = $this->_conf_string_val( $id, $val );
647 }
648
649 // Save data
650 self::update_site_option( $id, $val );
651
652 // Handle purge if setting changed
653 if ( $this->network_conf( $id ) !== $val ) {
654 // Check if need to do a purge all or not
655 if ( $this->_conf_purge_all( $id ) ) {
656 Purge::purge_all( '[Conf] Network conf changed [id] ' . $id );
657 }
658
659 // Update in-memory data
660 $this->set_network_conf( $id, $val );
661 }
662
663 // No need to update cron here, Cron will register in each init
664
665 if ( $this->has_conf( $id ) ) {
666 $this->set_conf( $id, $val );
667 }
668 }
669
670 /**
671 * Check if one user role is in exclude optimization group settings
672 *
673 * @since 1.6
674 * @access public
675 *
676 * @param string|null $role The user role.
677 * @return string|false The set value if already set, otherwise false.
678 */
679 public function in_optm_exc_roles( $role = null ) {
680 // Get user role
681 if ( null === $role ) {
682 $role = Router::get_role();
683 }
684
685 if ( ! $role ) {
686 return false;
687 }
688
689 $roles = explode( ',', $role );
690 $found = array_intersect( $roles, $this->conf( self::O_OPTM_EXC_ROLES ) );
691
692 return $found ? implode( ',', $found ) : false;
693 }
694
695 /**
696 * Set one config value directly
697 *
698 * @since 2.9
699 * @access private
700 * @return void
701 */
702 private function _set_conf() {
703 /**
704 * NOTE: For URL Query String setting,
705 * 1. If append lines to an array setting e.g. `cache-force_uri`, use `set[cache-force_uri][]=the_url`.
706 * 2. If replace the array setting with one line, use `set[cache-force_uri]=the_url`.
707 * 3. If replace the array setting with multi lines value, use 2 then 1.
708 */
709 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput
710 $raw = !empty( $_GET[ self::TYPE_SET ] ) ? $_GET[ self::TYPE_SET ] : false;
711 if ( !$raw || ! is_array( $raw ) ) {
712 return;
713 }
714
715 // Sanitize the incoming matrix.
716 $the_matrix = [];
717 foreach ( $raw as $id => $v ) {
718 if ( ! $this->has_conf( $id ) ) {
719 continue;
720 }
721
722 // Append new item to array type settings
723 if ( is_array( $v ) && is_array( $this->conf( $id ) ) ) {
724 $v = array_merge( $this->conf( $id ), $v );
725
726 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
727 Debug2::debug( '[Conf] Appended to settings [' . $id . ']: ' . var_export( $v, true ) );
728 } else {
729 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
730 Debug2::debug( '[Conf] Set setting [' . $id . ']: ' . var_export( $v, true ) );
731 }
732
733 $the_matrix[ $id ] = $v;
734 }
735
736 if ( !$the_matrix ) {
737 return;
738 }
739
740 $this->update_confs( $the_matrix );
741
742 $msg = __( 'Changed setting successfully.', 'litespeed-cache' );
743 Admin_Display::success( $msg );
744
745 // Redirect if changed frontend URL
746 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
747 $redirect = ! empty( $_GET['redirect'] ) ? sanitize_text_field( wp_unslash( $_GET['redirect'] ) ) : '';
748 if ( $redirect ) {
749 wp_safe_redirect( $redirect );
750 exit;
751 }
752 }
753
754 /**
755 * Handle all request actions from main cls
756 *
757 * @since 2.9
758 * @access public
759 * @return void
760 */
761 public function handler() {
762 $type = Router::verify_type();
763
764 switch ( $type ) {
765 case self::TYPE_SET:
766 $this->_set_conf();
767 break;
768
769 default:
770 break;
771 }
772
773 Admin::redirect();
774 }
775 }
776