194 lines
4.8 KiB
PHP
194 lines
4.8 KiB
PHP
<?php
|
|
/**
|
|
* Hook Monitor Module
|
|
*
|
|
* Rastrea todos los hooks de WordPress ejecutados
|
|
*
|
|
* @package WP_Debug
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* WP_Debug_Hook_Monitor class
|
|
*/
|
|
class WP_Debug_Hook_Monitor {
|
|
|
|
/**
|
|
* Hooks executed
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $hooks_executed = array();
|
|
|
|
/**
|
|
* Hook execution count
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $hook_counts = array();
|
|
|
|
/**
|
|
* Initialize hook monitor
|
|
*/
|
|
public static function init() {
|
|
// Monitor all actions
|
|
add_action('all', array(__CLASS__, 'track_hook'), 1);
|
|
|
|
// Record hooks on shutdown
|
|
add_action('shutdown', array(__CLASS__, 'record_hooks'), 999);
|
|
}
|
|
|
|
/**
|
|
* Track hook execution
|
|
*
|
|
* @param string $hook Hook name
|
|
*/
|
|
public static function track_hook($hook) {
|
|
// Skip our own hooks to avoid recursion
|
|
if (strpos($hook, 'wp_debug_') === 0) {
|
|
return;
|
|
}
|
|
|
|
// Skip some noisy hooks
|
|
$skip_hooks = array('gettext', 'gettext_with_context', 'ngettext', 'all');
|
|
if (in_array($hook, $skip_hooks)) {
|
|
return;
|
|
}
|
|
|
|
$start_time = microtime(true);
|
|
|
|
// Get backtrace
|
|
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
|
|
$caller = 'unknown';
|
|
if (isset($backtrace[2]['file'])) {
|
|
$caller = basename($backtrace[2]['file']) . ':' . $backtrace[2]['line'];
|
|
}
|
|
|
|
// Store hook info
|
|
$hook_info = array(
|
|
'hook' => $hook,
|
|
'type' => current_filter() === $hook ? 'action' : 'filter',
|
|
'timestamp' => microtime(true),
|
|
'caller' => $caller,
|
|
'args_count' => func_num_args() - 1,
|
|
);
|
|
|
|
self::$hooks_executed[] = $hook_info;
|
|
|
|
// Count executions
|
|
if (!isset(self::$hook_counts[$hook])) {
|
|
self::$hook_counts[$hook] = 0;
|
|
}
|
|
self::$hook_counts[$hook]++;
|
|
}
|
|
|
|
/**
|
|
* Get executed hooks
|
|
*
|
|
* @param array $args Query arguments
|
|
* @return array Hooks
|
|
*/
|
|
public static function get_hooks($args = array()) {
|
|
$defaults = array(
|
|
'search' => '',
|
|
'limit' => 100,
|
|
);
|
|
|
|
$args = wp_parse_args($args, $defaults);
|
|
|
|
$hooks = self::$hooks_executed;
|
|
|
|
// Filter by search
|
|
if ($args['search']) {
|
|
$hooks = array_filter($hooks, function($hook) use ($args) {
|
|
return strpos($hook['hook'], $args['search']) !== false;
|
|
});
|
|
}
|
|
|
|
// Limit results
|
|
if ($args['limit'] > 0) {
|
|
$hooks = array_slice($hooks, 0, $args['limit']);
|
|
}
|
|
|
|
return $hooks;
|
|
}
|
|
|
|
/**
|
|
* Get hook counts
|
|
*
|
|
* @return array Hook counts
|
|
*/
|
|
public static function get_hook_counts() {
|
|
// Sort by count descending
|
|
arsort(self::$hook_counts);
|
|
return self::$hook_counts;
|
|
}
|
|
|
|
/**
|
|
* Get hooks called multiple times
|
|
*
|
|
* @param int $threshold Minimum count
|
|
* @return array Hooks
|
|
*/
|
|
public static function get_frequent_hooks($threshold = 10) {
|
|
return array_filter(self::$hook_counts, function($count) use ($threshold) {
|
|
return $count >= $threshold;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Record hooks on shutdown
|
|
*/
|
|
public static function record_hooks() {
|
|
$total_hooks = count(self::$hooks_executed);
|
|
$unique_hooks = count(self::$hook_counts);
|
|
|
|
// Log summary
|
|
if (class_exists('WP_Debug_Logger')) {
|
|
WP_Debug_Logger::debug("Hooks executed", array(
|
|
'total' => $total_hooks,
|
|
'unique' => $unique_hooks,
|
|
'top_5' => array_slice(self::$hook_counts, 0, 5, true),
|
|
));
|
|
}
|
|
|
|
// Store for frontend panel
|
|
set_transient('wp_debug_hooks_data', array(
|
|
'total' => $total_hooks,
|
|
'unique' => $unique_hooks,
|
|
'hooks' => self::$hooks_executed,
|
|
'counts' => self::$hook_counts,
|
|
), 3600);
|
|
}
|
|
|
|
/**
|
|
* Check if hook was executed
|
|
*
|
|
* @param string $hook Hook name
|
|
* @return bool True if executed
|
|
*/
|
|
public static function was_hook_executed($hook) {
|
|
return isset(self::$hook_counts[$hook]);
|
|
}
|
|
|
|
/**
|
|
* Get hook execution time
|
|
*
|
|
* @param string $hook Hook name
|
|
* @return float|null Execution time in seconds
|
|
*/
|
|
public static function get_hook_execution_time($hook) {
|
|
foreach (self::$hooks_executed as $hook_info) {
|
|
if ($hook_info['hook'] === $hook && isset($hook_info['execution_time'])) {
|
|
return $hook_info['execution_time'];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|