cfg
1/15/2013 - 1:40 PM

wordpress action/hook logging

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);
});