├── README.md ├── redirect.php └── screenshot.png /README.md: -------------------------------------------------------------------------------- 1 | # wp-debug-redirect 2 | Allows you to debug mysterious page redirects 3 | 4 | # How to use it 5 | Simply install and activate the plugin. 6 | 7 | From now on all page redirects that were initiated by WordPress will include some additonal HTTP headers with a stack-trace that triggered the redirect. 8 | 9 | ![Screenshot](/screenshot.png?raw=true "Example of debug headers for a WP redirect") 10 | -------------------------------------------------------------------------------- /redirect.php: -------------------------------------------------------------------------------- 1 | get_trace(); 58 | 59 | if ( ! headers_sent() ) { 60 | foreach ( $trace as $ind => $line ) { 61 | header( "WPDev-Redirect-Trace-$ind: $line", false ); 62 | } 63 | } else { 64 | echo "\n"; 65 | foreach ( $trace as $ind => $line ) { 66 | echo "\n"; 67 | } 68 | } 69 | } 70 | 71 | return $location; 72 | } 73 | 74 | /** 75 | * Generates an array of stack-trace information. Each array item is a 76 | * simple string that can be directly output. 77 | * 78 | * @since 1.0.0 79 | * @return array Trace information 80 | */ 81 | public function get_trace() { 82 | $result = array(); 83 | 84 | $trace = debug_backtrace(); 85 | $trace_count = count( $trace ); 86 | $_num = 0; 87 | $start_at = 0; 88 | 89 | // Skip the first 4 trace lines (filter call inside wp_redirect) 90 | if ( $trace_count > 4 ) { $start_at = 4; } 91 | 92 | for ( $i = $start_at; $i < $trace_count; $i += 1 ) { 93 | $trace_info = $trace[$i]; 94 | $line_info = $trace_info; 95 | $j = $i; 96 | 97 | while ( empty( $line_info['line'] ) && $j < $trace_count ) { 98 | $line_info = $trace[$j]; 99 | $j += 1; 100 | } 101 | 102 | $_file = empty( $line_info['file'] ) ? '' : $line_info['file']; 103 | $_line = empty( $line_info['line'] ) ? '' : $line_info['line']; 104 | $_args = empty( $trace_info['args'] ) ? array() : $trace_info['args']; 105 | $_class = empty( $trace_info['class'] ) ? '' : $trace_info['class']; 106 | $_type = empty( $trace_info['type'] ) ? '' : $trace_info['type']; 107 | $_function = empty( $trace_info['function'] ) ? '' : $trace_info['function']; 108 | 109 | $_num += 1; 110 | $_arg_string = ''; 111 | $_args_arr = array(); 112 | 113 | if ( $i > 0 && is_array( $_args ) && count( $_args ) ) { 114 | foreach ( $_args as $arg ) { 115 | if ( is_scalar( $arg ) ) { 116 | if ( is_bool( $arg ) ) { 117 | $_args_arr[] = ( $arg ? 'true' : 'false' ); 118 | } elseif ( is_string( $arg ) ) { 119 | $_args_arr[] = '"' . $arg . '"'; 120 | } else { 121 | $_args_arr[] = $arg; 122 | } 123 | } elseif ( is_array( $arg ) ) { 124 | $_args_arr[] = '[Array]'; 125 | } elseif ( is_object( $arg ) ) { 126 | $_args_arr[] = '[' . get_class( $arg ) . ']'; 127 | } elseif ( is_null( $arg ) ) { 128 | $_args_arr[] = 'NULL'; 129 | } else { 130 | $_args_arr[] = '[?]'; 131 | } 132 | } 133 | 134 | $_arg_string = implode( ',', $_args_arr ); 135 | } 136 | 137 | if ( strlen( $_file ) > 80 ) { 138 | $_file = '...' . substr( $_file, -77 ); 139 | } else { 140 | $_file = str_pad( $_file, 80, ' ', STR_PAD_RIGHT ); 141 | } 142 | 143 | $result_item = sprintf( 144 | '%s:%s %s(%s)', 145 | $_file, 146 | str_pad( $_line, 5, ' ', STR_PAD_LEFT ), 147 | $_class . $_type . $_function, 148 | $_arg_string 149 | ); 150 | 151 | $_num_str = str_pad( $_num, 2, '0', STR_PAD_LEFT ); 152 | $result[$_num_str] = $result_item; 153 | } 154 | 155 | return $result; 156 | } 157 | 158 | } 159 | WDevDebug_Redirect::instance(); -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stracker-phil/wp-debug-redirect/12758fe92737284a581c68517a031d861e7d6aab/screenshot.png --------------------------------------------------------------------------------