| @@ -322,8 +322,62 @@ | ||
| 322 | 322 | ); |
| 323 | 323 | } |
| 324 | 324 | } |
| 325 | 325 | |
| 326 | + /* | |
| 327 | + * A full-page cache owned by the WEB SERVER, in front of PHP. | |
| 328 | + * | |
| 329 | + * Reported only when it is actually there, because it is a fact about | |
| 330 | + * the host rather than a setting the admin can act on from here — an | |
| 331 | + * "absent" row would be noise on the ~99% of sites that have no such | |
| 332 | + * layer. When it IS there it outranks almost everything else on this | |
| 333 | + * panel: nginx answers before WordPress runs, so what a visitor sees | |
| 334 | + * is decided by that cache and not by anything xSpeed reports about | |
| 335 | + * its own. | |
| 336 | + * | |
| 337 | + * The severity is about DOUBLE full-page caching, not about the layer | |
| 338 | + * existing. Two independent full-page caches stacked in front of one | |
| 339 | + * site have independent TTLs, and the outer one can re-serve HTML the | |
| 340 | + * inner one has already regenerated — the classic "I purged and it is | |
| 341 | + * still stale" report. With xSpeed's own page cache off there is only | |
| 342 | + * one layer and nothing to warn about, so that case is INFO. | |
| 343 | + */ | |
| 344 | + $host_cache_path = Host_Page_Caches::nginx_helper_cache_path(); | |
| 345 | + if ( null !== $host_cache_path ) { | |
| 346 | + $detail = $cache_enabled | |
| 347 | + ? 'Your server is running its own full-page cache in nginx (FastCGI), managed by the Nginx Helper plugin your host installed — so this site has TWO full-page caches stacked in front of it. xSpeed forwards every Purge All to the server layer, but the two expire on their own schedules (the server side is typically an hour), so a page can still be served from nginx after xSpeed has regenerated it. If edits keep looking stale, purge from your host\'s dashboard too, or turn xSpeed\'s page cache off and let the server layer do the work — it is the faster of the two, because it answers before PHP starts.' | |
| 348 | + : 'Your server is running a full-page cache in nginx (FastCGI), managed by the Nginx Helper plugin your host installed. xSpeed\'s own page cache is off, so this is the only full-page cache in front of the site — and it is the fastest kind, answering before PHP starts. Purge All in xSpeed still clears it.'; | |
| 349 | + | |
| 350 | + // Path prefix as a fingerprint for the WORDING only — never as a | |
| 351 | + // gate. Nginx Helper is not xCloud-only; other hosts and manual | |
| 352 | + // installs use it with a cache directory somewhere else entirely. | |
| 353 | + if ( 0 === strpos( $host_cache_path, '/etc/nginx/cache/' ) ) { | |
| 354 | + $detail .= sprintf( ' Cache directory: %s (the layout xCloud provisions).', $host_cache_path ); | |
| 355 | + } else { | |
| 356 | + $detail .= sprintf( ' Cache directory: %s.', $host_cache_path ); | |
| 357 | + } | |
| 358 | + | |
| 359 | + // The purge is a direct unlink by the PHP-FPM user against a | |
| 360 | + // directory nginx owns. Whether that user can write there is a | |
| 361 | + // property of the host we cannot test from here without deleting | |
| 362 | + // someone's cache to find out, so say what to check rather than | |
| 363 | + // claiming an outcome either way. | |
| 364 | + if ( 'unlink_files' === Host_Page_Caches::nginx_helper_purge_method() ) { | |
| 365 | + $detail .= ' The server cache is purged by deleting its files directly, which needs PHP to have write access to that directory — if a purge here never changes what nginx serves, that permission is the thing to check with your host.'; | |
| 366 | + } | |
| 367 | + | |
| 368 | + if ( is_multisite() ) { | |
| 369 | + $detail .= ' On multisite, nginx keys one cache per install rather than per site, so this purge clears every site on the network.'; | |
| 370 | + } | |
| 371 | + | |
| 372 | + $out[] = array( | |
| 373 | + 'id' => 'host_page_cache', | |
| 374 | + 'tone' => $cache_enabled ? self::WARN : self::INFO, | |
| 375 | + 'label' => 'Server-level page cache (nginx FastCGI)', | |
| 376 | + 'detail' => $detail, | |
| 377 | + ); | |
| 378 | + } | |
| 379 | + | |
| 326 | 380 | // Cache expiry vs preloader schedule (deterministic rule, issue #31): |
| 327 | 381 | // pages that expire faster than the preloader re-warms them leave the |
| 328 | 382 | // cache cold for most real traffic — the classic "24.8% hit ratio with |
| 329 | 383 | // everything on" misconfiguration. Pure logic in |