@@ -1,13 +1,15 @@
<?php
/*
Plugin Name: R Debug
Description: Set of helper dump functions for debug.
Description: Set of dump helpers for debug.
Author: Andrey "Rarst" Savchenko
Author URI: http://www.rarst.net/
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
License: MIT
*/
/**
* Class with static dump methods
*/
class R_Debug {
/**
@@ -17,10 +19,15 @@ class R_Debug {
*/
static function list_performance ( $ visible = false ) {
$ stat = sprintf ( '%d queries in %.3f seconds, using %.2fMB memory ' ,
if ( defined ( 'DOING_AJAX ' ) ) {
return ;
}
$ stat = sprintf (
'%d queries in %s seconds, using %.2fMB memory ' ,
get_num_queries (),
timer_stop ( 0 , 3 ),
memory_get_peak_usage () / 1024 / 1024
memory_get_peak_usage () / 1024 / 1024
);
echo $ visible ? $ stat : "<!-- {$ stat } --> " ;
@@ -33,53 +40,88 @@ static function list_performance( $visible = false ) {
*/
static function list_constants ( $ filter = false ) {
$ constants = get_defined_constants ();
$ constants = get_defined_constants ();
if ( false !== $ filter ) {
$ temp = array ();
foreach ( $ constants as $ key => $ constant ) {
if ( false !== stripos ( $ key , $ filter ) || false !== stripos ( $ constant , $ filter ) )
if ( false !== stripos ( $ key , $ filter ) || false !== stripos ( $ constant , $ filter ) ) {
$ temp [$ key ] = $ constant ;
}
}
$ constants = $ temp ;
}
ksort ( $ constants );
var_dump ( $ constants );
self ::dump ( $ constants );
}
/**
* Concatenate print_r of all input and echo in pre tags.
*/
static function dump () {
$ output = '' ;
foreach ( func_get_args () as $ arg ) {
$ output .= print_r ( $ arg , true );
}
echo '<pre> ' . $ output . '</pre> ' ;
}
/**
* List cron entries with time remaining till next run
*/
static function list_cron () {
$ cron = _get_cron_array ();
$ cron = _get_cron_array ();
echo '<pre> ' ;
$ offset = get_option ( 'gmt_offset ' ) * 3600 ;
foreach ( $ cron as $ time => $ entry ) {
$ when ='<strong>In ' . human_time_diff ( $ time ) . '</strong> ( ' . date ( DATE_RSS , $ time ) . ') ' ;
$ when = '<strong>In ' . human_time_diff ( $ time ) . '</strong> ( ' . $ time . ' ' . date_i18n ( DATE_RSS , $ time + $ offset ) . ') ' ;
echo "<br />>>>>> \t{$ when }<br /> " ;
foreach ( array_keys ( $ entry ) as $ function ) {
echo "\t{$ function }<br /> " ;
self ::list_hooks ( $ function );
}
}
echo '</pre> ' ;
}
/**
* List hooks as currently defined
*
* @param bool|string $filter limit to matching names
*/
static function list_hooks ( $ filter = false ) {
global $ wp_filter ;
$ skip_filter = empty ( $ filter );
$ hooks = $ wp_filter ;
ksort ( $ hooks );
foreach ( $ hooks as $ tag => $ hook ) {
if ( $ skip_filter || false !== strpos ( $ tag , $ filter ) ) {
self ::dump_hook ( $ tag , $ hook );
}
}
}
/**
* Output hook info
*
* @param string $tag hook name
* @param array $hook hook data
* @param string $tag hook name
* @param array $hook hook data
*/
static function dump_hook ( $ tag , $ hook ) {
@@ -88,60 +130,41 @@ static function dump_hook( $tag, $hook ) {
echo "<pre>>>>>> \t<strong> {$ tag }</strong><br /> " ;
foreach ( $ hook as $ priority => $ functions ) {
echo $ priority ;
foreach ( $ functions as $ function ) {
echo "\t" ;
$ callback = $ function ['function ' ];
if ( is_string ( $ callback ) )
if ( is_string ( $ callback ) ) {
echo $ callback ;
elseif ( is_string ( $ callback [0 ] ) )
} elseif ( is_a ( $ callback , 'Closure ' ) ) {
$ closure = new ReflectionFunction ( $ callback );
echo 'closure from ' . $ closure ->getFileName () . ':: ' . $ closure ->getStartLine ();
} elseif ( is_string ( $ callback [0 ] ) ) { // static method call
echo $ callback [0 ] . ':: ' . $ callback [1 ];
elseif ( is_object ( $ callback [0 ] ) )
} elseif ( is_object ( $ callback [0 ] ) ) {
echo get_class ( $ callback [0 ] ) . '-> ' . $ callback [1 ];
}
echo (1 == $ function ['accepted_args ' ]) ? '<br /> ' : " ( {$ function ['accepted_args ' ]}) <br /> " ;
echo ( 1 == $ function ['accepted_args ' ] ) ? '<br /> ' : " ( {$ function ['accepted_args ' ]}) <br /> " ;
}
}
echo '</pre> ' ;
}
/**
* List hooks as currently defined
*
* @param bool|string $filter limit to matching names
*/
static function list_hooks ( $ filter = false ) {
global $ wp_filter ;
$ skip_filter = empty ($ filter );
$ hooks = $ wp_filter ;
ksort ( $ hooks );
foreach ( $ hooks as $ tag => $ hook ) {
if ( $ skip_filter || false !== strpos ( $ tag , $ filter ) )
self ::dump_hook ( $ tag , $ hook );
}
}
/**
* Enable live listing of hooks as they run
*
* @param bool|string $hook limit to matching names
*/
static function list_live_hooks ( $ hook = false ) {
if ( false === $ hook )
if ( false === $ hook ) {
$ hook = 'all ' ;
}
add_action ( $ hook , array ( __CLASS__ , 'list_hook_details ' ), - 1 );
}
@@ -150,6 +173,7 @@ static function list_live_hooks( $hook = false ) {
* Handler for live hooks output
*
* @param mixed $input
*
* @return mixed
*/
static function list_hook_details ( $ input = NULL ) {
@@ -158,8 +182,9 @@ static function list_hook_details( $input = NULL ) {
$ tag = current_filter ();
if ( isset ($ wp_filter [$ tag ]) )
if ( isset ( $ wp_filter [$ tag ] ) ) {
self ::dump_hook ( $ tag , $ wp_filter [$ tag ] );
}
return $ input ;
}
@@ -169,7 +194,7 @@ static function list_hook_details( $input = NULL ) {
*/
static function list_plugins () {
var_dump ( get_option ( 'active_plugins ' ) );
self :: dump ( get_option ( 'active_plugins ' ) );
}
/**
@@ -182,28 +207,49 @@ static function list_queries() {
if ( ! defined ( 'SAVEQUERIES ' ) || ! SAVEQUERIES ) {
trigger_error ( 'SAVEQUERIES needs to be defined ' , E_USER_NOTICE );
return ;
}
$ queries = $ wpdb ->queries ;
echo '<pre> ' ;
foreach ( $ queries as $ query ) {
foreach ( $ wpdb -> queries as $ query ) {
list ($ request , $ duration , $ backtrace ) = $ query ;
list ( $ request , $ duration , $ backtrace ) = $ query ;
$ duration = sprintf ( '%f ' , $ duration );
$ backtrace = trim ( array_pop ( explode ( ', ' , $ backtrace ) ) );
$ backtrace = explode ( ', ' , $ backtrace );
$ backtrace = trim ( array_pop ( $ backtrace ) );
if ( 'get_option ' == $ backtrace ) {
preg_match_all ( '/\option_name.*?=.*? \'(.+?) \'/ ' , $ request , $ matches );
$ backtrace .= "( {$ matches [1 ][0 ]}) " ;
}
echo "<br /><strong > {$ request }</strong ><br /> {$ backtrace } in {$ duration }s<br /> " ;
echo "<br /><code > {$ request }</code ><br /> {$ backtrace } in {$ duration }s<br /> " ;
}
echo '</pre> ' ;
echo '<br /></pre> ' ;
}
/**
* Run EXPLAIN on provided MySQL query or last query performed.
*
* @param string $query
*/
static function explain_query ( $ query = '' ) {
/** @var wpdb $wpdb */
global $ wpdb ;
if ( empty ( $ query ) ) {
$ query = $ wpdb ->last_query ;
}
self ::dump (
$ query ,
$ wpdb ->get_results ( 'EXPLAIN EXTENDED ' . $ query ),
$ wpdb ->get_results ( 'SHOW WARNINGS ' )
);
}
}
}