wordpress action/hook logging
<?php
/**
* Log all filter and action calls.
*
* Actions and filters are logged to two separate global variables $_x_wp_filters and $_x_wp_actions respectively.
* Hardcode loading this in wp-settings.php to generate a complete tree of filters/actions.
* Add `require_once( '/path/to/hook-logging.php' );` after `require_once( ABSPATH . WPINC . '/plugin.php' );`
*
*/
function x_all_hook_logging($args) {
global $_x_wp_filters, $_x_wp_actions;
if ( ! isset( $_x_wp_filters ) ) {
$_x_wp_filters = array();
}
if ( ! isset( $_x_wp_actions ) ) {
$_x_wp_actions = array();
}
$current_filter = current_filter();
// if did_action returns non-zero, this is an action (the global $wp_actions[$tag] is updated before _wp_call_all_hook is called)
if ( did_action( $current_filter ) ) {
$ref = &$_x_wp_actions; // reference the global actions array
} else {
// it's not an action, so it must be a filter
$ref = &$_x_wp_filters; // reference the global filters array
}
if ( ! isset( $ref[$current_filter] ) ) {
$ref[$current_filter] = array( 'calls' => 0, 'param_counts' => array() );
}
$ref[$current_filter]['calls']++;
if ( ! isset( $ref[$current_filter]['param_counts'][sizeof($args)] ) ) {
$ref[$current_filter]['param_counts'][sizeof($args)] = 0;
}
$ref[$current_filter]['param_counts'][sizeof($args)]++;
}
add_filter('all', 'x_all_hook_logging');
add_action('shutdown', function() {
global $_x_wp_filters, $_x_wp_actions;
$d = function( $filters, $type ) {
foreach( $filters as $f => $v ) {
printf("%s:%s\t%s<br />\n", $type, $f, $v['calls'] );
}
};
// Dump the action/filter call history here.
// Alternatively you could cache the values and display them somewhere else, like the debug bar.
$d( $_x_wp_filters, 'filter' );
echo '<hr />';
$d( $_x_wp_actions, 'action' );
// var_dump($_x_wp_filters);
// echo '<hr />';
// var_dump($_x_wp_actions);
});