get_all_settings(); if ( empty( $s['cache_stale_cleanup'] ) && empty( $s['page_cache_enabled'] ) && empty( $s['cache_enabled'] ) ) { $this->unschedule(); return; } // Always schedule when page cache is on so lifespan is enforced offline. $need = ! empty( $s['page_cache_enabled'] ) || ! empty( $s['cache_enabled'] ) || ! empty( $s['cache_stale_cleanup'] ); if ( ! $need ) { $this->unschedule(); return; } if ( ! wp_next_scheduled( self::CRON ) ) { wp_schedule_event( time() + 300, 'hourly', self::CRON ); } } /** * @param mixed $old Old. * @param mixed $new New. */ public function on_settings( $old, $new ) { $this->maybe_schedule(); } public function unschedule() { $ts = wp_next_scheduled( self::CRON ); while ( $ts ) { wp_unschedule_event( $ts, self::CRON ); $ts = wp_next_scheduled( self::CRON ); } } /** * Delete expired .html/.meta under cache dir. * * @param string $cache_dir Directory. * @param int $hours Lifespan hours (0 = only remove ancient > 30d). * @return int Files removed. */ public static function purge_expired_files( $cache_dir, $hours ) { $cache_dir = (string) $cache_dir; if ( '' === $cache_dir || ! is_dir( $cache_dir ) ) { return 0; } $hours = (int) $hours; $ttl = $hours > 0 ? $hours * ( defined( '\HOUR_IN_SECONDS' ) ? \HOUR_IN_SECONDS : 3600 ) : ( 30 * \DAY_IN_SECONDS ); if ( ! defined( '\DAY_IN_SECONDS' ) && $hours <= 0 ) { $ttl = 30 * 86400; } $now = time(); $removed = 0; $it = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( $cache_dir, \FilesystemIterator::SKIP_DOTS ) ); foreach ( $it as $file ) { if ( ! $file->isFile() ) { continue; } $name = $file->getFilename(); if ( ! preg_match( '/\.(html|meta\.json)$/', $name ) ) { continue; } $mtime = (int) $file->getMTime(); if ( ( $now - $mtime ) > $ttl ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink -- stale cache file cleanup. $path = $file->getPathname(); if ( is_file( $path ) && wp_delete_file( $path ) ) { ++$removed; } } } return $removed; } public function run() { $s = \QWSpeedCache\Plugin::instance()->get_all_settings(); $hours = (int) ( $s['cache_lifespan'] ?? 10 ); $cache_dir = defined( 'QWSC_CACHE_DIR' ) ? QWSC_CACHE_DIR : ( WP_CONTENT_DIR . '/cache/qw-speed-cache/' ); $n = self::purge_expired_files( $cache_dir, $hours ); if ( class_exists( '\QWSpeedCache\Stats\Logger' ) && $n > 0 ) { \QWSpeedCache\Stats\Logger::log( 'cache', 'stale_cleanup removed ' . $n ); } // Also temps/locks. if ( class_exists( '\QWSpeedCache\Cache\Engine' ) ) { $engine = new Engine(); $engine->cleanup_stale_temps(); } } }