PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.3.3
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.3.3
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
← All changes | includes/class-onboarding.php +53 -3 1.1.31.3.3 View file →
@@ -163,10 +163,12 @@
163 163 XSPEED_VERSION . '.' . filemtime( $asset_css )
164 164 );
165 165 }
166 166
167 - wp_localize_script(
168 - 'xspeed-admin',
167 + // Same type-preserving path as the dashboard — see
168 + // Admin::print_config(). wp_localize_script() would stringify every
169 + // scalar in this payload too. (#105)
170 + Admin::print_config(
169 171 'XSpeedConfig',
170 172 array(
171 173 'mode' => 'onboarding',
172 174 'restUrl' => esc_url_raw( rest_url( Rest_Api::NAMESPACE_V1 ) ),
@@ -178,8 +180,11 @@
178 180 'branding' => Admin::branding(),
179 181 'dashboardUrl' => admin_url( 'admin.php?page=' . Admin::PAGE_SLUG ),
180 182 'bootstrap' => array(
181 183 'settings' => Settings::get(),
184 + // Live values for every wizard toggle, so re-running the
185 + // wizard reflects the site instead of overwriting it.
186 + 'current' => self::current_choices(),
182 187 'env' => self::env_payload(),
183 188 // xSpeed Hub connection snapshot for the wizard's first
184 189 // "Connect your account" step. Guarded so core onboarding
185 190 // never hard-depends on the MCP module — if it's absent the
@@ -191,8 +196,50 @@
191 196 );
192 197 }
193 198
194 199 /**
200 + * The site's CURRENT values for every toggle the wizard can write,
201 + * in the same shape as the wizard's OnboardingChoices.
202 + *
203 + * The wizard used to seed its toggles from hard-coded preset constants,
204 + * so re-running it on a configured site showed a fiction: options the
205 + * admin had deliberately switched on rendered as off, and Apply wrote
206 + * that fiction back, silently undoing their configuration. Nothing
207 + * warned them, and the completion screen still reported success.
208 + *
209 + * The wizard couldn't have done better on its own — the bootstrap only
210 + * carried Settings::get(), which is just cache_enabled. Every other
211 + * toggle lives in a per-module option the payload never included, so
212 + * this method is what makes "show the site as it actually is" possible.
213 + *
214 + * Pure read. Mirrors the keys apply() writes, so the two stay in step.
215 + *
216 + * @return array<string,bool|int>
217 + */
218 + public static function current_choices() {
219 + $minify = Settings_Manager::get( 'minify' );
220 + $gzip = Settings_Manager::get( 'gzip' );
221 + $cache = Settings_Manager::get( 'cache' );
222 + $lazy = Settings_Manager::get( 'lazy' );
223 + $browser = Settings_Manager::get( 'browser-cache' );
224 + $hints = Settings_Manager::get( 'resource-hints' );
225 + $settings = Settings::get();
226 +
227 + return array(
228 + 'cache_enabled' => ! empty( $settings['cache_enabled'] ),
229 + 'minify_html' => ! empty( $minify['minify_html'] ),
230 + 'minify_css' => ! empty( $minify['minify_css'] ),
231 + 'minify_js' => ! empty( $minify['minify_js'] ),
232 + 'defer_js' => ! empty( $minify['defer_js'] ),
233 + 'gzip_enabled' => ! empty( $gzip['gzip_enabled'] ),
234 + 'lazy_images' => ! empty( $lazy['lazy_images'] ),
235 + 'browser_cache' => ! empty( $browser['enabled'] ),
236 + 'resource_hints' => ! empty( $hints['enabled'] ),
237 + 'cache_expiry' => isset( $cache['cache_expiry'] ) ? absint( $cache['cache_expiry'] ) : \XSpeed\Modules\Cache\CacheModule::DEFAULT_EXPIRY_HOURS,
238 + );
239 + }
240 +
241 + /**
195 242 * Environment snapshot rendered as Step 1's health rows. Pure read —
196 243 * never writes to disk, never makes outbound requests.
197 244 */
198 245 public static function env_payload() {
@@ -323,8 +370,12 @@
323 370 // Opt-in usage analytics. Only acted on when the key is present in the
324 371 // payload (legacy onboarding-complete sites are left untouched). The
325 372 // consent toggle defaults OFF in the wizard, so the common path is
326 373 // usage_tracking=false → tracker stays dormant, no outbound HTTP.
374 + // (True since #437; before that the toggle shipped pre-checked and
375 + // this comment described an intent the UI did not implement. The
376 + // same consent is now also writable from Settings → Privacy & usage
377 + // data, via PrivacyModule, which routes through the same opt_in().)
327 378 if ( array_key_exists( 'usage_tracking', $params ) ) {
328 379 $tracker = Plugin::instance()->usage_tracker();
329 380 if ( $tracker ) {
330 381 $tracker->opt_in( ! empty( $params['usage_tracking'] ) );
@@ -331,9 +382,8 @@
331 382 }
332 383 }
333 384
334 385 $install_state = Cache::toggle( $want_cache );
335 - Settings::update( array( 'cache_enabled' => $install_state['enabled'] ) );
336 386
337 387 // Recompute the unified nginx block AFTER cache_enabled is persisted.
338 388 // Cache::toggle() computes it inline, before the Settings::update()
339 389 // above writes cache_enabled — so the block in $install_state reflects