Skip to content

Commit 12db246

Browse files
committed
feat: agregar plugin Visor de Errores v1.3
- Añade plugin de WordPress para gestión de debug.log - Implementa visualización de logs con resaltado de sintaxis - Incluye funcionalidad de descarga de archivos de log - Agrega sistema de archivado automático con timestamp - Incorpora búsqueda y filtrado en tiempo real - Añade notificaciones automáticas para nuevos errores - Soporte para visualización de logs archivados - Interfaz de administración con permisos de seguridad
0 parents  commit 12db246

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

error-log-viewer.php

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<?php
2+
3+
/**
4+
* Plugin Name: Visor de Errores
5+
* Description: Muestra, descarga y limpia el archivo debug.log desde el panel de administración, con filtro y resaltado.
6+
* Version: 1.3
7+
* Author: Yogui Dev
8+
* Author URI: https://github.com/yogui-dev
9+
*/
10+
11+
if (!defined('ABSPATH')) exit;
12+
13+
define('YD_VE_ERROR_LOG_PATH', ABSPATH . 'wp-content/debug.log');
14+
15+
add_action('admin_menu', 'yd_ve_error_log_viewer_menu');
16+
17+
function yd_ve_error_log_viewer_menu()
18+
{
19+
add_menu_page(
20+
'Visor de Errores',
21+
'Visor de Errores',
22+
'manage_options',
23+
'em-error-log-viewer',
24+
'yd_ve_error_log_viewer_page',
25+
'dashicons-warning',
26+
80
27+
);
28+
}
29+
30+
function yd_ve_error_log_viewer_page()
31+
{
32+
if (!current_user_can('manage_options')) wp_die('No tienes permisos para ver esto.');
33+
34+
// Descargar el archivo
35+
if (isset($_GET['download']) && file_exists(YD_VE_ERROR_LOG_PATH)) {
36+
header('Content-Description: File Transfer');
37+
header('Content-Type: text/plain');
38+
header('Content-Disposition: attachment; filename=debug.log');
39+
header('Content-Length: ' . filesize(YD_VE_ERROR_LOG_PATH));
40+
readfile(YD_VE_ERROR_LOG_PATH);
41+
exit;
42+
}
43+
44+
// Limpiar el archivo (renombrar y crear nuevo vacío)
45+
if (isset($_POST['clear_log']) && check_admin_referer('yd_ve_clear_log')) {
46+
$timestamp = date('Y-m-d_H-i-s');
47+
$old_log_path = dirname(YD_VE_ERROR_LOG_PATH) . "/debug.old.$timestamp.log";
48+
49+
if (file_exists(YD_VE_ERROR_LOG_PATH)) {
50+
// Renombrar el log
51+
rename(YD_VE_ERROR_LOG_PATH, $old_log_path);
52+
// Crear archivo nuevo vacío
53+
file_put_contents(YD_VE_ERROR_LOG_PATH, '');
54+
echo '<div class="notice notice-success"><p>Log archivado como <code>' . esc_html(basename($old_log_path)) . '</code> y nuevo archivo creado.</p></div>';
55+
} else {
56+
echo '<div class="notice notice-warning"><p>No se encontró el archivo debug.log para archivar.</p></div>';
57+
}
58+
}
59+
60+
61+
echo '<div class="wrap"><h1>Visor de Errores (debug.log)</h1>';
62+
63+
if (!file_exists(YD_VE_ERROR_LOG_PATH)) {
64+
echo '<p><strong>No se encontró el archivo debug.log.</strong></p></div>';
65+
return;
66+
}
67+
68+
$selected_log = isset($_GET['logfile']) ? sanitize_file_name($_GET['logfile']) : '';
69+
$log_path = $selected_log ? dirname(YD_VE_ERROR_LOG_PATH) . '/' . $selected_log : YD_VE_ERROR_LOG_PATH;
70+
71+
if (!file_exists($log_path)) {
72+
echo '<p><strong>No se encontró el archivo seleccionado.</strong></p></div>';
73+
return;
74+
}
75+
76+
$log_content = file_get_contents($log_path);
77+
$search_term = isset($_GET['s']) ? sanitize_text_field($_GET['s']) : '';
78+
79+
echo '<form method="get" style="margin-bottom:10px;">';
80+
echo '<input type="hidden" name="page" value="em-error-log-viewer" />';
81+
echo '<input type="text" name="s" value="' . esc_attr($search_term) . '" placeholder="Buscar en el log..." />';
82+
echo '<button class="button">Buscar</button>';
83+
echo '</form>';
84+
85+
echo '<p><a class="button button-primary" href="' . admin_url('admin.php?page=em-error-log-viewer&download=1') . '">📥 Descargar log</a></p>';
86+
87+
echo '<form method="post" style="margin-top:10px;">';
88+
wp_nonce_field('yd_ve_clear_log');
89+
echo '<button type="submit" name="clear_log" class="button">🧹 Limpiar log</button>';
90+
echo '</form>';
91+
92+
echo '<div style="background:#fff; border:1px solid #ccc; padding:10px; max-height:600px; overflow:auto; margin-top:20px; font-family:monospace;">';
93+
94+
$lines = explode(PHP_EOL, $log_content);
95+
$lines = array_reverse($lines); // Muestra últimos errores arriba
96+
97+
foreach ($lines as $line) {
98+
if ($search_term && stripos($line, $search_term) === false) continue;
99+
100+
$style = '';
101+
if (stripos($line, 'Fatal error') !== false) $style = 'color:red;';
102+
elseif (stripos($line, 'Warning') !== false) $style = 'color:orange;';
103+
elseif (stripos($line, 'Notice') !== false) $style = 'color:blue;';
104+
105+
echo '<div style="' . esc_attr($style) . '">' . esc_html($line) . '</div>';
106+
}
107+
108+
// Mostrar lista de logs antiguos
109+
yd_ve_list_old_logs($selected_log);
110+
echo '</div></div>';
111+
}
112+
113+
114+
// Hook para mostrar aviso en el admin si hay nuevos errores
115+
add_action('admin_notices', 'yd_ve_show_new_errors_notice');
116+
117+
function yd_ve_show_new_errors_notice()
118+
{
119+
if (!current_user_can('manage_options')) return;
120+
121+
$log_path = YD_VE_ERROR_LOG_PATH;
122+
if (!file_exists($log_path)) return;
123+
124+
$current_size = filesize($log_path);
125+
$stored_size = get_option('yd_ve_error_log_last_size', 0);
126+
127+
// Si hay nuevo contenido
128+
if ($current_size > $stored_size) {
129+
$size_diff = $current_size - $stored_size;
130+
echo '<div class="notice notice-warning is-dismissible">';
131+
echo '<p><strong>Nuevo error detectado:</strong> El archivo <code>debug.log</code> ha aumentado en <code>' . size_format($size_diff) . '</code>. ';
132+
echo '<a href="' . admin_url('admin.php?page=em-error-log-viewer') . '">Revisar log</a>.</p>';
133+
echo '</div>';
134+
}
135+
}
136+
137+
// Al visitar el visor, actualizar tamaño del log
138+
add_action('admin_init', function () {
139+
if (!current_user_can('manage_options')) return;
140+
141+
if (isset($_GET['page']) && $_GET['page'] === 'em-error-log-viewer') {
142+
if (file_exists(YD_VE_ERROR_LOG_PATH)) {
143+
update_option('yd_ve_error_log_last_size', filesize(YD_VE_ERROR_LOG_PATH));
144+
}
145+
}
146+
});
147+
148+
function yd_ve_list_old_logs($selected_file = '')
149+
{
150+
$dir = dirname(YD_VE_ERROR_LOG_PATH);
151+
$files = glob($dir . '/debug.old.*.log');
152+
153+
if (!$files) {
154+
echo '<p><em>No hay logs antiguos.</em></p>';
155+
return;
156+
}
157+
158+
echo '<h2 style="margin-top:40px;">Logs Archivados</h2>';
159+
echo '<ul style="list-style-type:disc; padding-left:20px;">';
160+
foreach ($files as $file) {
161+
$basename = basename($file);
162+
$link = admin_url('admin.php?page=em-error-log-viewer&logfile=' . urlencode($basename));
163+
$active = ($basename === $selected_file) ? 'font-weight:bold;' : '';
164+
echo '<li><a href="' . esc_url($link) . '" style="' . $active . '">' . esc_html($basename) . '</a></li>';
165+
}
166+
echo '</ul>';
167+
}

0 commit comments

Comments
 (0)