__( 'WP Speed Cache', 'speednest' ), 'enabled' => true, 'size' => wpsco_get_dir_size( $base_dir ), 'size_text' => wpsco_format_size( wpsco_get_dir_size( $base_dir ) ), 'clearable' => true, ); // CSS cache. $css_dir = $base_dir . 'css/'; $status['css_cache'] = array( 'name' => __( 'CSS Cache', 'speednest' ), 'enabled' => wpsco_get_setting( 'css_minify', false ) || wpsco_get_setting( 'css_combine', false ), 'size' => wpsco_get_dir_size( $css_dir ), 'size_text' => wpsco_format_size( wpsco_get_dir_size( $css_dir ) ), 'clearable' => true, ); // JS cache. $js_dir = $base_dir . 'js/'; $status['js_cache'] = array( 'name' => __( 'JS Cache', 'speednest' ), 'enabled' => wpsco_get_setting( 'js_minify', false ) || wpsco_get_setting( 'js_combine', false ), 'size' => wpsco_get_dir_size( $js_dir ), 'size_text' => wpsco_format_size( wpsco_get_dir_size( $js_dir ) ), 'clearable' => true, ); // HTML cache. $html_dir = $base_dir . 'html/'; $status['html_cache'] = array( 'name' => __( 'HTML Cache', 'speednest' ), 'enabled' => wpsco_get_setting( 'page_cache_enabled', false ), 'size' => wpsco_get_dir_size( $html_dir ), 'size_text' => wpsco_format_size( wpsco_get_dir_size( $html_dir ) ), 'clearable' => true, ); // Critical CSS. $ccss_dir = $base_dir . 'critical-css/'; $status['critical_css'] = array( 'name' => __( 'Critical CSS', 'speednest' ), 'enabled' => wpsco_get_setting( 'css_critical', false ), 'size' => wpsco_get_dir_size( $ccss_dir ), 'size_text' => wpsco_format_size( wpsco_get_dir_size( $ccss_dir ) ), 'clearable' => true, ); // WordPress Object Cache. $status['object_cache'] = array( 'name' => __( 'WordPress Object Cache', 'speednest' ), 'enabled' => wp_using_ext_object_cache(), 'type' => $this->detect_object_cache_type(), 'clearable' => true, ); // Transients. $status['transients'] = array( 'name' => __( 'Transients', 'speednest' ), 'enabled' => true, 'count' => $this->count_transients(), 'clearable' => true, ); // OPcache. $opcache = wpsco_get_opcache_status(); $status['opcache'] = array( 'name' => __( 'PHP OPcache', 'speednest' ), 'enabled' => $opcache['enabled'], 'available' => $opcache['available'], 'can_reset' => $opcache['can_reset'], 'memory' => $opcache['memory_usage'], 'reason' => $opcache['reason'], 'clearable' => $opcache['can_reset'], ); // Server cache. $server_type = wpsco_get_server_type(); $status['server_cache'] = array( 'name' => __( 'Server Cache', 'speednest' ), 'server' => $server_type, 'clearable' => in_array( $server_type, array( 'litespeed', 'openlitespeed' ), true ), 'reason' => $this->get_server_cache_reason( $server_type ), ); // Cloudflare. $status['cloudflare'] = array( 'name' => __( 'Cloudflare', 'speednest' ), 'enabled' => wpsco_get_setting( 'cloudflare_enabled', false ), 'configured' => ! empty( wpsco_get_setting( 'cloudflare_api_token', '' ) ) && ! empty( wpsco_get_setting( 'cloudflare_zone_id', '' ) ), 'clearable' => wpsco_get_setting( 'cloudflare_enabled', false ), ); // CDN. $status['cdn'] = array( 'name' => __( 'CDN', 'speednest' ), 'enabled' => wpsco_get_setting( 'cdn_enabled', false ), 'url' => wpsco_get_setting( 'cdn_url', '' ), 'clearable' => ! empty( wpsco_get_setting( 'cdn_purge_endpoint', '' ) ), ); // Browser cache. $status['browser_cache'] = array( 'name' => __( 'Browser Cache', 'speednest' ), 'enabled' => true, 'note' => __( 'Browser cache cannot be cleared from the server. Asset versioning and cache-busting URLs ensure visitors receive the latest files.', 'speednest' ), 'clearable' => false, ); return $status; } /** * Detect object cache type. * * @return string */ public function detect_object_cache_type() { if ( ! wp_using_ext_object_cache() ) { return 'default'; } // Check for Redis. if ( class_exists( 'Redis' ) || class_exists( 'Predis\\Client' ) || defined( 'WP_REDIS_DISABLED' ) ) { return 'redis'; } // Check for Memcached. if ( class_exists( 'Memcached' ) || class_exists( 'Memcache' ) ) { return 'memcached'; } return 'external'; } /** * Count transients. * * @return array */ public function count_transients() { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Direct database query required to count total transients in options table. $total = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE '_transient_%' AND option_name NOT LIKE '_transient_timeout_%'" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Direct database query required to count expired transients in options table. $expired = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->options} a INNER JOIN {$wpdb->options} b ON b.option_name = CONCAT('_transient_timeout_', SUBSTRING(a.option_name, 12)) WHERE a.option_name LIKE %s AND a.option_name NOT LIKE %s AND b.option_value < %d", $wpdb->esc_like( '_transient_' ) . '%', $wpdb->esc_like( '_transient_timeout_' ) . '%', time() ) ); return array( 'total' => $total, 'expired' => $expired, ); } /** * Get server cache reason. * * @param string $server_type Server type. * @return string */ private function get_server_cache_reason( $server_type ) { switch ( $server_type ) { case 'litespeed': case 'openlitespeed': return __( 'LiteSpeed server cache can be purged via server headers.', 'speednest' ); case 'nginx': return __( 'NGINX FastCGI cache cannot be purged from WordPress. Please purge from your server or hosting control panel.', 'speednest' ); case 'apache': return __( 'Apache does not provide a server-level page cache purge API.', 'speednest' ); default: return __( 'Server type could not be determined.', 'speednest' ); } } /** * Get cache layer visualization data. * * @return array */ public function get_cache_layers() { return array( array( 'name' => __( 'Visitor Browser', 'speednest' ), 'icon' => 'dashicons-desktop', 'status' => __( 'Asset versioning active', 'speednest' ), 'type' => 'browser', ), array( 'name' => __( 'Cloudflare / CDN', 'speednest' ), 'icon' => 'dashicons-cloud', 'status' => wpsco_get_setting( 'cloudflare_enabled', false ) ? __( 'Connected', 'speednest' ) : __( 'Not configured', 'speednest' ), 'type' => 'cdn', ), array( 'name' => __( 'Server Cache', 'speednest' ), 'icon' => 'dashicons-admin-generic', 'status' => ucfirst( wpsco_get_server_type() ), 'type' => 'server', ), array( 'name' => __( 'WordPress Page Cache', 'speednest' ), 'icon' => 'dashicons-media-document', 'status' => wpsco_get_setting( 'page_cache_enabled', false ) ? __( 'Active', 'speednest' ) : __( 'Disabled', 'speednest' ), 'type' => 'page', ), array( 'name' => __( 'Object Cache', 'speednest' ), 'icon' => 'dashicons-database', 'status' => wp_using_ext_object_cache() ? sprintf( '%s (%s)', __( 'Active', 'speednest' ), $this->detect_object_cache_type() ) : __( 'Default', 'speednest' ), 'type' => 'object', ), array( 'name' => __( 'PHP OPcache', 'speednest' ), 'icon' => 'dashicons-editor-code', 'status' => wpsco_get_opcache_status()['enabled'] ? __( 'Enabled', 'speednest' ) : __( 'Disabled', 'speednest' ), 'type' => 'opcache', ), array( 'name' => __( 'WordPress', 'speednest' ), 'icon' => 'dashicons-wordpress-alt', 'status' => __( 'Application', 'speednest' ), 'type' => 'wordpress', ), ); } }