*/ public static function snapshot() { $settings = \QWSpeedCache\Plugin::instance()->get_all_settings(); $cache_files = 0; $cache_bytes = 0; $html_files = 0; $dir = defined( 'QWSC_CACHE_DIR' ) ? QWSC_CACHE_DIR : ''; if ( $dir && is_dir( $dir ) ) { $it = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( $dir, \FilesystemIterator::SKIP_DOTS ) ); foreach ( $it as $file ) { if ( $file->isFile() ) { ++$cache_files; $cache_bytes += $file->getSize(); if ( 'html' === $file->getExtension() ) { ++$html_files; } } } } $log = Logger::all(); $purges = 0; foreach ( $log as $row ) { if ( isset( $row['type'] ) && 'purge' === $row['type'] ) { ++$purges; } } $warmup = 0; if ( class_exists( '\\QWSpeedCache\\Preload\\Queue' ) ) { $warmup = count( \QWSpeedCache\Preload\Queue::get() ); } $opcode = array(); if ( class_exists( '\\QWSpeedCache\\Diagnostics\\Opcode' ) ) { $opcode = \QWSpeedCache\Diagnostics\Opcode::status(); } $last_purge = (int) get_option( 'qwsc_last_purge_at', 0 ); $conflicts = array(); if ( class_exists( '\\QWSpeedCache\\Safety\\ConflictDetector' ) ) { $conflicts = \QWSpeedCache\Safety\ConflictDetector::active_conflicts(); } $adv = array( 'installed' => false, 'ours' => false, 'wp_cache' => false ); if ( class_exists( '\\QWSpeedCache\\Cache\\AdvancedCache' ) ) { $adv = \QWSpeedCache\Cache\AdvancedCache::status(); } return array( 'version' => defined( 'QWSC_VERSION' ) ? QWSC_VERSION : '', 'page_cache' => ! empty( $settings['page_cache_enabled'] ) || ! empty( $settings['cache_enabled'] ), 'cache_files' => $cache_files, 'cache_html_files' => $html_files, 'cache_bytes' => $cache_bytes, 'cache_lifespan' => (int) ( $settings['cache_lifespan'] ?? 10 ), 'purge_events' => $purges, 'last_purge_at' => $last_purge, 'last_purge_human' => $last_purge ? self::human_ago( $last_purge ) : '', 'preload_queue' => $warmup, 'multisite' => is_multisite(), 'opcode' => $opcode, 'conflicts' => $conflicts, 'advanced_cache' => $adv, 'test_mode' => ! empty( $settings['test_mode'] ), 'delay_js' => ( \QWSpeedCache\Free\Extensions::pro_key_available( 'delay_js' ) && ! empty( $settings['delay_js'] ) ), 'js_safe_mode' => ! empty( $settings['js_safe_mode'] ), 'remove_unused_css' => ( \QWSpeedCache\Free\Extensions::pro_key_available( 'remove_unused_css' ) && ! empty( $settings['remove_unused_css'] ) ), 'object_cache' => class_exists( '\QWSpeedCache\ObjectCache\Dropin' ) ? \QWSpeedCache\ObjectCache\Dropin::status() : array(), 'preload_progress' => class_exists( '\QWSpeedCache\Preload\Manager' ) ? \QWSpeedCache\Preload\Manager::progress() : array(), 'last_events' => array_slice( array_reverse( $log ), 0, 10 ), ); } /** * Lightweight health checks for REST/CLI. * * @return array{ok:bool,checks:array} */ public static function health() { $checks = array(); $s = \QWSpeedCache\Plugin::instance()->get_all_settings(); $dir = defined( 'QWSC_CACHE_DIR' ) ? QWSC_CACHE_DIR : ''; $writable = $dir && ( is_dir( $dir ) ? wp_is_writable( $dir ) : wp_is_writable( dirname( $dir ) ) ); $checks[] = array( 'id' => 'cache_dir', 'ok' => (bool) $writable, 'message' => $writable ? 'Cache directory writable' : 'Cache directory not writable', ); $wp_cache = defined( 'WP_CACHE' ) && WP_CACHE; $adv_on = ! empty( $s['advanced_cache_enabled'] ); $adv_status = class_exists( '\\QWSpeedCache\\Cache\\AdvancedCache' ) ? \QWSpeedCache\Cache\AdvancedCache::status() : array( 'ours' => false, 'installed' => false, 'config_found' => false, 'config_writable' => false ); $checks[] = array( 'id' => 'wp_cache', 'ok' => ! $adv_on || $wp_cache, 'message' => $adv_on ? ( $wp_cache ? 'WP_CACHE enabled for advanced-cache' : 'advanced-cache enabled but WP_CACHE is false' ) : 'advanced-cache not required', ); $checks[] = array( 'id' => 'advanced_cache_dropin', 'ok' => ! $adv_on || ! empty( $adv_status['ours'] ), 'message' => ! $adv_on ? 'advanced-cache not required' : ( ! empty( $adv_status['ours'] ) ? 'QW Optimize advanced-cache drop-in installed' : ( ! empty( $adv_status['installed'] ) ? 'Another plugin owns advanced-cache.php' : 'QW Optimize advanced-cache drop-in missing' ) ), ); $conflicts = class_exists( '\\QWSpeedCache\\Safety\\ConflictDetector' ) ? \QWSpeedCache\Safety\ConflictDetector::active_conflicts() : array(); $checks[] = array( 'id' => 'conflicts', 'ok' => empty( $conflicts ), 'message' => empty( $conflicts ) ? 'No known conflicting plugins' : ( 'Conflicts: ' . implode( ', ', $conflicts ) ), ); $delay_ok = ! \QWSpeedCache\Free\Extensions::pro_key_available( 'delay_js' ) || empty( $s['delay_js'] ) || ! empty( $s['js_safe_mode'] ); $checks[] = array( 'id' => 'delay_js_safe', 'ok' => (bool) $delay_ok, 'message' => $delay_ok ? 'Delay JS safe' : 'Delay JS on without safe mode', ); $php_ok = version_compare( PHP_VERSION, '7.4', '>=' ); $checks[] = array( 'id' => 'php_version', 'ok' => $php_ok, 'message' => 'PHP ' . PHP_VERSION, ); $ok = true; foreach ( $checks as $c ) { if ( empty( $c['ok'] ) ) { $ok = false; break; } } return array( 'ok' => $ok, 'version' => defined( 'QWSC_VERSION' ) ? QWSC_VERSION : '', 'checks' => $checks, ); } /** * @param int $ts Unix time. * @return string */ public static function human_ago( $ts ) { $ts = (int) $ts; if ( $ts <= 0 ) { return ''; } $diff = max( 0, time() - $ts ); if ( $diff < 60 ) { return $diff . 's ago'; } if ( $diff < 3600 ) { return (int) floor( $diff / 60 ) . 'm ago'; } if ( $diff < 86400 ) { return (int) floor( $diff / 3600 ) . 'h ago'; } return (int) floor( $diff / 86400 ) . 'd ago'; } }