DreadyCrig
12/20/2017 - 10:11 PM

Wordpress Debugging and Profiler

Wordpress Debugging and Profiler

<?php
/**
 * Extra debugging and profiling information.
 *
 * Usage information :
 *
 * Add "&debug=" to the url to enable
 *
 * &debug=sql     - dump all querys run
 * &debug=http    -
 * &debug=cache   - dump cache
 * &debug=cron    - show all cron  jobs
 * &debug=phpinfo - phpinfo
 */

if ( WP_DEBUG && array_key_exists( 'debug', $_GET ) )
{
    new SC_Profiler();
}

class SC_Profiler {

    public function __construct()
    {
        if ( ! defined( 'SAVEQUERIES' ) && $this->is_debug( 'sql' ) )
        {
            define('SAVEQUERIES', true);
        }
        if ( array_key_exists( 'debug', $_GET ) && $this->is_debug( 'http' ) )
        {
            add_filter('http_request_args', array( &$this, 'dump_http') , 0, 2 );
        }

        add_action('init', create_function('$in', 'return SC_Profiler::add_stop($in, "Load"); '), 10000000);
        add_action('template_redirect', create_function('$in', 'return SC_Profiler::add_stop($in, "Query");'), -10000000);
        add_action('wp_footer', create_function('$in', 'return SC_Profiler::add_stop($in, "Display");'), 10000000);
        add_action('admin_footer', create_function('$in', 'return SC_Profiler::add_stop($in, "Display");'), 10000000);
        add_action('wp_print_scripts', array( &$this, 'init_dump' ));
        add_action('init', array( &$this, 'dump_phpinfo' ));
    }

    // ------------------------------------------------------------------------

    public function is_debug( $debug )
    {
        return ( array_key_exists( 'debug', $_GET) && $debug === $_GET['debug'] ) ? true : false;
    }

    // ------------------------------------------------------------------------

    /**
     * add_stop()
     *
     * @param mixed $in
     * @param string $where
     * @return mixed $in
     **/
    public static function add_stop($in = null, $where = null)
    {
        global $sem_stops, $wp_object_cache, $wpdb;


        $queries      = get_num_queries();
        $milliseconds = timer_stop() * 1000;
        $out =  "$queries queries - {$milliseconds}ms";
        if ( function_exists('memory_get_usage') )
        {
            $memory = number_format(memory_get_usage() / ( 1024 * 1024 ), 1);
            $out .= " - {$memory}MB";
        }
        $out .= " - $wp_object_cache->cache_hits cache hits / " . ( $wp_object_cache->cache_hits + $wp_object_cache->cache_misses );
        if ( $where )
        {
            $sem_stops[$where] = $out;
        } else {
            dump($out);
        }
        return $in;
    } # add_stop()

    // ------------------------------------------------------------------------

    function dump_stops($in = null)
    {
        if ( $_POST ) return $in;

        global $sem_stops, $wp_object_cache, $wpdb;
        $stops = '';
        foreach ( $sem_stops as $where => $stop ) {
            $stops .= "$where: $stop\n";
        }
        dump("\n" . trim($stops) . "\n");

        if ( defined('SAVEQUERIES') && $this->is_debug( 'sql' ) )
        {
            foreach ( $wpdb->queries as $key => $data )
            {
                $query = rtrim($data[0]);
                $duration = number_format($data[1] * 1000, 1) . 'ms';
                $loc = trim($data[2]);
                $loc = preg_replace("/(require|include)(_once)?,\s*/ix", '', $loc);
                $loc = "\n" . preg_replace("/,\s*/", ",\n", $loc) . "\n";
                dump($query, $duration, $loc);
            }
        }

        if ( $this->is_debug( 'cache') ) dump($wp_object_cache->cache);
        if ( $this->is_debug( 'cron' ) )
        {
            $crons = get_option('cron');
            foreach ( $crons as $time => $_crons ) {
                if ( !is_array($_crons) ) continue;
                foreach ( $_crons as $event => $_cron )
                {
                    foreach ( $_cron as $details )
                    {
                        $date = date('Y-m-d H:m:i', $time);
                        $schedule = isset($details['schedule']) ? "({$details['schedule']})" : '';
                        if ( $details['args'] )
                            dump("$date: $event $schedule", $details['args']);
                        else
                            dump("$date: $event $schedule");
                    }
                }
            }
        }
        return $in;
    } # dump_stops()

    // ------------------------------------------------------------------------

    /**
     * init_dump()
     *
     * @return void
     **/

    function init_dump()
    {
        global $hook_suffix;

        $tag = ( !is_admin() || empty($hook_suffix) ) ? 'admin_footer' : "admin_footer-{$hook_suffix}";
        add_action( $tag,        array( &$this, 'dump_stops' ), 10000000);
        add_action( 'wp_footer', array( &$this, 'dump_stops' ), 10000000);
    } # init_dump()

    // ------------------------------------------------------------------------

    /**
     * dump_phpinfo()
     * @return void
     **/

    function dump_phpinfo()
    {
        if ( false === $this->is_debug( 'phpinfo' ) ) return;
        phpinfo();
        die;
    } # dump_phpinfo()

    // ------------------------------------------------------------------------

    /**
     * dump_http()
     *
     * @param array $args
     * @param string $url
     * @return array $args
     **/

    function dump_http($args, $url)
    {
        dump(preg_replace("|/[0-9a-f]{32}/?$|", '', $url));
        return $args;
    } # dump_http()

    // ------------------------------------------------------------------------

    /**
     * dump_trace()
     *
     * @return void
     **/

    function dump_trace()
    {
        $backtrace = debug_backtrace();
        foreach ( $backtrace as $trace )
        {
            dump(
                'File/Line: ' . $trace['file'] . ', ' . $trace['line'],
                'Function / Class: ' . $trace['function'] . ', ' . $trace['class']
                );
        }
    } # dump_trace()

}