PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.3.6
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.3.6
1.3.6 1.3.5 1.3.4 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 All 32 releases
← All changes | includes/class-rest-api.php +34 -7 1.1.5 → 1.3.6 View file →
@@ -425,8 +425,13 @@
425 425 'nginx_snippet' => Gzip::nginx_snippet(),
426 426 ),
427 427 'rewrite_probe' => $rewrite_probe,
428 428 'nginx_server_block' => Cache::full_nginx_server_block(),
429 + // What enabling the page cache would do to
430 + // wp-content/advanced-cache.php. The dashboard discloses the
431 + // replacement BEFORE the write when a leftover drop-in is
432 + // already there; see Page_Cache_Detector::dropin_disclosure().
433 + 'dropin' => Page_Cache_Detector::dropin_disclosure(),
429 434 // Separate Mobile Cache visibility (FBS-83145). `blocking` is
430 435 // true when mobile_separate is what's keeping the device-blind
431 436 // static fast path from installing on a rewrite-capable server;
432 437 // `needs_review` is true when a migration turned it on for us and
@@ -433,9 +438,16 @@
433 438 // the user hasn't confirmed they actually need it. The dashboard
434 439 // renders a callout (+ "Check now" equality probe) from these.
435 440 'mobile_separate' => array(
436 441 'enabled' => ! empty( Settings::get()['cache_enabled'] ) ? (bool) ( Settings_Manager::get( 'cache' )['mobile_separate'] ?? false ) : false,
437 - 'blocking' => $rewrite_capable && 'mobile_separate' === Cache::static_rewrite_block_reason(),
442 + // Gated to servers that HAVE a static fast path — see the
443 + // matching comment in Admin::bootstrap_payload(): on IIS /
444 + // unknown, block_reason still falls through to
445 + // mobile_separate and reporting it as "blocking" would nag
446 + // about a rewrite that does not exist there (#108).
447 + // LiteSpeed joined the capable set with the opt-in (#509).
448 + 'blocking' => ( $rewrite_capable || Server::LITESPEED === $server_type )
449 + && 'mobile_separate' === Cache::static_rewrite_block_reason(),
438 450 'needs_review' => Cache::mobile_separate_needs_review(),
439 451 ),
440 452 )
441 453 );
@@ -459,10 +471,19 @@
459 471 return rest_ensure_response( $updated );
460 472 }
461 473
462 474 public function purge() {
463 - Cache::purge_all( __( 'dashboard', 'xspeed' ) );
464 - return rest_ensure_response( array( 'stats' => Cache::get_stats() ) );
475 + // The same core function `wp xspeed purge` runs, so the dashboard
476 + // button and the CLI cannot clear different sets of stores — and the
477 + // per-store report is available here for the UI to surface a store
478 + // that was skipped or refused rather than flashing "cache cleared".
479 + $report = Purge_Runner::run( array( 'all' ), __( 'dashboard', 'xspeed' ) );
480 + return rest_ensure_response(
481 + array(
482 + 'stats' => Cache::get_stats(),
483 + 'report' => $report,
484 + )
485 + );
465 486 }
466 487
467 488 /**
468 489 * The "Cached Pages" drill-down: which pages are cached and how old they
@@ -540,9 +561,9 @@
540 561 // permission_callback above already enforced current_user_can(
541 562 // 'manage_options' ); the REST nonce is verified by core via the
542 563 // X-WP-Nonce header.
543 564 $state = Cache::toggle( $enabled );
544 - $updated = Settings::update( array( 'cache_enabled' => $state['enabled'] ) );
565 + $updated = Settings::get();
545 566
546 567 // Recompute the unified nginx block AFTER cache_enabled is persisted.
547 568 // Cache::toggle() computes it inline, but cache_enabled isn't written
548 569 // until the Settings::update() above — so the block inside $state
@@ -552,11 +573,17 @@
552 573 $state['nginx_server_block'] = Cache::full_nginx_server_block();
553 574
554 575 return rest_ensure_response(
555 576 array(
556 - 'enabled' => $updated['cache_enabled'],
557 - 'stats' => Cache::get_stats(),
558 - 'install_state' => $state,
577 + 'enabled' => $updated['cache_enabled'],
578 + // Surfaced at the top level so the dashboard can explain a
579 + // refusal rather than silently snapping the toggle back:
580 + // Cache::toggle() writes nothing when another plugin owns the
581 + // drop-in or WP_CACHE is in a shape we must not rewrite.
582 + 'blocked' => ! empty( $state['blocked'] ),
583 + 'blocked_reason' => $state['blocked_reason'] ?? null,
584 + 'stats' => Cache::get_stats(),
585 + 'install_state' => $state,
559 586 )
560 587 );
561 588 }
562 589 }