Skip to content

Instantly share code, notes, and snippets.

@Cifro
Forked from thefuxia/t5-wp-load-order.php
Created April 28, 2013 12:22

Revisions

  1. @toscho toscho created this gist Nov 11, 2012.
    273 changes: 273 additions & 0 deletions t5-wp-load-order.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,273 @@
    <?php
    /**
    * Plugin Name: T5 WP Load Order
    * Description: Hooks into every action and creates a list of available variables, constants, functions, classes and files.
    * Plugin URI:
    * Version: 2012.11.05
    * Author: Thomas Scholz
    * Author URI: http://toscho.de
    * Licence: MIT
    * License URI: http://opensource.org/licenses/MIT
    */

    /* Install as mu-plugin, UNCOMMENT the next line
    * Be aware this will be slow, write actions on the log file will happen long
    * after the request is finished, so be patient.
    */
    #new T5_Track_Load;

    class T5_Track_Load
    {
    /**
    * Destination for log file. For each URL a new one.
    *
    * @type string
    */
    protected $log_path = '';

    /**
    * Actions to ignore.
    *
    * @type array
    */
    protected $do_not_track = array (
    'gettext',
    'gettext_with_context'
    );

    /**
    * Already logged details.
    *
    * @type array
    */
    protected $logged = array (
    'files' => array (),
    'globals' => array (),
    'constants' => array (),
    'classes' => array (),
    'functions' => array (),
    );

    /**
    * Constructor
    *
    * @since 2012.11.05
    * @return object of this class
    */
    public function __construct()
    {
    $this->set_log_file_path();
    $this->track();
    add_action( 'all', array ( $this, 'track' ), 100, 100 );
    }

    /**
    * Collect and write data.
    *
    * @return void
    */
    public function track()
    {
    static $called = FALSE;

    $hook = $called ? current_filter() : 'Plugin called: ' . __FILE__;
    $called = TRUE;

    if ( in_array( $hook, $this->do_not_track ) )
    return;

    // Track each hooks just once.
    $this->do_not_track[] = $hook;

    // start tracking
    $files = $this->track_files();
    $globals = $this->track_globals();
    $constants = $this->track_constants();
    $classes = $this->track_classes();
    $functions = $this->track_functions();

    $empty_log = FALSE;

    if ( '' === $files.$globals.$constants.$classes.$functions ) {
    $empty_log = TRUE;
    }

    $log = ( $empty_log ? "\nHook: $hook" : "\n\nHook: $hook\n" )
    . $files . $globals . $constants . $classes . $functions;

    file_put_contents( $this->log_path, $log, FILE_APPEND );
    }

    /**
    * Format logged data to log string.
    *
    * @param array $diff
    * @param string $name
    * @param string $before_item
    * @param string $after_item
    * @return string
    */
    protected function diff_string(
    array $diff,
    $name,
    $before_item = '',
    $after_item = ''
    )
    {
    $num = count( $diff );

    if ( 0 === $num )
    return '';

    $list = join( "$after_item\n - $before_item", $diff );
    return "\n$name: $num\n\n - $before_item$list$after_item\n";
    }

    /**
    * Attempt to recreate the URL currently called.
    *
    * @return string
    */
    protected function get_current_url()
    {
    $url = 'http';

    is_ssl() && $url .= 's';

    $url .= '://' . $_SERVER['HTTP_HOST'];

    if ( ! empty ( $_SERVER['SERVER_PORT'] )
    && 80 !== (int) $_SERVER['SERVER_PORT']
    )
    {
    $url .= $_SERVER['SERVER_PORT'];
    }

    // $_SERVER['REQUEST_URI'] is set in wp-includes/load.php
    // before any plugin is activated.
    $url .= $_SERVER['REQUEST_URI'];

    return $url;
    }

    /**
    * Create the directory and fill $this->log_path.
    *
    * @return void
    */
    protected function set_log_file_path()
    {
    $this->log_path = $this->get_dir_name() . $this->get_log_file_name();
    }

    /**
    * File name for the current log.
    *
    * @return string
    */
    protected function get_log_file_name()
    {
    $base = $_SERVER['HTTP_HOST'] . '-' . $_SERVER['REQUEST_URI'];

    return sanitize_title_with_dashes( $base ) . '.log';
    }

    /**
    * Try to create the directory. Return it on success.
    *
    * @return string
    */
    protected function get_dir_name()
    {
    $upload = wp_upload_dir();
    empty ( $upload['error'] ) || die ( $upload['error'] );
    $dir = $upload['basedir'] . '/t5-track-load-logs';
    wp_mkdir_p( $dir ) || die ( "Could not create $dir." );

    return "$dir/";
    }

    /**
    * New files loaded.
    *
    * @return string
    */
    protected function track_files()
    {
    $diff = $this->register_diff( get_included_files(), 'files' );

    return $this->diff_string( (array) $diff, 'Files' );
    }

    /**
    * New global variables
    *
    * @return string
    */
    protected function track_globals()
    {
    $glob = array_keys( $GLOBALS );
    $diff = $this->register_diff( $glob, 'globals' );

    return $this->diff_string( (array) $diff, 'Globals', '$' );
    }

    /**
    * New defined constants
    *
    * @return string
    */
    protected function track_constants()
    {
    $constants = get_defined_constants( TRUE );
    $names = array_keys( $constants['user'] );
    $diff = $this->register_diff( $names, 'constants' );

    return $this->diff_string( (array) $diff, 'Constants' );
    }

    /**
    * Track new classes.
    *
    * Only classes and subclasses, no subsubclasses.
    * That is a limitation of PHP.
    *
    * @return string
    */
    protected function track_classes()
    {
    $classes = get_declared_classes();
    $diff = $this->register_diff( $classes, 'classes' );

    return $this->diff_string( (array) $diff, 'Classes' );
    }

    /**
    * New defined functions.
    *
    * @return string
    */
    protected function track_functions()
    {
    $functions = get_defined_functions();
    $diff = $this->register_diff( $functions['user'], 'functions' );

    return $this->diff_string( (array) $diff, 'Functions', '', '()' );
    }

    /**
    * Sort new values, compare with already logged values and update log.
    *
    * @param array $new
    * @param string $key
    * @return array
    */
    protected function register_diff( $new, $key )
    {
    sort( $new, SORT_NATURAL | SORT_FLAG_CASE );
    $diff = array_diff( $new, $this->logged[ $key ] );
    $this->logged[ $key ] = $new;

    return $diff;
    }
    }