| @@ -80,8 +80,11 @@ | ||
| 80 | 80 | // Single-URL purge entry points — row actions, the edit-screen |
| 81 | 81 | // button and the admin-post handler the admin-bar item also uses. |
| 82 | 82 | Purge_Ui::boot(); |
| 83 | 83 | |
| 84 | + // While the page cache is off, every admin page says so (#594). | |
| 85 | + Cache_Off_Notice::boot(); | |
| 86 | + | |
| 84 | 87 | // Phase 0 architecture — managers + Free modules. v1 services |
| 85 | 88 | // (Cache/Minifier/Gzip) are NOT yet Modules; they'll be refactored |
| 86 | 89 | // in a follow-up PR with parity tests. |
| 87 | 90 | Conflict_Registry::boot(); |
| @@ -103,8 +106,15 @@ | ||
| 103 | 106 | // purge that runs after an import, which the nginx adapter's import |
| 104 | 107 | // gate stands down in favour of. |
| 105 | 108 | Server_Caches::boot(); |
| 106 | 109 | |
| 110 | + // Remembers the terms a post had before a save, so a narrow purge | |
| 111 | + // can clear the category it left as well as the one it joined. | |
| 112 | + Affected_Pages::boot(); | |
| 113 | + // Records which pages run a post list of their own (a page builder | |
| 114 | + // grid, a related-posts block), so a narrow purge clears them too. | |
| 115 | + Listing_Pages::boot(); | |
| 116 | + | |
| 107 | 117 | // Tell WP Statistics and Slimstat not to count the warmer, the |
| 108 | 118 | // benchmark and the verifier as visitors. Record-time filters only; |
| 109 | 119 | // see the class for why the tracking snippet itself is left alone. |
| 110 | 120 | Self_Traffic::boot(); |
| @@ -202,9 +212,40 @@ | ||
| 202 | 212 | // outlives it: nothing purges on upgrade, and the static serve path |
| 203 | 213 | // never revalidates. Clear the tree once. The flat cache is keyed |
| 204 | 214 | // correctly and is deliberately left alone. (issue #191) |
| 205 | 215 | if ( version_compare( $current, '1.1.6', '<' ) ) { |
| 206 | - Cache::purge_static_tree(); | |
| 216 | + $removed = Cache::purge_static_tree(); | |
| 217 | + | |
| 218 | + /* | |
| 219 | + * And tell anything caching in front of us, because the poisoned | |
| 220 | + * entry is exactly the kind that reaches an edge: the web server | |
| 221 | + * served it straight off disk as the homepage, so a CDN in front had | |
| 222 | + * every opportunity to store it. Deleting our copy leaves that one | |
| 223 | + * untouched, and the edge's lifetime is the longer of the two. | |
| 224 | + * | |
| 225 | + * Announced on `init` rather than here. This runs at | |
| 226 | + * `plugins_loaded` 21, before an add-on has wired its purge | |
| 227 | + * listeners, so firing it inline would announce to an empty room. | |
| 228 | + * Priority 99 puts it after any reasonable `init` registration. | |
| 229 | + * | |
| 230 | + * Once per site, on the upgrade that clears the tree — never again, | |
| 231 | + * since the data version is written immediately below. | |
| 232 | + * | |
| 233 | + * Through `Cache::announce_purge()` rather than a bare `do_action`, | |
| 234 | + * because the purge-event contract (#348) is more than the payload: | |
| 235 | + * it forwards to the server caches by direct call before the public | |
| 236 | + * action runs, and it isolates listeners so one throwing add-on | |
| 237 | + * cannot fatal the first admin request after an update. A raw | |
| 238 | + * publish here would skip both and hand listeners the pre-contract | |
| 239 | + * payload shape. | |
| 240 | + */ | |
| 241 | + add_action( | |
| 242 | + 'init', | |
| 243 | + static function () use ( $removed ) { | |
| 244 | + Cache::announce_purge( 'static cache repaired on upgrade', $removed ); | |
| 245 | + }, | |
| 246 | + 99 | |
| 247 | + ); | |
| 207 | 248 | } |
| 208 | 249 | |
| 209 | 250 | // 1.3.6 — new click and campaign IDs in the default ignored list. |
| 210 | 251 | // A site that ever saved the Cache panel has its own copy of the list, |
| @@ -490,8 +531,22 @@ | ||
| 490 | 531 | * @param string $profile Settings::PROFILE_* — which profile a fresh |
| 491 | 532 | * install came up with, '' if not fresh. |
| 492 | 533 | */ |
| 493 | 534 | do_action( 'xspeed_activated', $installed_by, $profile ); |
| 535 | + | |
| 536 | + /* | |
| 537 | + * Announce the change to anything caching in front of us. | |
| 538 | + * | |
| 539 | + * Activation writes the default settings and activates modules, so | |
| 540 | + * every URL on the site starts returning different HTML. A CDN | |
| 541 | + * holding renders from before goes on serving them for their whole | |
| 542 | + * lifetime, and nothing told it. | |
| 543 | + * | |
| 544 | + * Cheap on a fresh install — there is nothing to sweep — and the | |
| 545 | + * case it exists for is reactivation on a site that has been running | |
| 546 | + * for months behind an edge. | |
| 547 | + */ | |
| 548 | + Cache::purge_all( 'plugin activated' ); | |
| 494 | 549 | } |
| 495 | 550 | |
| 496 | 551 | /** |
| 497 | 552 | * Restore the cache drop-in right after THIS plugin is updated. |
| @@ -534,9 +589,14 @@ | ||
| 534 | 589 | |
| 535 | 590 | Cache::restore_dropin_if_enabled(); |
| 536 | 591 | } |
| 537 | 592 | |
| 538 | - public static function deactivate() { | |
| 593 | + /** | |
| 594 | + * @param bool $network_wide Whether a network admin deactivated the | |
| 595 | + * plugin for every site (WordPress passes this | |
| 596 | + * to deactivation hooks). | |
| 597 | + */ | |
| 598 | + public static function deactivate( $network_wide = false ) { | |
| 539 | 599 | // Drop-in + WP_CACHE constant are NOT touched here. WordPress |
| 540 | 600 | // upgrades run as deactivate → wipe files → install → activate, |
| 541 | 601 | // so removing those artifacts on every deactivate would silently |
| 542 | 602 | // disable caching after each plugin update. uninstall.php |
| @@ -543,9 +603,16 @@ | ||
| 543 | 603 | // handles full teardown when the user actually removes the |
| 544 | 604 | // plugin; auto_heal() restores state on the next admin_init if |
| 545 | 605 | // the drop-in or WP_CACHE went missing for any other reason. |
| 546 | 606 | Cache::purge_all(); |
| 547 | - Minifier::purge_minified(); | |
| 607 | + // purge_all() is site-scoped and no longer touches min/, so clear it | |
| 608 | + // here. On a network where only this site is deactivating, the other | |
| 609 | + // sites still link those files: drop this site's manifests only. | |
| 610 | + if ( is_multisite() && ! $network_wide ) { | |
| 611 | + Minifier::purge_manifests( Asset_Manifest::blog_id() ); | |
| 612 | + } else { | |
| 613 | + Minifier::purge_minified(); | |
| 614 | + } | |
| 548 | 615 | Gzip::apply( false ); |
| 549 | 616 | |
| 550 | 617 | Module_Registry::deactivate_all(); |
| 551 | 618 | } |