Skip to content

Instantly share code, notes, and snippets.

@tott
Created May 1, 2012 23:39
Show Gist options
  • Save tott/2572405 to your computer and use it in GitHub Desktop.
Save tott/2572405 to your computer and use it in GitHub Desktop.
debugging WordPress rewrite rules
<?php
add_action( 'generate_rewrite_rules', 'debug_action_generate_rewrite_rules', 1, 1 );
// debug http://core.trac.wordpress.org/browser/trunk/wp-includes/rewrite.php#L1592
// this should only be hit if the rewrite_rules option is empty.
// http://core.trac.wordpress.org/browser/trunk/wp-includes/rewrite.php#L1616
function debug_action_generate_rewrite_rules( $rules ) {
global $debug_action_rules;
error_log( __FUNCTION__ . ' : ' . __LINE__ );
error_log( var_export( $_SERVER, true ) );
error_log( "Rules Option: " . var_export( get_option( 'rewrite_rules' ), true ) );
global $wpdb;
$rules_direct = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s", 'rewrite_rules' ) );
error_log( "Rules Option direct query: " . var_export( $rules_direct, true ) );
error_log( "Generated Rules unfiltered: " . var_export( $rules->rules, true ) );
$trax = array();
$trace = debug_backtrace();
foreach ( $trace as $key => $trc ) {
$trax[$key] = ( isset( $trc['file'] ) ? $trc['file'] : '' ) . '::' . ( isset( $trc['line'] ) ? $trc['line'] : '' ) . ' - ' . $trc['function'];
}
error_log( "Trace: " . var_export( $trax, true ) );
$debug_action_rules = $rules->rules;
error_log( 'Debug End ' . __FUNCTION__ . ' : ' . __LINE__ );
}
add_filter( 'rewrite_rules_array', 'debug_filter_rewrite_rules', 9999, 1 );
// debug the rewrite rules after filters have been applied to see if anything changed
// http://core.trac.wordpress.org/browser/trunk/wp-includes/rewrite.php#L1593
function debug_filter_rewrite_rules( $rules ) {
global $debug_action_rules;
error_log( 'Debug Start ' . __FUNCTION__ . ' : ' . __LINE__ );
error_log( "Generated Rules filtered: " . var_export( $rules, true ) );
if ( serialize( (array) $debug_action_rules ) <> serialize( (array) $rules ) ) {
error_log( "Rewrite rules altered by filter" );
_debug_log_filters( 'rewrite_rules_array' );
_debug_log_filters( 'generate_rewrite_rules' );
}
error_log( 'Debug End ' . __FUNCTION__ . ' : ' . __LINE__ );
return $rules;
}
add_filter( 'pre_option_rewrite_rules', 'debug_filter_pre_option_rewrite_rules', 1, 1 );
// check if something bypasses the option http://core.trac.wordpress.org/browser/trunk/wp-includes/option.php#L36
function debug_filter_pre_option_rewrite_rules( $result ) {
global $wp_filter;
if ( !isset( $wp_filter['pre_option_rewrite_rules'] ) || count( $wp_filter['pre_option_rewrite_rules'] ) == 1 )
return $result;
error_log( 'Debug Start ' . __FUNCTION__ . ' : ' . __LINE__ );
_debug_log_filters( 'pre_option_rewrite_rules' );
error_log( 'Debug End ' . __FUNCTION__ . ' : ' . __LINE__ );
return $result;
}
add_filter( 'option_rewrite_rules', 'debug_filter_option_rewrite_rules', 1, 1 );
// check if something alters the option http://core.trac.wordpress.org/browser/trunk/wp-includes/option.php#L91
function debug_filter_option_rewrite_rules( $result ) {
global $wp_filter;
if ( !isset( $wp_filter['option_rewrite_rules'] ) || count( $wp_filter['option_rewrite_rules'] ) == 1 )
return $result;
error_log( 'Debug Start ' . __FUNCTION__ . ' : ' . __LINE__ );
_debug_log_filters( 'option_rewrite_rules' );
error_log( 'Debug End ' . __FUNCTION__ . ' : ' . __LINE__ );
return $result;
}
add_action( 'request', 'debug_filter_request', 1, 1 );
// store the original query vars to validate if they were altered.
function debug_filter_request( $query_vars ) {
global $debug_query_vars;
$debug_query_vars = $query_vars;
return $query_vars;
}
add_action( 'parse_request', 'debug_action_parse_request', 9999, 1 );
// grab a bunch of request variables http://core.trac.wordpress.org/browser/trunk/wp-includes/class-wp.php#L307
function debug_action_parse_request( $request ) {
global $debug_query_vars;
if ( ( !preg_match( "#^" . $request->matched_rule . "#", $request->request, $matches ) && !preg_match( "#^" . $request->matched_rule . "#", urldecode( $request->request ), $matches ) ) || serialize( $request->query_vars ) <> serialize( $debug_query_vars ) ) {
error_log( 'Debug Start ' . __FUNCTION__ . ' : ' . __LINE__ );
error_log( 'Request : ' . $request->request );
error_log( 'Query Vars unaltered : ' . var_export( $debug_query_vars, true ) );
error_log( 'Query Vars new : ' . var_export( $request->query_vars, true ) );
error_log( 'Matched Rule : ' . $request->matched_rule );
error_log( 'Matched Query : ' . $request->matched_query );
_debug_log_filters( 'request' );
_debug_log_filters( 'parse_request' );
error_log( 'Debug End ' . __FUNCTION__ . ' : ' . __LINE__ );
} else {
return;
}
}
function _debug_log_filters( $name ) {
global $wp_filter;
foreach ( (array) $wp_filter[$name] as $priority => $data ) {
foreach( $data as $key => $function_data ) {
try {
if ( is_array( $function_data['function'] ) && is_callable( $function_data['function'] ) )
$reflection = new ReflectionMethod( $function_data['function'][0], $function_data['function'][1] );
else
$reflection = new ReflectionFunction( $function_data['function'] );
$fline = sprintf( '%s : %s::%d', $reflection->getName(), $reflection->getFileName(), $reflection->getStartLine() );
} catch ( Exception $e ) {
$fline = $function_data['function'];
}
error_log( "Filters/Actions for " . $name . " : " . $priority . " : " . $fline );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment