374 lines
18 KiB
PHP
374 lines
18 KiB
PHP
<?php
|
|
/**
|
|
* Frontend Panel Module
|
|
*
|
|
* Panel visual flotante en frontend para administradores
|
|
*
|
|
* @package WP_Debug
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* WP_Debug_Frontend_Panel class
|
|
*/
|
|
class WP_Debug_Frontend_Panel {
|
|
|
|
/**
|
|
* Initialize frontend panel
|
|
*/
|
|
public static function init() {
|
|
// Only for admins
|
|
if (!current_user_can('manage_options')) {
|
|
return;
|
|
}
|
|
|
|
// Enqueue assets
|
|
add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_assets'));
|
|
|
|
// Render panel
|
|
add_action('wp_footer', array(__CLASS__, 'render_panel'), 999);
|
|
}
|
|
|
|
/**
|
|
* Enqueue assets
|
|
*/
|
|
public static function enqueue_assets() {
|
|
// Enqueue CSS
|
|
wp_enqueue_style(
|
|
'wp-debug-panel',
|
|
WP_DEBUG_PLUGIN_URL . 'assets/css/debug-panel.css',
|
|
array(),
|
|
WP_DEBUG_VERSION
|
|
);
|
|
|
|
// Enqueue JS
|
|
wp_enqueue_script(
|
|
'wp-debug-panel',
|
|
WP_DEBUG_PLUGIN_URL . 'assets/js/debug-panel.js',
|
|
array('jquery'),
|
|
WP_DEBUG_VERSION,
|
|
true
|
|
);
|
|
|
|
// Localize script with data
|
|
wp_localize_script('wp-debug-panel', 'wpDebugData', array(
|
|
'ajaxUrl' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('wp_debug_panel'),
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Render panel
|
|
*/
|
|
public static function render_panel() {
|
|
// Load data from transients
|
|
$metrics = get_transient('wp_debug_last_metrics');
|
|
$hooks_data = get_transient('wp_debug_hooks_data');
|
|
$templates_data = get_transient('wp_debug_templates_data');
|
|
$assets_data = get_transient('wp_debug_assets_data');
|
|
$queries_data = get_transient('wp_debug_queries_data');
|
|
|
|
?>
|
|
<div id="wp-debug-panel" class="wp-debug-panel" style="display: none;">
|
|
<div class="wp-debug-panel-header">
|
|
<h3>WP Debug Panel</h3>
|
|
<div class="wp-debug-panel-tabs">
|
|
<button class="wp-debug-tab active" data-tab="overview">Overview</button>
|
|
<button class="wp-debug-tab" data-tab="performance">Performance</button>
|
|
<button class="wp-debug-tab" data-tab="hooks">Hooks</button>
|
|
<button class="wp-debug-tab" data-tab="templates">Templates</button>
|
|
<button class="wp-debug-tab" data-tab="assets">Assets</button>
|
|
<button class="wp-debug-tab" data-tab="queries">Queries</button>
|
|
</div>
|
|
<button class="wp-debug-panel-close">×</button>
|
|
</div>
|
|
|
|
<div class="wp-debug-panel-content">
|
|
<!-- Overview Tab -->
|
|
<div class="wp-debug-tab-content active" data-tab="overview">
|
|
<h4>System Overview</h4>
|
|
<table class="wp-debug-table">
|
|
<tr>
|
|
<td><strong>WordPress Version:</strong></td>
|
|
<td><?php echo get_bloginfo('version'); ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>PHP Version:</strong></td>
|
|
<td><?php echo phpversion(); ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Active Theme:</strong></td>
|
|
<td><?php echo wp_get_theme()->get('Name'); ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Memory Usage:</strong></td>
|
|
<td><?php echo size_format(memory_get_usage()); ?> / <?php echo size_format(memory_get_peak_usage()); ?> peak</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Execution Time:</strong></td>
|
|
<td><?php echo round(timer_stop(0), 3); ?>s</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h4>Module Status</h4>
|
|
<ul class="wp-debug-module-list">
|
|
<?php
|
|
$modules = array(
|
|
'logger' => 'Logger',
|
|
'profiler' => 'Profiler',
|
|
'hook_monitor' => 'Hook Monitor',
|
|
'template_tracer' => 'Template Tracer',
|
|
'asset_tracker' => 'Asset Tracker',
|
|
'query_analyzer' => 'Query Analyzer',
|
|
);
|
|
|
|
foreach ($modules as $module_key => $module_name) {
|
|
$enabled = get_option('wp_debug_module_' . $module_key, true);
|
|
$status = $enabled ? '<span class="status-active">Active</span>' : '<span class="status-inactive">Inactive</span>';
|
|
echo "<li>{$module_name}: {$status}</li>";
|
|
}
|
|
?>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Performance Tab -->
|
|
<div class="wp-debug-tab-content" data-tab="performance">
|
|
<h4>Performance Metrics</h4>
|
|
<?php if ($metrics): ?>
|
|
<table class="wp-debug-table">
|
|
<tr>
|
|
<td><strong>Execution Time:</strong></td>
|
|
<td><?php echo round($metrics['execution_time'], 3); ?>s</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Memory Peak:</strong></td>
|
|
<td><?php echo size_format($metrics['memory_peak']); ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Memory Current:</strong></td>
|
|
<td><?php echo size_format($metrics['memory_current']); ?></td>
|
|
</tr>
|
|
<?php if (isset($metrics['server_load'])): ?>
|
|
<tr>
|
|
<td><strong>Server Load:</strong></td>
|
|
<td><?php echo esc_html($metrics['server_load']); ?></td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
</table>
|
|
|
|
<?php if (!empty($metrics['timers'])): ?>
|
|
<h4>Custom Timers</h4>
|
|
<table class="wp-debug-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Timer</th>
|
|
<th>Elapsed</th>
|
|
<th>Memory Used</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($metrics['timers'] as $name => $timer): ?>
|
|
<tr>
|
|
<td><?php echo esc_html($name); ?></td>
|
|
<td><?php echo round($timer['elapsed'], 4); ?>s</td>
|
|
<td><?php echo size_format($timer['memory_used']); ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
<?php else: ?>
|
|
<p>No performance data available.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- Hooks Tab -->
|
|
<div class="wp-debug-tab-content" data-tab="hooks">
|
|
<h4>WordPress Hooks</h4>
|
|
<?php if ($hooks_data): ?>
|
|
<p><strong>Total Hooks:</strong> <?php echo $hooks_data['total']; ?> | <strong>Unique:</strong> <?php echo $hooks_data['unique']; ?></p>
|
|
|
|
<h5>Most Frequent Hooks</h5>
|
|
<table class="wp-debug-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Hook Name</th>
|
|
<th>Count</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
$top_hooks = array_slice($hooks_data['counts'], 0, 20, true);
|
|
foreach ($top_hooks as $hook => $count):
|
|
?>
|
|
<tr>
|
|
<td><code><?php echo esc_html($hook); ?></code></td>
|
|
<td><?php echo $count; ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php else: ?>
|
|
<p>No hooks data available.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- Templates Tab -->
|
|
<div class="wp-debug-tab-content" data-tab="templates">
|
|
<h4>Loaded Templates</h4>
|
|
<?php if ($templates_data): ?>
|
|
<?php if (!empty($templates_data['templates'])): ?>
|
|
<h5>Main Templates</h5>
|
|
<ul class="wp-debug-list">
|
|
<?php foreach ($templates_data['templates'] as $template): ?>
|
|
<li>
|
|
<strong><?php echo esc_html($template['name']); ?></strong>
|
|
<span class="template-type"><?php echo esc_html($template['type']); ?></span>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php endif; ?>
|
|
|
|
<?php if (!empty($templates_data['parts'])): ?>
|
|
<h5>Template Parts (<?php echo count($templates_data['parts']); ?>)</h5>
|
|
<ul class="wp-debug-list">
|
|
<?php foreach (array_slice($templates_data['parts'], 0, 20) as $part): ?>
|
|
<li>
|
|
<code><?php echo esc_html($part['file']); ?></code>
|
|
<?php if (!$part['found']): ?>
|
|
<span class="status-error">Not Found</span>
|
|
<?php endif; ?>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php endif; ?>
|
|
|
|
<?php if (!empty($templates_data['missing'])): ?>
|
|
<h5>Missing Templates</h5>
|
|
<ul class="wp-debug-list">
|
|
<?php foreach ($templates_data['missing'] as $missing): ?>
|
|
<li class="missing">
|
|
<code><?php echo esc_html($missing['file']); ?></code>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php endif; ?>
|
|
<?php else: ?>
|
|
<p>No template data available.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- Assets Tab -->
|
|
<div class="wp-debug-tab-content" data-tab="assets">
|
|
<h4>Enqueued Assets</h4>
|
|
<?php if ($assets_data): ?>
|
|
<?php if (isset($assets_data['statistics'])): ?>
|
|
<table class="wp-debug-table">
|
|
<tr>
|
|
<td><strong>Total Assets:</strong></td>
|
|
<td><?php echo $assets_data['statistics']['total_assets']; ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Styles:</strong></td>
|
|
<td><?php echo $assets_data['statistics']['total_styles']; ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Scripts:</strong></td>
|
|
<td><?php echo $assets_data['statistics']['total_scripts']; ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Total Size:</strong></td>
|
|
<td><?php echo $assets_data['statistics']['total_size_formatted']; ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Duplicates:</strong></td>
|
|
<td><?php echo $assets_data['statistics']['duplicates_count']; ?></td>
|
|
</tr>
|
|
</table>
|
|
<?php endif; ?>
|
|
|
|
<?php if (!empty($assets_data['duplicates'])): ?>
|
|
<h5>Duplicate Assets</h5>
|
|
<ul class="wp-debug-list">
|
|
<?php foreach ($assets_data['duplicates'] as $dup): ?>
|
|
<li class="duplicate">
|
|
<strong><?php echo esc_html($dup['type']); ?>:</strong>
|
|
<?php echo implode(', ', array_map('esc_html', $dup['handles'])); ?>
|
|
<span class="count">(<?php echo $dup['count']; ?>x)</span>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php endif; ?>
|
|
<?php else: ?>
|
|
<p>No assets data available.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- Queries Tab -->
|
|
<div class="wp-debug-tab-content" data-tab="queries">
|
|
<h4>Database Queries</h4>
|
|
<?php if ($queries_data): ?>
|
|
<table class="wp-debug-table">
|
|
<tr>
|
|
<td><strong>Total Queries:</strong></td>
|
|
<td><?php echo $queries_data['total_queries']; ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Total Time:</strong></td>
|
|
<td><?php echo round($queries_data['total_time'], 4); ?>s</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Slow Queries:</strong></td>
|
|
<td><?php echo count($queries_data['slow_queries']); ?></td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>N+1 Patterns:</strong></td>
|
|
<td><?php echo count($queries_data['n_plus_one']); ?></td>
|
|
</tr>
|
|
</table>
|
|
|
|
<?php if (!empty($queries_data['slow_queries'])): ?>
|
|
<h5>Slow Queries</h5>
|
|
<div class="wp-debug-queries">
|
|
<?php foreach (array_slice($queries_data['slow_queries'], 0, 5) as $query): ?>
|
|
<div class="query-item">
|
|
<div class="query-time"><?php echo round($query['elapsed'], 4); ?>s</div>
|
|
<code class="query-sql"><?php echo esc_html(substr($query['sql'], 0, 150)); ?>...</code>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if (!empty($queries_data['n_plus_one'])): ?>
|
|
<h5>N+1 Query Patterns</h5>
|
|
<div class="wp-debug-queries">
|
|
<?php foreach (array_slice($queries_data['n_plus_one'], 0, 3) as $pattern): ?>
|
|
<div class="query-item n-plus-one">
|
|
<div class="query-count"><?php echo $pattern['count']; ?>x</div>
|
|
<div class="query-time"><?php echo round($pattern['total_time'], 4); ?>s total</div>
|
|
<code class="query-sql"><?php echo esc_html(substr($pattern['example'], 0, 150)); ?>...</code>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php else: ?>
|
|
<p>No query data available. Make sure SAVEQUERIES is enabled.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Toggle Button -->
|
|
<button id="wp-debug-toggle" class="wp-debug-toggle">
|
|
<span class="dashicons dashicons-admin-tools"></span>
|
|
<span class="label">Debug</span>
|
|
</button>
|
|
<?php
|
|
}
|
|
}
|