usable = $usable; $this->cacheEnabled = $cacheEnabled ?? static fn (): bool => ! empty($GLOBALS['cache_enabled']); $this->purgePost = $purgePost ?? static function (int $id): void { wp_cache_post_edit($id); }; $this->purgeAll = $purgeAll ?? static function (int $blog): void { wp_cache_clear_cache($blog); }; } public function cacheEnabled(): bool { return ($this->cacheEnabled)(); } /** Whether a whole-cache purge now would only be postponed. */ public function throttled(): bool { return self::within($this->lastPurge()); } private static function within(?int $last): bool { return $last !== null && time() - $last < self::THROTTLE; } /** Time of the last whole-cache purge; null = none within the lock time. Transients may come back as strings. */ private function lastPurge(): ?int { $last = get_transient(self::PURGED_AT); return is_numeric($last) ? (int) $last : null; } /** wp_cache_post_edit for one post; false = locked. Never throttled. */ public function post(int $postId): bool { if (! $this->allowed(SuperCacheFeature::PurgePost)) { return false; } ($this->purgePost)($postId); return true; } /** * Whole cache, at most every THROTTLE seconds. Inside the lock time one trailing purge is scheduled (cron events * are per site: the callback runs on this blog, no blog switch, wp_cache_clear_cache takes the blog ID). * * @return self::PURGED|self::THROTTLED|self::LOCKED */ public function everything(): string { if (! $this->allowed(SuperCacheFeature::PurgeAll)) { return self::LOCKED; } $last = $this->lastPurge(); if ($last !== null && self::within($last)) { if (wp_next_scheduled(self::TRAILING_HOOK) === false) { wp_schedule_single_event($last + self::THROTTLE, self::TRAILING_HOOK); } return self::THROTTLED; } // Known and unavoidable on a multisite: WPSC also empties the shared blogs/ meta directory of all sites // in its blog branch (wp-cache-phase2.php, wp_cache_clear_cache). ($this->purgeAll)(is_multisite() ? get_current_blog_id() : 0); set_transient(self::PURGED_AT, time(), self::THROTTLE); return self::PURGED; } private function allowed(SuperCacheFeature $feature): bool { if (($this->usable)($feature)) { return true; } if (! $this->warned) { $this->warned = true; Log::line(sprintf('WP Super Cache not purged: %s not usable (see tab Compatibility)', $feature->id())); } return false; } }