Last active
December 17, 2015 22:49
-
-
Save Rayken/5685176 to your computer and use it in GitHub Desktop.
Debugging WordPress with the JavaScript Console
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* WordPress Console Debug | |
* | |
* Debug PHP using the JavaScript console. | |
* Enable this plugin and view your console for more information on how to use it. | |
* | |
* @package WP_console_debug | |
* @author DRSK | |
* @license WTFPL | |
* | |
* @wordpress-plugin | |
* Plugin Name: WordPress Console Debug | |
* Description: Debug PHP using the JavaScript console. View your console after activation for more details. | |
* Version: 1.0 | |
* Author: DRSK | |
*/ | |
// If this file is called directly | |
if( !defined( 'WP_PLUGIN_URL' ) || !defined( 'WPINC' ) ) | |
die( 'Restricted access' ); | |
// WP_console_debug | |
class WP_console_debug { | |
/** | |
* Static variables | |
*/ | |
static $console_debug = null; | |
/** | |
* Initialization of the plugin | |
*/ | |
function __construct() { | |
// set up constants for debugging types | |
if( !defined( 'LOG' ) ) define( 'LOG', 1 ); | |
if( !defined( 'INFO' ) ) define( 'INFO', 2 ); | |
if( !defined( 'WARN' ) ) define( 'WARN', 3 ); | |
if( !defined( 'ERROR' ) ) define( 'ERROR', 4 ); | |
// new line | |
define( 'NL', "\r\n" ); | |
// add debugging to footers | |
add_action( 'wp_footer', array( $this, 'print_console' ) ); | |
add_action( 'admin_footer', array( $this, 'print_console' ) ); | |
} | |
/** | |
* Create debugging output in JavaScript | |
*/ | |
public function debug( $name = null, $var = null, $type = LOG ) { | |
global $wpdb, $template; | |
// debugging template files | |
if( $name == TEMPLATE ) | |
$name = basename( $template ); | |
// fallback: if an object or array has been called as $name | |
if( is_object( $name ) || is_array( $name ) ) { | |
$var = $name; | |
$name = null; | |
} | |
// gather information about the call | |
$debug_call = $this->track_debug_call(); | |
// start output | |
if( $debug_call && ( $name || $var ) ) | |
$output = 'console.debug("Debug from '. str_replace( array( "\\" ), "\\\\", $debug_call['file'] ) . ' @ line ' . $debug_call['line']. ':");'.NL; | |
elseif( $debug_call && ( !$name || !$var ) ) | |
$output = 'console.error("Something went wrong. Please check ' . str_replace( array( "\\" ), "\\\\", $debug_call['file'] ) . ' @ line ' . $debug_call['line']. '.");'.NL; | |
// standard output | |
if( $name && ( is_string( $name ) || is_int( $name ) ) ) { | |
switch( $type ) { | |
case LOG: | |
$output .= 'console.log("'.$name.'");'.NL; | |
break; | |
case INFO: | |
$output .= 'console.info("'.$name.'");'.NL; | |
break; | |
case WARN: | |
$output .= 'console.warn("'.$name.'");'.NL; | |
break; | |
case ERROR: | |
$output .= 'console.error("'.$name.'");'.NL; | |
break; | |
} | |
} | |
// if a variable has been set (or $name is an object or array) | |
if( !empty( $var ) ) { | |
if( is_object( $var ) || is_array( $var ) ) { | |
// JSON encode the $var and let the console do its magic | |
if( $var ) | |
$object = json_encode( $var ); | |
else | |
$object = 'No data available'; | |
// uniquify each variable, just in case | |
if( !$name ) | |
$name = intval( $debug_call['line'] ); | |
// create unique JavaScript variables based on $name | |
$output .= 'var object'.preg_replace( '~[^A-Z|0-9]~i', "_", $name ).' = \''.str_replace( array( "'", '\"', '\r\n', '\n' ), "\'", $object ).'\';'.NL; | |
$output .= 'var val'.preg_replace( '~[^A-Z|0-9]~i', "_", $name ).' = eval("(" + object'.preg_replace( '~[^A-Z|0-9]~i', "_", $name ).' + ")" );'.NL; | |
// output for objects and arrays | |
switch($type) { | |
case LOG: | |
$output .= 'console.debug(val'.preg_replace( '~[^A-Z|0-9]~i', "_", $name ).');'.NL; | |
break; | |
case INFO: | |
$output .= 'console.info(val'.preg_replace( '~[^A-Z|0-9]~i', "_", $name ).');'.NL; | |
break; | |
case WARN: | |
$output .= 'console.warn(val'.preg_replace( '~[^A-Z|0-9]~i', "_", $name ).');'.NL; | |
break; | |
case ERROR: | |
$output .= 'console.error(val'.preg_replace( '~[^A-Z|0-9]~i', "_", $name ).');'.NL; | |
break; | |
} | |
} else { | |
// output for variables | |
switch($type) { | |
case LOG: | |
$output .= 'console.debug("'.str_replace( '"', '\\"', $var ).'");'.NL; | |
break; | |
case INFO: | |
$output .= 'console.info("'.str_replace( '"', '\\"', $var ).'");'.NL; | |
break; | |
case WARN: | |
$output .= 'console.warn("'.str_replace( '"', '\\"', $var ).'");'.NL; | |
break; | |
case ERROR: | |
$output .= 'console.error("'.str_replace( '"', '\\"', $var ).'");'.NL; | |
break; | |
} | |
} | |
} | |
// assign the output to the static variable as an array | |
self::$console_debug[] = $output; | |
} | |
/** | |
* Trackback call data from function debug | |
*/ | |
private function track_debug_call() { | |
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); | |
// locate the debugging | |
if( 'console_debug' == $backtrace[2]['function'] ) | |
return $backtrace[2]; | |
else | |
return false; | |
} | |
/** | |
* Output the debugging and help menu | |
*/ | |
public function print_console() { | |
// start WP Console Debug | |
echo NL.'<!-- WordPress Console Debug -->'; | |
// IE and other browsers without a good console | |
$ie = NL.'<!-- Internet Explorer -->' . NL .'<script type="text/javascript">'.NL; | |
$ie .= '(function(f){f||(f=window.console={log:function(a,b,c,d,e){},info:function(a,b,c,d,e){},warn:function(a,b,c,d,e){},error:function(a,b,c,d,e){}});if(!Function.prototype.bind){Function.prototype.bind=function(a){var b=this,args=Array.prototype.slice.call(arguments,1);return function(){return b.apply(a,Array.prototype.concat.apply(args,arguments))}}}if(typeof(f.log)===\'object\'){f.log=Function.prototype.call.bind(f.log,f);f.info=Function.prototype.call.bind(f.info,f);f.warn=Function.prototype.call.bind(f.warn,f);f.error=Function.prototype.call.bind(f.error,f)}(\'group\'in f)||(f.group=function(a){f.info("\n------------\n"+a+"\n------------")});(\'groupEnd\'in f)||(f.groupEnd=function(){});(\'time\'in f)||(function(){var c={};f.time=function(a){c[a]=new Date().getTime()};f.timeEnd=function(a){var b=new Date().getTime(),time=(a in c)?b-c[a]:0;f.info(a+\': \'+time+\'ms\')}}())})(window.console);'; | |
$ie .= 'if (!window.console) console = {};'; | |
$ie .= 'console.log = console.log || function(){};'; | |
$ie .= 'console.warn = console.warn || function(){};'; | |
$ie .= 'console.error = console.error || function(){};'; | |
$ie .= 'console.info = console.info || function(){};'; | |
$ie .= 'console.debug = console.debug || function(){};'; | |
$ie .= 'console.groupCollapsed = console.groupCollapsed || function(){};'; | |
$ie .= 'console.groupEnd = console.groupEnd || function(){};'; | |
$ie .= '</script>'; | |
echo $ie; | |
// set up help menu | |
$help = NL.'<!-- Help Menu -->' . NL .'<script type="text/javascript">'; | |
$help .= 'console.groupCollapsed("WordPress Console Debug");'.NL; | |
$help .= 'console.log("To hide this menu, use: define( \'WPDC_HELP\', false );");'.NL; | |
$help .= 'console.warn("Note: the console is very limited in IE and does not work as intended.");'.NL; | |
$help .= 'console.groupCollapsed("Standard debugging");'.NL; | |
$help .= 'console.debug("Examples for simple debugging");'.NL; | |
$help .= 'console.log("// Simple message to console \nconsole_debug(\"A very simple message\"); \n \n// Variable to console \n$x = 3; \n$y = 5; \n$z = $x/$y; \nconsole_debug(\"Variable Z: \", $z); \n \n// A warning \nconsole_debug(\"A simple Warning\", null, WARN); \n \n// Info \nconsole_debug(\"A simple Info message\", null, INFO); \n \n// An error \nconsole_debug(\"A simple error messsage\", null, ERROR); \n \n// Array in console \n$fruits = array(\"banana\", \"apple\", \"strawberry\", \"pineaple\"); \n$fruits = array_reverse($fruits); \nconsole_debug(\"Fruits array\", $fruits); \n \n \n// Object to console \n$book = new stdClass; \n$book->title = \"Harry Potter and the Prisoner of Azkaban\"; \n$book->author = \"J. K. Rowling\"; \n$book->publisher = \"Arthur A. Levine Books\"; \n$book->amazon_link = \"http://www.amazon.com/dp/0439136369/\"; \nconsole_debug(\"Object\", $book);");'.NL; | |
$help .= 'console.groupEnd();'.NL; | |
$help .= 'console.groupCollapsed("WordPress Debugging");'.NL; | |
$help .= 'console.debug("Examples for WordPress debugging");'.NL; | |
$help .= 'console.log("console_debug(get_the_id());\nconsole_debug(\"Post name:\", $post->post_name);\nconsole_debug(\"Post meta:\", get_post_meta( $post->ID ));\n\n//Check template\nWithin a template: console_debug( TEMPLATE );\nCheck all templates: add_action( \'the_content\', function( $content ) { return $content . console_debug( TEMPLATE ); } );\n\n//Check post data\nWithin a teplate: console_debug( $post );\nCheck post data everywhere: add_action( \'the_content\', function( $content ) { global $post; return $content . console_debug( $post ); } );");'.NL; | |
$help .= 'console.groupEnd();'.NL; | |
$help .= 'console.groupEnd();'.NL; | |
$help .= '</script>'; | |
// if help constant is false, don't show the menu | |
if( ( defined( 'WPDC_HELP' ) && WPDC_HELP !== FALSE ) || !defined( 'WPDC_HELP' ) ) | |
echo $help; | |
// loop debugs | |
if( self::$console_debug ) { | |
$debug_output = NL.'<!-- Debugging -->' . NL .'<script type="text/javascript">'.NL; | |
foreach( self::$console_debug as $debug ) | |
$debug_output .= $debug; | |
$debug_output .= '</script>'; | |
echo $debug_output; | |
} | |
echo NL.'<!-- end: WordPress console debug -->'.NL; | |
} | |
} | |
// create new instance of the class | |
$wp_console_debug = new WP_console_debug(); | |
// debug function | |
function console_debug( $name = null, $var = null, $type = LOG ) { | |
global $wp_console_debug; | |
return $wp_console_debug->debug( $name, $var, $type ); | |
} |
Neat script! Though, just to let you and potential others know: I'm afraid it doesn't work in WordPress hooks where a page redirect is executed immediately after the hook, like publish_to_publish
(pressing "update" on a post). http://wordpress.stackexchange.com/questions/193641/how-to-use-output-buffering-in-wordpress-hooked-functions
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Rev7
Rev8
Rev11
Rev12