watched_options() as $option_name) { add_action('update_option_' . $option_name, array($this, 'queue_purge'), 10, 0); add_action('add_option_' . $option_name, array($this, 'queue_purge'), 10, 0); } add_action(self::DEFERRED_EVENT, array($this, 'purge_page_caches')); } /** * Option names whose writes trigger a page-cache purge. * * @return string[] */ private function watched_options() { $options = apply_filters('mxchat_cache_purge_watched_options', array('mxchat_options')); return is_array($options) ? array_filter(array_map('strval', $options)) : array('mxchat_options'); } /** * Coalesce all option writes in this request into one shutdown purge. */ public function queue_purge() { if ($this->purge_queued) { return; } $this->purge_queued = true; add_action('shutdown', array($this, 'run_queued_purge'), 5); } /** * Shutdown handler: purge unless one ran inside the debounce window; in * that case schedule a single deferred purge so the last write still wins. */ public function run_queued_purge() { if (get_transient(self::DEBOUNCE_TRANSIENT)) { if (!wp_next_scheduled(self::DEFERRED_EVENT)) { wp_schedule_single_event(time() + self::DEBOUNCE_SECONDS, self::DEFERRED_EVENT); } return; } set_transient(self::DEBOUNCE_TRANSIENT, 1, self::DEBOUNCE_SECONDS); $this->purge_page_caches(); } /** * Purge every supported page cache via its own public API. Each call is * guarded so installs without that plugin skip it silently. */ public function purge_page_caches() { // WP Rocket — public helper, clears the whole domain's page cache. if (function_exists('rocket_clean_domain')) { rocket_clean_domain(); } // LiteSpeed Cache — documented third-party purge API. if (defined('LSCWP_V') || class_exists('LiteSpeed\Core')) { do_action('litespeed_purge_all'); } // W3 Total Cache — page-cache flush helper. if (function_exists('w3tc_pgcache_flush')) { w3tc_pgcache_flush(); } // WP Super Cache — global cache clear. if (function_exists('wp_cache_clear_cache')) { wp_cache_clear_cache(); } // FlyingPress — documented programmatic purge (purge_pages clears the // HTML page cache without rebuilding optimized assets): // https://docs.flyingpress.com/en/articles/11406092-programmatically-purge-and-preload-cache if (class_exists('\FlyingPress\Purge') && method_exists('\FlyingPress\Purge', 'purge_pages')) { \FlyingPress\Purge::purge_pages(); } // Extension point for CDNs / host caches / custom setups. do_action('mxchat_purge_page_caches'); } }