PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.2.0
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.2.0
1.3.3 1.3.2 1.3.1 1.3.0 1.2.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 All 29 releases
xspeed / includes / class-settings.php

class-settings.php in xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN 1.2.0, at includes/class-settings.php

130 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Settings handling.
4 *
5 * @package XSpeed
6 */
7
8 namespace XSpeed;
9
10 defined( 'ABSPATH' ) || exit;
11
12 class Settings {
13
14 const OPTION_KEY = 'xspeed_options';
15
16 public static function defaults() {
17 // Migrated out of this legacy blob (now per-module storage):
18 // - minify_html / minify_css / minify_js → xspeed_module_minify
19 // - gzip_enabled → xspeed_module_gzip
20 // - cache_expiry / excluded_urls → xspeed_module_cache
21 // Still here (intentionally, drop-in lifecycle):
22 // - cache_enabled (Cache::toggle owns the .htaccess/wp-config edit)
23 return array(
24 'cache_enabled' => false,
25 );
26 }
27
28 public static function get() {
29 $saved = get_option( self::OPTION_KEY, array() );
30 return wp_parse_args( $saved, self::defaults() );
31 }
32
33 public static function update( array $input ) {
34 $current = self::get();
35 $clean = $current;
36
37 // Every former field is now in per-module storage:
38 // - minify_* → MinifyModule, gzip_enabled → GzipModule,
39 // cache_expiry / excluded_urls → CacheModule.
40 // Only cache_enabled lives on here, owned by Cache::toggle's
41 // drop-in lifecycle. All other writes are silently ignored to
42 // keep duplicate sources from re-forming.
43 if ( isset( $input['cache_enabled'] ) ) {
44 $clean['cache_enabled'] = (bool) $input['cache_enabled'];
45 }
46
47 update_option( self::OPTION_KEY, $clean );
48 return $clean;
49 }
50
51 public static function set_defaults() {
52 if ( false === get_option( self::OPTION_KEY ) ) {
53 add_option( self::OPTION_KEY, self::defaults() );
54 // Only a genuinely fresh install reaches this branch — the
55 // option survives deactivation, so an upgrade (deactivate →
56 // wipe → install → activate) always finds it present.
57 self::seed_recommended_modules();
58 }
59 }
60
61 /**
62 * Settings a fresh install starts with, beyond each module's schema
63 * default. Mirrors the wizard's "Balanced" preset — the profile the
64 * product already labels "Recommended for most sites".
65 *
66 * Why this exists: the wizard is skippable, and a WP-CLI or bulk
67 * activation never shows it at all. Those users fell through to the raw
68 * schema defaults, which are more conservative than what we recommend to
69 * the very same site — so whether a site compressed its responses came
70 * down to whether someone clicked through a wizard. Measured on a real
71 * install: gzip off, browser-cache headers off, no minification, while
72 * lazy-load and resource hints (schema default `true`) were on.
73 *
74 * Deliberately excluded: `minify_js`, `defer_js`, `combine_css`,
75 * `combine_js`, `delay_js`. Each can break a theme, and a default that
76 * breaks the site is worse than a default that is merely slow. They stay
77 * opt-in via the wizard's Aggressive preset or the dashboard.
78 *
79 * @return array<string,array<string,bool>> module slug => settings
80 */
81 private static function recommended_module_settings(): array {
82 return array(
83 // Compression — the single largest byte win, and inert until a
84 // server actually supports it (GzipModule writes .htaccess only
85 // where supports_htaccess() is true, and emits a snippet
86 // otherwise).
87 'gzip' => array( 'gzip_enabled' => true ),
88 // Far-future caching for static assets. Only ever affects
89 // css/js/images/fonts; HTML keeps its own short TTL.
90 'browser-cache' => array( 'enabled' => true ),
91 // HTML + CSS minification. Both are whitespace/comment-level
92 // and do not reorder or combine anything, so they carry none of
93 // the cascade risk that combine_css does.
94 'minify' => array(
95 'minify_html' => true,
96 'minify_css' => true,
97 ),
98 );
99 }
100
101 /**
102 * Write the recommended defaults for a fresh install, without ever
103 * overwriting a value the user has already chosen.
104 *
105 * Each key is written only when it is absent from stored settings, so
106 * this stays safe if it is ever reached on a site that has some — but
107 * not all — module options saved.
108 */
109 private static function seed_recommended_modules(): void {
110 foreach ( self::recommended_module_settings() as $slug => $values ) {
111 $key = 'xspeed_module_' . $slug;
112 $stored = get_option( $key, null );
113 $stored = is_array( $stored ) ? $stored : array();
114
115 $next = $stored;
116 foreach ( $values as $setting => $value ) {
117 if ( ! array_key_exists( $setting, $stored ) ) {
118 $next[ $setting ] = $value;
119 }
120 }
121 if ( $next !== $stored ) {
122 update_option( $key, $next, false );
123 }
124 }
125 }
126
127 // sanitize_urls() removed — excluded_urls now owned by CacheModule
128 // and validated by Settings_Manager's typed schema (list / item_type).
129 }
130