| 1 |
<?php |
| 2 |
defined('ABSPATH') or die('Unauthorized Access'); |
| 3 |
|
| 4 |
$is_pro = Phpinfo_WP_License::is_valid(); |
| 5 |
$grader = Phpinfo_WP_Config_Grader::summary(); |
| 6 |
$bar = Phpinfo_WP_Admin_Bar::status(); |
| 7 |
|
| 8 |
// Fetch new stats for visual dashboard |
| 9 |
$api_stats = class_exists('Phpinfo_WP_API_Monitor') ? Phpinfo_WP_API_Monitor::get_stats() : []; |
| 10 |
if (!is_array($api_stats)) $api_stats = []; |
| 11 |
$db_stats = class_exists('Phpinfo_WP_DB_Health') ? Phpinfo_WP_DB_Health::autoload_size() : ['total_kb' => 0]; |
| 12 |
if (!is_array($db_stats)) $db_stats = ['total_kb' => 0]; |
| 13 |
|
| 14 |
$grade = $grader['grade']; |
| 15 |
$score = $grader['score']; |
| 16 |
$mem = $bar['memory'] ?? ['peak_bytes' => 0, 'limit_label' => ini_get('memory_limit'), 'pct' => 0]; |
| 17 |
|
| 18 |
// Calculate Donut Chart (Memory) |
| 19 |
$mem_pct = $mem['pct']; |
| 20 |
$mem_color = $mem_pct > 85 ? '#d63638' : ($mem_pct > 65 ? '#dba617' : '#00a32a'); |
| 21 |
$dasharray = $mem_pct . ' ' . (100 - $mem_pct); |
| 22 |
|
| 23 |
// Calculate API Chart |
| 24 |
$slowest_apis = []; |
| 25 |
foreach ($api_stats as $host => $data) { |
| 26 |
$slowest_apis[$host] = $data['max_time']; |
| 27 |
} |
| 28 |
arsort($slowest_apis); |
| 29 |
$top_apis = array_slice($slowest_apis, 0, 3, true); |
| 30 |
|
| 31 |
// Calculate DB Autoload Bar |
| 32 |
$db_bytes = $db_stats['bytes'] ?? 0; |
| 33 |
$db_kb = round($db_bytes / 1024, 1); |
| 34 |
// 800KB is danger zone. Max scale is 1200KB. |
| 35 |
$db_pct = min(100, ($db_kb / 1200) * 100); |
| 36 |
$db_color = $db_kb > 800 ? '#d63638' : ($db_kb > 400 ? '#dba617' : '#00a32a'); |
| 37 |
|
| 38 |
// Config Grade Bar |
| 39 |
$grade_pct = $score; |
| 40 |
$grade_color = $score < 60 ? '#d63638' : ($score < 80 ? '#dba617' : '#00a32a'); |
| 41 |
|
| 42 |
// Fetch the current nav arrays |
| 43 |
$nav_cache = Phpinfo_WP_Admin_Nav::groups(); |
| 44 |
|
| 45 |
if (!function_exists('render_dash_grid')) { |
| 46 |
function render_dash_grid($group_id, $nav_cache, $is_pro) { |
| 47 |
if (!isset($nav_cache[$group_id])) return; |
| 48 |
$group = $nav_cache[$group_id]; |
| 49 |
echo '<div class="phpinfowp-dash-section">'; |
| 50 |
echo '<h2 class="phpinfowp-dash-section-title">' . esc_html($group['label']) . '</h2>'; |
| 51 |
echo '<div class="phpinfowp-dash-grid">'; |
| 52 |
foreach ($group['tabs'] as $slug => $tab) { |
| 53 |
$locked = $tab['pro'] && !$is_pro; |
| 54 |
echo '<a href="' . esc_url(admin_url('admin.php?page=' . $slug)) . '" class="phpinfowp-dash-card' . ($locked ? ' is-locked' : '') . '">'; |
| 55 |
echo '<span class="dashicons ' . esc_attr($tab['icon']) . '"></span>'; |
| 56 |
echo '<div class="phpinfowp-dash-card-title">'; |
| 57 |
echo esc_html($tab['label']); |
| 58 |
if ($tab['pro']) { |
| 59 |
echo '<span class="phpinfowp-dash-card-pro">' . __('PRO', 'phpinfo-wp') . '</span>'; |
| 60 |
} |
| 61 |
echo '</div>'; |
| 62 |
echo '</a>'; |
| 63 |
} |
| 64 |
echo '</div></div>'; |
| 65 |
} |
| 66 |
} |
| 67 |
?> |
| 68 |
|
| 69 |
<div class="phpinfowp-pro-page phpinfowp-dashboard"> |
| 70 |
|
| 71 |
<div class="phpinfowp-page-header"> |
| 72 |
<div> |
| 73 |
<h1><?php _e('Dashboard', 'phpinfo-wp'); ?></h1> |
| 74 |
<p class="phpinfowp-page-subtitle"><?php _e('Visual health overview and system shortcuts', 'phpinfo-wp'); ?></p> |
| 75 |
</div> |
| 76 |
</div> |
| 77 |
|
| 78 |
|
| 79 |
|
| 80 |
<!-- VISUAL INSIGHTS WIDGETS --> |
| 81 |
<div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(280px, 1fr)); gap:20px; margin-bottom:32px;"> |
| 82 |
|
| 83 |
<!-- 1. Config Grader Gauge --> |
| 84 |
<a href="<?php echo esc_url(admin_url('admin.php?page=phpinfowp-config-grader')); ?>" style="background:#fff; border:1px solid #ccd0d4; border-radius:6px; padding:20px; text-decoration:none; color:inherit; box-shadow:0 1px 2px rgba(0,0,0,0.02); display:flex; flex-direction:column; justify-content:space-between;"> |
| 85 |
<div> |
| 86 |
<h3 style="margin:0 0 12px 0; font-size:14px; color:#555; text-transform:uppercase; letter-spacing:0.5px;"><?php _e('Setup Optimization', 'phpinfo-wp'); ?></h3> |
| 87 |
<div style="font-size:32px; font-weight:300; line-height:1; margin-bottom:8px; color:#1d2327;"> |
| 88 |
<?php printf( |
| 89 |
/* translators: %s: score value */ |
| 90 |
__('%s / 100', 'phpinfo-wp'), |
| 91 |
(int)$score |
| 92 |
); ?> |
| 93 |
</div> |
| 94 |
</div> |
| 95 |
<div> |
| 96 |
<div style="width:100%; height:8px; background:#f0f0f1; border-radius:4px; overflow:hidden; margin-bottom:6px;"> |
| 97 |
<div style="height:100%; width:<?php echo $grade_pct; ?>%; background:<?php echo $grade_color; ?>; border-radius:4px;"></div> |
| 98 |
</div> |
| 99 |
<div style="font-size:12px; color:#777;"> |
| 100 |
<?php _e('Current Grade:', 'phpinfo-wp'); ?> <strong class="grade-<?php echo esc_attr(strtolower(str_replace('+', 'plus', $grade))); ?>"><?php echo esc_html($grade); ?></strong> |
| 101 |
</div> |
| 102 |
</div> |
| 103 |
</a> |
| 104 |
|
| 105 |
<!-- 2. Memory Donut Chart --> |
| 106 |
<a href="<?php echo esc_url(admin_url('admin.php?page=phpinfowp-info')); ?>" style="background:#fff; border:1px solid #ccd0d4; border-radius:6px; padding:20px; text-decoration:none; color:inherit; box-shadow:0 1px 2px rgba(0,0,0,0.02); display:flex; align-items:center; justify-content:space-between;"> |
| 107 |
<div> |
| 108 |
<h3 style="margin:0 0 8px 0; font-size:14px; color:#555; text-transform:uppercase; letter-spacing:0.5px;"><?php _e('Memory Peak', 'phpinfo-wp'); ?></h3> |
| 109 |
<div style="font-size:24px; font-weight:300; line-height:1.2; margin-bottom:4px; color:#1d2327;"> |
| 110 |
<?php echo esc_html(size_format($mem['peak_bytes'] > 0 ? $mem['peak_bytes'] : memory_get_usage(true))); ?> |
| 111 |
</div> |
| 112 |
<div style="font-size:12px; color:#777;"> |
| 113 |
<?php _e('Limit:', 'phpinfo-wp'); ?> <?php echo esc_html($mem['limit_label']); ?> |
| 114 |
</div> |
| 115 |
</div> |
| 116 |
<svg width="80" height="80" viewBox="0 0 36 36" style="display:block;"> |
| 117 |
<path d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="#f0f0f1" stroke-width="4"/> |
| 118 |
<path d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="<?php echo $mem_color; ?>" stroke-width="4" stroke-dasharray="<?php echo $dasharray; ?>" /> |
| 119 |
<text x="18" y="20.5" font-family="sans-serif" font-size="9" font-weight="bold" fill="#555" text-anchor="middle"><?php echo $mem_pct; ?>%</text> |
| 120 |
</svg> |
| 121 |
</a> |
| 122 |
|
| 123 |
<!-- 3. DB Autoload Progress --> |
| 124 |
<a href="<?php echo esc_url(admin_url('admin.php?page=phpinfowp-db-health')); ?>" style="background:#fff; border:1px solid #ccd0d4; border-radius:6px; padding:20px; text-decoration:none; color:inherit; box-shadow:0 1px 2px rgba(0,0,0,0.02); display:flex; flex-direction:column; justify-content:space-between;"> |
| 125 |
<div> |
| 126 |
<h3 style="margin:0 0 12px 0; font-size:14px; color:#555; text-transform:uppercase; letter-spacing:0.5px;"><?php _e('Autoload Bloat', 'phpinfo-wp'); ?></h3> |
| 127 |
<div style="font-size:24px; font-weight:300; line-height:1; margin-bottom:8px; color:<?php echo $db_color; ?>;"> |
| 128 |
<?php echo $db_kb; ?> <span style="font-size:16px; color:#888;">KB</span> |
| 129 |
</div> |
| 130 |
</div> |
| 131 |
<div> |
| 132 |
<div style="width:100%; height:8px; background:#f0f0f1; border-radius:4px; overflow:hidden; margin-bottom:6px;"> |
| 133 |
<div style="height:100%; width:<?php echo $db_pct; ?>%; background:<?php echo $db_color; ?>; border-radius:4px;"></div> |
| 134 |
</div> |
| 135 |
<div style="font-size:12px; color:#777;"> |
| 136 |
<?php echo $db_kb > 800 ? __('Danger: High TTFB Impact', 'phpinfo-wp') : __('Healthy footprint', 'phpinfo-wp'); ?> |
| 137 |
</div> |
| 138 |
</div> |
| 139 |
</a> |
| 140 |
|
| 141 |
<!-- 4. API Monitor Bar Chart --> |
| 142 |
<?php if ($is_pro): ?> |
| 143 |
<a href="<?php echo esc_url(admin_url('admin.php?page=phpinfowp-api-monitor')); ?>" style="background:#fff; border:1px solid #ccd0d4; border-radius:6px; padding:20px; text-decoration:none; color:inherit; box-shadow:0 1px 2px rgba(0,0,0,0.02); display:flex; flex-direction:column;"> |
| 144 |
<h3 style="margin:0 0 12px 0; font-size:14px; color:#555; text-transform:uppercase; letter-spacing:0.5px;"><?php _e('Slowest External APIs', 'phpinfo-wp'); ?></h3> |
| 145 |
<?php if (empty($top_apis)): ?> |
| 146 |
<div style="flex:1; display:flex; align-items:center; justify-content:center; color:#888; font-size:13px; font-style:italic;"> |
| 147 |
<?php _e('No slow API calls detected', 'phpinfo-wp'); ?> |
| 148 |
</div> |
| 149 |
<?php else: ?> |
| 150 |
<div style="flex:1; display:flex; flex-direction:column; justify-content:space-around;"> |
| 151 |
<?php |
| 152 |
$max_t = max(2.0, max($top_apis)); // base scale on 2.0s or highest |
| 153 |
foreach($top_apis as $host => $time): |
| 154 |
$w = min(100, ($time / $max_t) * 100); |
| 155 |
$c = $time > 2.0 ? '#d63638' : ($time > 1.0 ? '#dba617' : '#00a32a'); |
| 156 |
?> |
| 157 |
<div style="margin-bottom:6px;"> |
| 158 |
<div style="display:flex; justify-content:space-between; font-size:11px; color:#555; margin-bottom:2px;"> |
| 159 |
<span style="white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:70%;"><?php echo esc_html($host); ?></span> |
| 160 |
<strong><?php echo number_format($time, 1); ?>s</strong> |
| 161 |
</div> |
| 162 |
<div style="width:100%; height:4px; background:#f0f0f1; border-radius:2px;"> |
| 163 |
<div style="height:100%; width:<?php echo $w; ?>%; background:<?php echo $c; ?>; border-radius:2px;"></div> |
| 164 |
</div> |
| 165 |
</div> |
| 166 |
<?php endforeach; ?> |
| 167 |
</div> |
| 168 |
<?php endif; ?> |
| 169 |
</a> |
| 170 |
<?php else: ?> |
| 171 |
<a href="<?php echo esc_url(admin_url('admin.php?page=phpinfowp-api-monitor')); ?>" style="background:#fff; border:1px solid #ccd0d4; border-radius:6px; padding:20px; text-decoration:none; color:inherit; box-shadow:0 1px 2px rgba(0,0,0,0.02); display:flex; flex-direction:column; justify-content:space-between;"> |
| 172 |
<div> |
| 173 |
<div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:8px;"> |
| 174 |
<h3 style="margin:0; font-size:14px; color:#555; text-transform:uppercase; letter-spacing:0.5px;"><?php _e('Slowest External APIs', 'phpinfo-wp'); ?></h3> |
| 175 |
<span class="phpinfowp-dash-card-pro"><?php _e('PRO', 'phpinfo-wp'); ?></span> |
| 176 |
</div> |
| 177 |
<div style="font-size:13px; color:#64748b; line-height:1.45; margin-bottom:8px;"> |
| 178 |
<span class="dashicons dashicons-lock" style="font-size:16px; width:16px; height:16px; vertical-align:text-bottom; color:#777BB3; margin-right:2px;"></span> |
| 179 |
<?php _e('Track outbound HTTP latency & slow 3rd-party services impacting TTFB.', 'phpinfo-wp'); ?> |
| 180 |
</div> |
| 181 |
</div> |
| 182 |
<div style="font-size:12px; font-weight:600; color:#777BB3; display:flex; align-items:center; gap:4px;"> |
| 183 |
<?php _e('Unlock API Monitor →', 'phpinfo-wp'); ?> |
| 184 |
</div> |
| 185 |
</a> |
| 186 |
<?php endif; ?> |
| 187 |
|
| 188 |
</div> |
| 189 |
|
| 190 |
<!-- Active issues panel --> |
| 191 |
<?php if (!empty($bar['issues'])): ?> |
| 192 |
<div class="phpinfowp-dash-section"> |
| 193 |
<h2 class="phpinfowp-dash-section-title"><?php _e('Active Issues', 'phpinfo-wp'); ?></h2> |
| 194 |
<div class="phpinfowp-dash-issues"> |
| 195 |
<?php foreach ($bar['issues'] as $issue): |
| 196 |
$c = $issue['level'] === 'critical' ? '#d63638' : '#dba617'; |
| 197 |
?> |
| 198 |
<a href="<?php echo esc_url($issue['href']); ?>" class="phpinfowp-dash-issue"> |
| 199 |
<span class="phpinfowp-dash-issue-dot" style="background:<?php echo $c; ?>"></span> |
| 200 |
<strong><?php echo esc_html($issue['label']); ?></strong> |
| 201 |
<span class="phpinfowp-dash-issue-detail"><?php echo esc_html($issue['detail']); ?></span> |
| 202 |
</a> |
| 203 |
<?php endforeach; ?> |
| 204 |
</div> |
| 205 |
</div> |
| 206 |
<?php endif; ?> |
| 207 |
|
| 208 |
<!-- Nav Grids --> |
| 209 |
<?php |
| 210 |
render_dash_grid('performance', $nav_cache, $is_pro); |
| 211 |
render_dash_grid('audit', $nav_cache, $is_pro); |
| 212 |
render_dash_grid('tools', $nav_cache, $is_pro); |
| 213 |
render_dash_grid('reports', $nav_cache, $is_pro); |
| 214 |
?> |
| 215 |
|
| 216 |
<?php if (!$is_pro): ?> |
| 217 |
<div style="margin-top:24px;padding:14px 16px;background:#f6f7f7;border:1px solid #e5e7ea;border-radius:4px;display:flex;align-items:center;justify-content:space-between;"> |
| 218 |
<span style="font-size:13px;color:#555;"> |
| 219 |
<?php _e('🔒 Running <strong>Pro features</strong> in preview mode.', 'phpinfo-wp'); ?> |
| 220 |
</span> |
| 221 |
<a href="https://exeebit.com/phpinfo-wp#pricing" target="_blank" rel="noopener" |
| 222 |
style="background:#777BB3;color:#fff;padding:6px 14px;border-radius:4px;font-size:12.5px;font-weight:600;text-decoration:none;"> |
| 223 |
<?php _e('Unlock full access →', 'phpinfo-wp'); ?> |
| 224 |
</a> |
| 225 |
</div> |
| 226 |
<?php endif; ?> |
| 227 |
|
| 228 |
</div> |