'', 'compare_url' => '', 'email_alerts_enabled' => '0', 'alert_email' => get_option('admin_email'), 'alert_score_threshold' => 75, 'alert_cache_threshold' => 60, 'alert_when_page_cache_missing' => '1', 'alert_when_object_cache_missing' => '0', 'alert_frequency' => 'daily', 'weekly_report_enabled' => '0', ); $saved = get_option(AGEROTH_SH_OPTION_SETTINGS, array()); return wp_parse_args(is_array($saved) ? $saved : array(), $defaults); } function ageroth_sh_confidence_label($c){$c=(int)$c; if($c>=65)return'High'; if($c>=25)return'Medium'; return'Low';} function ageroth_sh_human_ms($seconds){return round(((float)$seconds)*1000).' ms';} function ageroth_sh_timing_signal_label($s){if($s==='strong')return'Strong'; if($s==='weak')return'Moderate'; return'Too Fast to Judge';} function ageroth_sh_timing_interpretation($s){if($s==='strong') return 'Strong timing hint'; if($s==='weak') return 'Moderate timing hint'; return 'Too fast to judge';} function ageroth_sh_is_plugin_active_slug($slug){if(!function_exists('is_plugin_active')) require_once ABSPATH.'wp-admin/includes/plugin.php'; return function_exists('is_plugin_active') && is_plugin_active($slug);} function ageroth_sh_sanitize_settings($input){ $output = array(); $input = is_array($input) ? $input : array(); $output['test_url'] = isset($input['test_url']) ? sanitize_text_field(wp_unslash($input['test_url'])) : ''; $output['compare_url'] = isset($input['compare_url']) ? sanitize_text_field(wp_unslash($input['compare_url'])) : ''; $output['email_alerts_enabled'] = !empty($input['email_alerts_enabled']) ? '1' : '0'; $email = isset($input['alert_email']) ? sanitize_email(wp_unslash($input['alert_email'])) : ''; $output['alert_email'] = is_email($email) ? $email : get_option('admin_email'); $score_threshold = isset($input['alert_score_threshold']) ? absint($input['alert_score_threshold']) : 75; $cache_threshold = isset($input['alert_cache_threshold']) ? absint($input['alert_cache_threshold']) : 60; $output['alert_score_threshold'] = max(1, min(100, $score_threshold)); $output['alert_cache_threshold'] = max(1, min(100, $cache_threshold)); $output['alert_when_page_cache_missing'] = !empty($input['alert_when_page_cache_missing']) ? '1' : '0'; $output['alert_when_object_cache_missing'] = !empty($input['alert_when_object_cache_missing']) ? '1' : '0'; $allowed_frequency = array('daily', 'weekly', 'changes_only'); $frequency = isset($input['alert_frequency']) ? sanitize_key(wp_unslash($input['alert_frequency'])) : 'daily'; $output['alert_frequency'] = in_array($frequency, $allowed_frequency, true) ? $frequency : 'daily'; $output['weekly_report_enabled'] = !empty($input['weekly_report_enabled']) ? '1' : '0'; return $output; } function ageroth_sh_normalize_url($value){$value=trim((string)$value); if($value==='') return home_url('/'); if(preg_match('#^https?://#i',$value)) return esc_url_raw($value); return home_url('/' . ltrim($value, '/'));} add_action('admin_menu', function(){ add_menu_page('Ageroth Site Health','Site Health+','manage_options','ageroth-site-health','ageroth_sh_render_dashboard','dashicons-heart',58); add_submenu_page('ageroth-site-health','Ageroth Site Health','Dashboard','manage_options','ageroth-site-health','ageroth_sh_render_dashboard'); add_submenu_page('ageroth-site-health','Ageroth Site Health Settings','Settings','manage_options','ageroth-site-health-settings','ageroth_sh_render_settings'); }); add_action('admin_enqueue_scripts', function($hook){ if (strpos((string)$hook,'ageroth-site-health')===false) return; wp_enqueue_style('ageroth-sh-admin', AGEROTH_SH_URL.'assets/admin.css', [], AGEROTH_SH_VERSION); }); add_filter('plugin_action_links_' . plugin_basename(__FILE__), function($links){ $custom = [ 'Dashboard', 'Settings', ]; return array_merge($custom, $links); }); add_action('admin_init', function(){ register_setting('ageroth_sh_settings_group', AGEROTH_SH_OPTION_SETTINGS, array('sanitize_callback' => 'ageroth_sh_sanitize_settings')); if (!current_user_can('manage_options')) return; if (!empty($_POST['ageroth_sh_run_test']) && check_admin_referer('ageroth_sh_run_test')) { $settings = ageroth_sh_get_settings(); $settings['test_url'] = sanitize_text_field(wp_unslash($_POST['test_url'] ?? '')); $settings['compare_url'] = sanitize_text_field(wp_unslash($_POST['compare_url'] ?? '')); update_option(AGEROTH_SH_OPTION_SETTINGS, $settings, false); wp_safe_redirect(admin_url('admin.php?page=ageroth-site-health')); exit; } if (!empty($_POST['ageroth_sh_use_homepage']) && check_admin_referer('ageroth_sh_use_homepage')) { $settings = ageroth_sh_get_settings(); $settings['test_url'] = ''; update_option(AGEROTH_SH_OPTION_SETTINGS, $settings, false); wp_safe_redirect(admin_url('admin.php?page=ageroth-site-health')); exit; } if (!empty($_POST['ageroth_sh_send_test_alert']) && check_admin_referer('ageroth_sh_send_test_alert')) { ageroth_sh_run_email_alert_check(true); wp_safe_redirect(admin_url('admin.php?page=ageroth-site-health-settings&ageroth_sh_test_alert=sent')); exit; } if (!empty($_POST['ageroth_sh_send_weekly_report_now']) && check_admin_referer('ageroth_sh_send_weekly_report_now')) { ageroth_sh_send_weekly_health_report(true); wp_safe_redirect(admin_url('admin.php?page=ageroth-site-health-settings&ageroth_sh_weekly_report=sent')); exit; } if (!empty($_POST['ageroth_sh_save_feedback']) && check_admin_referer('ageroth_sh_save_feedback')) { $msg = sanitize_textarea_field(wp_unslash($_POST['ageroth_sh_feedback'] ?? '')); if ($msg !== '') { $items = get_option(AGEROTH_SH_OPTION_FEEDBACK, []); if (!is_array($items)) $items = []; array_unshift($items, ['message'=>$msg,'created_at'=>current_time('mysql')]); $items = array_slice($items, 0, 8); update_option(AGEROTH_SH_OPTION_FEEDBACK, $items, false); } wp_safe_redirect(admin_url('admin.php?page=ageroth-site-health')); exit; } }); register_activation_hook(__FILE__, 'ageroth_sh_activate_alert_cron'); register_deactivation_hook(__FILE__, 'ageroth_sh_deactivate_alert_cron'); function ageroth_sh_activate_alert_cron() { if (!wp_next_scheduled(AGEROTH_SH_CRON_HOOK)) { wp_schedule_event(time() + HOUR_IN_SECONDS, 'daily', AGEROTH_SH_CRON_HOOK); wp_schedule_event(time() + DAY_IN_SECONDS, 'weekly', AGEROTH_SH_WEEKLY_CRON_HOOK); } } function ageroth_sh_deactivate_alert_cron() { $timestamp = wp_next_scheduled(AGEROTH_SH_CRON_HOOK); if ($timestamp) { wp_unschedule_event($timestamp, AGEROTH_SH_CRON_HOOK); $weekly_timestamp = wp_next_scheduled(AGEROTH_SH_WEEKLY_CRON_HOOK); if ($weekly_timestamp) { wp_unschedule_event($weekly_timestamp, AGEROTH_SH_WEEKLY_CRON_HOOK); } } } add_filter('cron_schedules', 'ageroth_sh_cron_schedules'); function ageroth_sh_cron_schedules($schedules) { if (!isset($schedules['weekly'])) { $schedules['weekly'] = array('interval' => WEEK_IN_SECONDS, 'display' => 'Once Weekly'); } return $schedules; } add_action(AGEROTH_SH_CRON_HOOK, 'ageroth_sh_run_email_alert_check'); add_action(AGEROTH_SH_WEEKLY_CRON_HOOK, 'ageroth_sh_send_weekly_health_report'); function ageroth_sh_alert_state() { $state = get_option(AGEROTH_SH_OPTION_ALERT_STATE, array()); return is_array($state) ? $state : array(); } function ageroth_sh_update_alert_state($state) { update_option(AGEROTH_SH_OPTION_ALERT_STATE, is_array($state) ? $state : array(), false); } function ageroth_sh_run_email_alert_check($force_send = false) { $settings = ageroth_sh_get_settings(); if (empty($settings['email_alerts_enabled']) && !$force_send) { return false; } $email = isset($settings['alert_email']) ? $settings['alert_email'] : ''; if (!is_email($email)) { return false; } $report = ageroth_sh_build_report(); $issues = ageroth_sh_get_alert_issues($report, $settings); if (empty($issues) && !$force_send) { ageroth_sh_update_alert_state(array( 'last_checked' => current_time('mysql'), 'last_status' => 'healthy', 'last_issues_hash' => '', )); return false; } if ($force_send && empty($issues)) { $issues[] = 'Test alert: no critical health issues were detected at this time.'; } $issues_hash = md5(wp_json_encode($issues)); $state = ageroth_sh_alert_state(); $frequency = isset($settings['alert_frequency']) ? $settings['alert_frequency'] : 'daily'; $last_sent = isset($state['last_sent_time']) ? absint($state['last_sent_time']) : 0; $last_hash = isset($state['last_issues_hash']) ? (string) $state['last_issues_hash'] : ''; if (!$force_send) { if ($frequency === 'changes_only' && $last_hash === $issues_hash) { return false; } if ($frequency === 'daily' && $last_sent > 0 && (time() - $last_sent) < DAY_IN_SECONDS && $last_hash === $issues_hash) { return false; } if ($frequency === 'weekly' && $last_sent > 0 && (time() - $last_sent) < WEEK_IN_SECONDS && $last_hash === $issues_hash) { return false; } } $subject = sprintf('[%s] Ageroth Site Health Alert', wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES)); $body = ageroth_sh_build_alert_email_body($report, $issues); $sent = wp_mail($email, $subject, $body); $state = array( 'last_checked' => current_time('mysql'), 'last_sent' => $sent ? current_time('mysql') : '', 'last_sent_time' => $sent ? time() : $last_sent, 'last_status' => $sent ? 'sent' : 'failed', 'last_issues_hash' => $issues_hash, 'last_issues' => $issues, ); ageroth_sh_update_alert_state($state); return $sent; } function ageroth_sh_get_alert_issues($report, $settings) { $issues = array(); $score = isset($report['score']) ? absint($report['score']) : 0; $score_threshold = isset($settings['alert_score_threshold']) ? absint($settings['alert_score_threshold']) : 75; if ($score > 0 && $score < $score_threshold) { $issues[] = sprintf('Overall health score is %d, below your alert threshold of %d.', $score, $score_threshold); } $cache_score = isset($report['score_breakdown']['Caching']) ? absint($report['score_breakdown']['Caching']) : 0; $cache_threshold = isset($settings['alert_cache_threshold']) ? absint($settings['alert_cache_threshold']) : 60; if ($cache_score > 0 && $cache_score < $cache_threshold) { $issues[] = sprintf('Caching score is %d, below your alert threshold of %d.', $cache_score, $cache_threshold); } if (!empty($settings['alert_when_page_cache_missing']) && isset($report['primary_page_cache']) && $report['primary_page_cache'] === 'None detected') { $issues[] = 'Primary page cache is no longer detected.'; } if (!empty($settings['alert_when_object_cache_missing']) && isset($report['primary_object_cache']) && $report['primary_object_cache'] === 'None detected') { $issues[] = 'Persistent object cache is not detected.'; } return array_values(array_unique($issues)); } function ageroth_sh_build_alert_email_body($report, $issues) { $lines = array(); $lines[] = 'Ageroth Site Health detected a change or issue that matches your alert settings.'; $lines[] = ''; $lines[] = 'Site: ' . home_url('/'); $lines[] = 'Overall Score: ' . (isset($report['score']) ? $report['score'] : 'Unknown'); $lines[] = 'Page Cache: ' . (isset($report['primary_page_cache']) ? $report['primary_page_cache'] : 'Unknown'); $lines[] = 'Object Cache: ' . (isset($report['primary_object_cache']) ? $report['primary_object_cache'] : 'Unknown'); $lines[] = 'Generated: ' . (isset($report['generated_at']) ? $report['generated_at'] : current_time('mysql')); $lines[] = ''; $lines[] = 'Issues:'; foreach ($issues as $issue) { $lines[] = '- ' . $issue; } if (!empty($report['recommendations'])) { $lines[] = ''; $lines[] = 'Recommendations:'; foreach ($report['recommendations'] as $recommendation) { $lines[] = '- ' . $recommendation; } } $lines[] = ''; $lines[] = 'Open WordPress admin to review the full report.'; $lines[] = 'This email was generated locally by the Ageroth Site Health plugin. No data was sent to external services.'; return implode("\n", $lines); } function ageroth_sh_detect_page_cache() { $map = [ 'wp-fastest-cache/wpFastestCache.php'=>'WP Fastest Cache', 'litespeed-cache/litespeed-cache.php'=>'LiteSpeed Cache', 'wp-rocket/wp-rocket.php'=>'WP Rocket', 'w3-total-cache/w3-total-cache.php'=>'W3 Total Cache', 'wp-super-cache/wp-cache.php'=>'WP Super Cache', 'sg-cachepress/sg-cachepress.php'=>'SiteGround Optimizer', 'breeze/breeze.php'=>'Breeze', 'cache-enabler/cache-enabler.php'=>'Cache Enabler', 'hummingbird-performance/wp-hummingbird.php'=>'Hummingbird', 'swift-performance-lite/performance.php'=>'Swift Performance', 'flying-press/flying-press.php'=>'FlyingPress', 'wp-optimize/wp-optimize.php'=>'WP-Optimize', 'autoptimize/autoptimize.php'=>'Autoptimize' ]; $signals=[]; $primary='None detected'; foreach($map as $slug=>$name){ if(ageroth_sh_is_plugin_active_slug($slug)){ $primary=$name; $signals[]='Active plugin: '.$name; break; } } if(defined('WP_CACHE') && WP_CACHE){ $signals[]='WP_CACHE'; if($primary==='None detected') $primary='Unknown / signal only'; } if(file_exists(WP_CONTENT_DIR.'/advanced-cache.php')){ $signals[]='advanced-cache.php'; if($primary==='None detected') $primary='Unknown / signal only'; } foreach([WP_CONTENT_DIR.'/cache', WP_CONTENT_DIR.'/wpfc-cache', WP_CONTENT_DIR.'/cache/page_enhanced'] as $folder){ if(is_dir($folder)) $signals[]='Cache dir: '.basename($folder); } if(empty($signals)) $signals[]='No cache signal found'; return ['primary'=>$primary,'signals'=>array_values(array_unique($signals))]; } function ageroth_sh_detect_object_cache() { $map=['redis-cache/redis-cache.php'=>'Redis Object Cache','object-cache-pro/object-cache-pro.php'=>'Object Cache Pro','memcached/memcached.php'=>'Memcached','docket-cache/docket-cache.php'=>'Docket Cache','litespeed-cache/litespeed-cache.php'=>'Not detected']; $signals=[]; $primary='None detected'; foreach($map as $slug=>$name){ if(ageroth_sh_is_plugin_active_slug($slug)){ $primary=$name; $signals[]='Active plugin: '.$name; break; } } if(function_exists('wp_using_ext_object_cache') && wp_using_ext_object_cache()){ $signals[]='wp_using_ext_object_cache()'; if($primary==='None detected') $primary='Unknown / signal only'; } if(file_exists(WP_CONTENT_DIR.'/object-cache.php')){ $signals[]='object-cache.php'; if($primary==='None detected') $primary='Unknown / signal only'; } if(empty($signals)) $signals[]='No object cache signal found'; return ['primary'=>$primary,'signals'=>array_values(array_unique($signals))]; } function ageroth_sh_extract_markers($body){ $body = strtolower((string)$body); $markers=[]; $map=['wp fastest cache'=>'HTML marker: WP Fastest Cache','wpfc-minified'=>'HTML marker: WP Fastest Cache','wp rocket'=>'HTML marker: WP Rocket','litespeed-cache'=>'HTML marker: LiteSpeed Cache','w3 total cache'=>'HTML marker: W3 Total Cache']; foreach($map as $needle=>$label){ if(strpos($body,$needle)!==false) $markers[]=$label; } return array_values(array_unique($markers)); } function ageroth_sh_classify_hit($hit){ $low = strtolower((string)$hit); foreach(['x-litespeed-cache: hit','cf-cache-status: hit','x-cache: hit','x-cache-status: hit','x-fastcgi-cache: hit','x-proxy-cache: hit','x-wp-cf-super-cache-cache: cache','x-kinsta-cache: hit'] as $pattern){ if(strpos($low,$pattern)!==false) return 'positive'; } if(preg_match('/^age:\s*[1-9][0-9]*/',$low)) return 'positive'; foreach(['cf-cache-status: bypass','cf-cache-status: dynamic','cf-cache-status: miss','x-litespeed-cache: miss','x-cache: miss','x-cache-status: miss','x-fastcgi-cache: miss','x-proxy-cache: miss','private'] as $pattern){ if(strpos($low,$pattern)!==false) return 'negative'; } if(strpos($low,'cache-control:')!==false && (strpos($low,'no-cache')!==false || strpos($low,'no-store')!==false || strpos($low,'must-revalidate')!==false)) return 'neutral-cache'; foreach(['html marker:','x-litespeed-cache:','cf-cache-status:','x-cache:','x-cache-status:','x-fastcgi-cache:','x-proxy-cache:','x-wp-cf-super-cache-cache:','x-kinsta-cache:','age:'] as $pattern){ if(strpos($low,$pattern)!==false) return 'neutral-cache'; } return 'generic'; } function ageroth_sh_run_frontend_test($url, $page_cache) { $requests=[$url,$url]; $request_times=[]; $all_hits=[]; $final_status=0; $server_header=""; foreach($requests as $i=>$request_url){ $start=microtime(true); $response=wp_remote_get($request_url,['timeout'=>8,'redirection'=>3,'sslverify'=>false,'user-agent'=>'Ageroth-Site-Health/'.AGEROTH_SH_VERSION,'headers'=>['Accept'=>'text/html,application/xhtml+xml']]); $elapsed=max(0,microtime(true)-$start); if(is_wp_error($response)){ return ['status'=>'warning','status_label'=>'Request Failed','summary'=>'The live frontend request failed before cache headers could be evaluated.','positive_hits'=>[],'negative_hits'=>[],'neutral_hits'=>[],'headers'=>[],'confidence'=>0,'tested_url'=>$url,'http_status'=>0,'diagnostics'=>['Cache Plugin'=>$page_cache['primary'] !== 'None detected' ? $page_cache['primary'] : 'Not detected','Live HIT Header'=>'Not detected','Response Type'=>'Unavailable'],'recommendation'=>'The test request failed. Try again or test a different public URL.','response_type'=>'Unavailable','explanation'=>'The live request failed before cache signals could be evaluated.','what_it_means'=>'The plugin could not complete the live request, so this report cannot confirm how the tested page behaves.','next_steps'=>['Run the test again.','Try a different public URL.','Check that the site can be reached from the server.'],'request_times'=>[],'double_request_summary'=>'No timing data available.','timing_signal'=>'inconclusive','timing_explanation'=>'Timing data was not available for this test.','why_uncached'=>[$response->get_error_message()]]; } $final_status=(int)wp_remote_retrieve_response_code($response); $headers=wp_remote_retrieve_headers($response); $body=(string)wp_remote_retrieve_body($response); $headers_array=[]; if(is_object($headers) && method_exists($headers,'getAll')) $headers_array=(array)$headers->getAll(); elseif(is_array($headers)) $headers_array=$headers; $all_hits[]='HTTP '.$final_status; foreach((array)$headers_array as $name=>$value){ $name=strtolower((string)$name); if(is_array($value)) $value=implode(', ', array_map('strval',$value)); $value=trim(preg_replace('/\s+/',' ',(string)$value)); if($value==='') continue; if($name==='server') $server_header=$value; if(in_array($name,['cache-control','age','x-cache','x-cache-status','x-litespeed-cache','x-fastcgi-cache','x-proxy-cache','cf-cache-status','x-wp-cf-super-cache-cache','x-kinsta-cache','server'],true)) $all_hits[]=$name.': '.$value; } foreach(ageroth_sh_extract_markers($body) as $marker) $all_hits[]=$marker; $request_times[]=['request'=>$i+1,'duration'=>$elapsed]; } $all_hits=array_values(array_unique($all_hits)); $positive_hits=[]; $negative_hits=[]; $neutral_hits=[]; $confidence=0; foreach($all_hits as $hit){ $type=ageroth_sh_classify_hit($hit); if($type==='positive'){ $positive_hits[]=$hit; $confidence+=40; } elseif($type==='negative'){ $negative_hits[]=$hit; $confidence-=15; } elseif($type==='neutral-cache'){ $neutral_hits[]=$hit; $confidence+=10; } } $confidence=max(0,min(100,$confidence)); $has_strong_positive=!empty($positive_hits); $has_marker=false; foreach($all_hits as $hit){ if(stripos($hit,'HTML marker:')!==false) $has_marker=true; } $has_page_cache_locally=$page_cache['primary']!=='None detected'; $timing_signal='inconclusive'; $timing_explanation='Timing data was not available for this test.'; $double_request_summary='Double-request timing was not available.'; $likely_cached=false; if(count($request_times)>=2){ $first=(float)$request_times[0]['duration']; $second=(float)$request_times[1]['duration']; $double_request_summary=sprintf('Request 1: %s • Request 2: %s', ageroth_sh_human_ms($first), ageroth_sh_human_ms($second)); if($second < $first*0.70 && ($first-$second)>0.08){ $timing_signal='strong'; $timing_explanation='The second request was significantly faster, which is a strong timing hint for cached delivery.'; $double_request_summary.=' • The second request was significantly faster.'; $likely_cached=true; $confidence=max($confidence,55); } elseif($second < $first*0.85 && ($first-$second)>0.04){ $timing_signal='weak'; $timing_explanation='The second request was moderately faster, which may suggest a cache warmup effect.'; $double_request_summary.=' • The second request was moderately faster.'; $likely_cached=true; $confidence=max($confidence,35); } else { $timing_signal='inconclusive'; $timing_explanation='Both requests were already very fast, so timing alone could not confirm a cache warmup effect.'; $double_request_summary.=' • The second request was not meaningfully faster.'; } } $result=['status'=>'neutral','status_label'=>'Page Cache Detected','summary'=>'A page cache layer appears to be active, but this response does not expose an explicit cache-hit header.','positive_hits'=>$positive_hits,'negative_hits'=>$negative_hits,'neutral_hits'=>$neutral_hits,'headers'=>array_slice($all_hits,0,10),'confidence'=>max(0,min(100,$confidence)),'tested_url'=>$url,'http_status'=>$final_status,'diagnostics'=>[],'recommendation'=>'Page cache is detected, but no explicit hit header is exposed on this response.','response_type'=>'Cache detected (no explicit HIT header)','explanation'=>'This is common on some cache plugins and does not necessarily mean caching is not working.','what_it_means'=>'Caching appears to be active on this site. However, the tested response did not include a direct HIT header, which is common on some cache plugins and server setups.','next_steps'=>['Test another public URL.','Try again after clearing cache.','Some pages may expose cache signals more clearly than others.'],'request_times'=>$request_times,'double_request_summary'=>$double_request_summary,'timing_signal'=>$timing_signal,'timing_explanation'=>$timing_explanation,'why_uncached'=>[],'server_header'=>$server_header]; if($has_strong_positive){ $result['status']='good'; $result['status_label']='Confirmed Cache Hit'; $result['summary']='A live request returned a clear cache-hit signal for this URL.'; $result['response_type']='Confirmed cache hit'; $result['explanation']='A live request returned a clear cache-hit signal for this URL.'; $result['what_it_means']='Good news. The tested page returned a clear cache-hit signal, so caching is working for this URL.'; $result['next_steps']=['Test another public URL to compare behavior.','Review object cache separately if needed.','Use this result as a baseline for the site.']; $result['recommendation']='A confirmed live cache hit was detected on this URL.'; } elseif(($has_marker || $has_page_cache_locally) && $likely_cached){ $result['status']='good'; $result['status_label']='Likely Cached (Double Request)'; $result['summary']='The second request was meaningfully faster, which suggests this URL is probably being served from cache.'; $result['response_type']='Likely cached (timing hint)'; $result['explanation']='This result is based on timing behavior across two back-to-back requests, even though no explicit HIT header was exposed.'; $result['what_it_means']='Caching appears to be active on this site. The server did not return a direct HIT header, but the second request was faster in a way that suggests cached delivery.'; $result['next_steps']=['Test another public URL to compare the pattern.','Run the test again after clearing cache.','Use Technical Details if you need the raw timing data.']; $result['recommendation']='Double-request timing suggests this URL is probably being served from cache.'; } elseif(!$has_marker && !$has_page_cache_locally && !empty($negative_hits)){ $result['status']='warning'; $result['status_label']='Likely Uncached'; $result['summary']='This page response looks dynamic or bypassed rather than served from cache.'; $result['response_type']='Likely uncached'; $result['explanation']='The tested response looks more like a dynamic or bypassed page than a cached response.'; $result['what_it_means']='This response looks more like a dynamic or bypassed page than a cached response. The page may be excluded from cache, or another rule may be affecting it.'; $result['next_steps']=['Check cache exclusions for this page.','Test a simpler public URL.','Review any plugin or theme code that adds restrictive headers.']; $result['recommendation']='This response looks uncached. Test another public URL and review any cache exclusions if needed.'; } foreach($negative_hits as $hit){ $low=strtolower($hit); if(strpos($low,'no-cache')!==false || strpos($low,'no-store')!==false) $result['why_uncached'][]='The response sent restrictive browser cache headers.'; elseif(strpos($low,'miss')!==false || strpos($low,'bypass')!==false || strpos($low,'dynamic')!==false) $result['why_uncached'][]='The cache layer reported a miss, bypass, or dynamic response.'; elseif(strpos($low,'private')!==false) $result['why_uncached'][]='The response appears private, which usually prevents a public cache hit.'; } $result['why_uncached']=array_values(array_unique($result['why_uncached'])); $result['diagnostics']=['Cache Plugin'=>($has_marker || $has_page_cache_locally)?$page_cache['primary']:'Not detected','Live HIT Header'=>$has_strong_positive?'Detected':'Not detected','Response Type'=>$result['response_type']]; return $result; } function ageroth_sh_compare_urls($home_result, $inner_result){ $home = $home_result['status_label'] ?? 'Unknown'; $inner = $inner_result['status_label'] ?? 'Unknown'; if($home === $inner) return ['summary'=>'Homepage and inner-page cache behavior look similar.','severity'=>'same']; return ['summary'=>'Cache behavior differs between the homepage and the comparison URL.','severity'=>'different']; } function ageroth_sh_server_profile($frontend){ $server = !empty($frontend['server_header']) ? $frontend['server_header'] : (isset($_SERVER['SERVER_SOFTWARE']) ? sanitize_text_field(wp_unslash($_SERVER['SERVER_SOFTWARE'])) : 'Unknown'); $opcache = 'Unknown / not exposed'; if (function_exists('opcache_get_status')) { $status = @opcache_get_status(false); if (is_array($status) && !empty($status['opcache_enabled'])) { $opcache = 'Enabled'; } } return [ 'Web Server' => $server, 'PHP Version' => PHP_VERSION, 'OPcache' => $opcache, 'Memory Limit' => defined('WP_MEMORY_LIMIT') ? WP_MEMORY_LIMIT : ini_get('memory_limit'), 'Max Execution Time' => ini_get('max_execution_time') !== false ? ini_get('max_execution_time').'s' : 'Unknown', 'Multisite' => is_multisite() ? 'Yes' : 'No' ]; } function ageroth_sh_cache_intelligence($page_cache,$frontend){ $confidence=(int)($frontend['confidence'] ?? 0); $hit=($frontend['status_label'] ?? '')==='Confirmed Cache Hit'; $takeaway=$hit?'A clear live cache HIT signal was detected.':($page_cache['primary']!=='None detected'?'A cache layer is detected, but this response does not expose a direct HIT header.':'No clear page-cache layer was detected locally.'); return [ 'Plugin / Layer'=>$page_cache['primary'], 'Live Result'=>$frontend['status_label'] ?? 'Unknown', 'Confidence'=>ageroth_sh_confidence_label($confidence).' ('.$confidence.'%)', 'Timing Signal'=>ageroth_sh_timing_signal_label($frontend['timing_signal'] ?? 'inconclusive'), 'Takeaway'=>$takeaway ]; } function ageroth_sh_object_cache_intelligence($object_cache){ return [ 'Object Cache Layer'=>$object_cache['primary'], 'Drop-in File'=>file_exists(WP_CONTENT_DIR.'/object-cache.php')?'Present':'Not found', 'WordPress External Object Cache'=>(function_exists('wp_using_ext_object_cache') && wp_using_ext_object_cache())?'Enabled':'Not reported', 'Recommendation'=>$object_cache['primary']!=='None detected'?'Persistent object cache signals were detected.':'Consider persistent object cache for larger or busier sites.' ]; } function ageroth_sh_wc_intelligence(){ $active=class_exists('WooCommerce'); $items=['Status'=>$active?'Active':'Inactive']; if($active && function_exists('wc_get_page_id')){ foreach(['Cart page'=>'cart','Checkout page'=>'checkout','My account page'=>'myaccount'] as $label=>$key){ $id=wc_get_page_id($key); $items[$label]=($id && $id>0)?get_permalink($id):'Not configured'; } $items['Cache note']='Cart, checkout, and account pages should normally stay excluded from full-page cache.'; } else { $items['Cache note']='WooCommerce is not active on this site.'; } return $items; } function ageroth_sh_render_kv_grid($items){ foreach((array)$items as $label=>$value){ echo '
Read-only WordPress health checks, cache intelligence, and server diagnostics.
The final score is calculated from the weighted balance of performance, caching, server, and maintenance signals.
Weekly report processed. Check your inbox.
Test alert processed. Check the alert status below and your inbox.
| Last Checked | |
|---|---|
| Last Sent | |
| Last Status | |
| Last Weekly Report | |
| Weekly Report Status | |
| Last Issues |
|
This plugin is read-only and does not collect or send personal data.