├── .github
└── workflows
│ └── deploy.yml
├── panels
├── class-debug-bar-object-cache.php
├── class-debug-bar-js.php
├── class-debug-bar-panel.php
├── class-debug-bar-request.php
├── class-debug-bar-php.php
├── class-debug-bar-queries.php
├── class-debug-bar-wp-query.php
├── class-debug-bar-deprecated.php
└── class-debug-bar-wp-http.php
├── js
├── debug-bar-js.js
├── ui-dockable.js
├── ui-dockable.dev.js
├── debug-bar.js
├── debug-bar-js.dev.js
└── debug-bar.dev.js
├── css
├── debug-bar.css
└── debug-bar.dev.css
├── readme.txt
└── debug-bar.php
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to WordPress.org
2 | on:
3 | push:
4 | tags:
5 | - "*"
6 |
7 | jobs:
8 | tag:
9 | name: New tag
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@master
13 | - name: WordPress Plugin Deploy
14 | uses: 10up/action-wordpress-plugin-deploy@stable
15 | env:
16 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
17 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
18 |
--------------------------------------------------------------------------------
/panels/class-debug-bar-object-cache.php:
--------------------------------------------------------------------------------
1 | title( __( 'Object Cache', 'debug-bar' ) );
6 | }
7 |
8 | function prerender() {
9 | global $wp_object_cache;
10 | $this->set_visible( is_object( $wp_object_cache ) && method_exists( $wp_object_cache, 'stats' ) );
11 | }
12 |
13 | function render() {
14 | global $wp_object_cache;
15 |
16 | ob_start();
17 | echo "
";
18 | $wp_object_cache->stats();
19 | echo "
";
20 | $out = ob_get_contents();
21 | ob_end_clean();
22 |
23 | echo $out;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/panels/class-debug-bar-js.php:
--------------------------------------------------------------------------------
1 | title( __( 'JavaScript', 'debug-bar' ) );
8 |
9 | /*
10 | * attach here instead of debug_bar_enqueue_scripts
11 | * because we want to be as early as possible!
12 | */
13 | $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '.dev' : '';
14 | wp_enqueue_script( 'debug-bar-js', plugins_url( "js/debug-bar-js$suffix.js", dirname( __FILE__ ) ), array( 'jquery' ), '20111216' );
15 | }
16 |
17 | function render() {
18 | echo '';
19 | echo '
' . __( 'Total Errors:', 'debug-bar' ) . "0
\n";
20 | echo '
' . "\n";
21 | echo '
';
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/js/debug-bar-js.js:
--------------------------------------------------------------------------------
1 | !function(){var e,i,t,r=0,n=[];window.onerror=function(e,i,r){document.getElementById("debug-bar-js-error-count")?t(e,i,r):n[n.length]=[e,i,r]},jQuery(function(){for(err in n)t(n[err][0],n[err][1],n[err][2])}),t=function(t,n,a){var s,o,u,d;if(r++,e||(e=document.getElementById("debug-bar-js-error-count")),i||(i=document.getElementById("debug-bar-js-errors")),e&&i){if(1==r){if(u=document.getElementById("wp-admin-bar-debug-bar"),!u)return;-1===u.className.indexOf("debug-bar-php-warning-summary")&&(u.className=u.className+" debug-bar-php-warning-summary"),["debug-menu-link-Debug_Bar_JS","wp-admin-bar-debug-bar-Debug_Bar_JS"].map(function(e){d=document.getElementById(e),d&&(d.style.display="block")})}e.textContent=r,s=document.createElement("li"),s.className="debug-bar-js-error",s.textContent=t,o=document.createElement("span"),o.textContent=n+" line "+a,s.appendChild(o),i.appendChild(s)}}}();
--------------------------------------------------------------------------------
/js/ui-dockable.js:
--------------------------------------------------------------------------------
1 | (function(a){a.widget("db.dockable",a.ui.mouse,{options:{handle:false,axis:"y",resize:function(){},resized:function(){}},_create:function(){if(this.options.axis=="x"){this.page="pageX";this.dimension="width"}else{this.page="pageY";this.dimension="height"}if(!this.options.handle){return}this.handle=a(this.options.handle);this._mouseInit()},_handoff:function(){return{element:this.element,handle:this.handle,axis:this.options.axis}},_mouseStart:function(b){this._trigger("start",b,this._handoff());this.d0=this.element[this.dimension]()+b[this.page]},_mouseDrag:function(c){var b=this._trigger("resize",c,this._handoff());if(b===false){return}this.element[this.dimension](this.d0-c[this.page]);this._trigger("resized",c,this._handoff())},_mouseCapture:function(b){return !this.options.disabled&&b.target==this.handle[0]},_mouseStop:function(b){this._trigger("stop",b,this._handoff())}})})(jQuery);
--------------------------------------------------------------------------------
/panels/class-debug-bar-panel.php:
--------------------------------------------------------------------------------
1 | title( $title );
9 |
10 | if ( $this->init() === false ) {
11 | $this->set_visible( false );
12 |
13 | return;
14 | }
15 |
16 | add_filter( 'debug_bar_classes', array( $this, 'debug_bar_classes' ) );
17 | }
18 |
19 | function Debug_Bar_Panel( $title = '' ) {
20 | _deprecated_constructor( __METHOD__, '0.8.3', __CLASS__ );
21 | self::__construct( $title );
22 | }
23 |
24 | /**
25 | * Initializes the panel.
26 | */
27 | function init() {}
28 |
29 | function prerender() {}
30 |
31 | /**
32 | * Renders the panel.
33 | */
34 | function render() {}
35 |
36 | function is_visible() {
37 | return $this->_visible;
38 | }
39 |
40 | function set_visible( $visible ) {
41 | $this->_visible = $visible;
42 | }
43 |
44 | /**
45 | * Get/set title.
46 | *
47 | * @param null $title
48 | * @return string|void
49 | */
50 | function title( $title = null ) {
51 | if ( ! isset( $title ) ) {
52 | return $this->_title;
53 | }
54 |
55 | $this->_title = $title;
56 | }
57 |
58 | function debug_bar_classes( $classes ) {
59 | return $classes;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/panels/class-debug-bar-request.php:
--------------------------------------------------------------------------------
1 | title( __('Request', 'debug-bar') );
6 | }
7 |
8 | function prerender() {
9 | $this->set_visible( ! is_admin() );
10 | }
11 |
12 | function render() {
13 | global $wp;
14 |
15 | echo "";
16 |
17 | if ( empty( $wp->request ) ) {
18 | $request = __( 'None', 'debug-bar' );
19 | } else {
20 | $request = $wp->request;
21 | }
22 |
23 | echo '
', __( 'Request:', 'debug-bar' ), '
';
24 | echo '
' . esc_html( $request ) . '
';
25 |
26 | if ( empty( $wp->query_string ) ) {
27 | $query_string = __( 'None', 'debug-bar' );
28 | } else {
29 | $query_string = $wp->query_string;
30 | }
31 |
32 | echo '
', __( 'Query String:', 'debug-bar' ), '
';
33 | echo '
' . esc_html( $query_string ) . '
';
34 |
35 | if ( empty( $wp->matched_rule ) ) {
36 | $matched_rule = __( 'None', 'debug-bar' );
37 | } else {
38 | $matched_rule = $wp->matched_rule;
39 | }
40 |
41 | echo '
', __( 'Matched Rewrite Rule:', 'debug-bar' ), '
';
42 | echo '
' . esc_html( $matched_rule ) . '
';
43 |
44 | if ( empty( $wp->matched_query ) ) {
45 | $matched_query = __( 'None', 'debug-bar' );
46 | } else {
47 | $matched_query = $wp->matched_query;
48 | }
49 |
50 | echo '
', __( 'Matched Rewrite Query:', 'debug-bar' ), '
';
51 | echo '
' . esc_html( $matched_query ) . '
';
52 |
53 | echo '
';
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/js/ui-dockable.dev.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Dockable.
3 | **/
4 | (function($){
5 | $.widget("db.dockable", $.ui.mouse, {
6 | options: {
7 | handle: false,
8 | axis: 'y',
9 | resize: function() {},
10 | resized: function() {}
11 | },
12 | _create: function() {
13 | if ( this.options.axis == 'x' ) {
14 | this.page = 'pageX';
15 | this.dimension = 'width';
16 | } else {
17 | this.page = 'pageY';
18 | this.dimension = 'height';
19 | }
20 |
21 | if ( ! this.options.handle )
22 | return;
23 |
24 | this.handle = $( this.options.handle );
25 |
26 | this._mouseInit();
27 | },
28 | _handoff: function() {
29 | return {
30 | element: this.element,
31 | handle: this.handle,
32 | axis: this.options.axis
33 | };
34 | },
35 | _mouseStart: function(event) {
36 | this._trigger( "start", event, this._handoff() );
37 | this.d0 = this.element[this.dimension]() + event[this.page];
38 | },
39 | _mouseDrag: function(event) {
40 | var resize = this._trigger( "resize", event, this._handoff() );
41 |
42 | // If the resize event returns false, we don't resize.
43 | if ( resize === false )
44 | return;
45 |
46 | this.element[this.dimension]( this.d0 - event[this.page] );
47 | this._trigger( "resized", event, this._handoff() );
48 | },
49 | _mouseCapture: function(event) {
50 | return !this.options.disabled && event.target == this.handle[0];
51 | },
52 | _mouseStop: function(event) {
53 | this._trigger( "stop", event, this._handoff() );
54 | }
55 | });
56 | })(jQuery);
--------------------------------------------------------------------------------
/js/debug-bar.js:
--------------------------------------------------------------------------------
1 | var wpDebugBar;!function(e){var i;wpDebugBar=i={body:void 0,init:function(){i.body=e(document.body),i.toggle.init(),i.tabs(),i.actions.init()},isVisible:function(){return i.body.hasClass("debug-bar-visible")},toggle:{init:function(){e("#wp-admin-bar-debug-bar").click(function(t){if(t.preventDefault(),t.target.hash){var s=e(t.target.rel);if(i.isVisible()){if(s.hasClass("current"))return s.removeClass("current"),void i.toggle.visibility()}else i.toggle.visibility();e(".debug-menu-target").hide().trigger("debug-bar-hide"),e(".debug-menu-link").removeClass("current"),s.addClass("current"),e(t.target.hash).show().trigger("debug-bar-show")}else i.toggle.visibility()})},visibility:function(t){t=void 0===t?!i.isVisible():t,i.body.toggleClass("debug-bar-visible",t),e(this).toggleClass("active",t)}},tabs:function(){var i=e(".debug-menu-link"),t=e(".debug-menu-target");i.click(function(s){var r=e(this);s.preventDefault(),r.hasClass("current")||(t.hide().trigger("debug-bar-hide"),i.removeClass("current"),r.addClass("current"),e("#"+this.href.substr(this.href.indexOf("#")+1)).show().trigger("debug-bar-show"))})},actions:{init:function(){var t=e("#debug-bar-actions");e(document).keydown(function(e){var t=e.key||e.which||e.keyCode;27===t&&i.isVisible()&&(e.preventDefault(),i.actions.close())}),e(".maximize",t).click(i.actions.maximize),e(".restore",t).click(i.actions.restore),e(".close",t).click(i.actions.close)},maximize:function(){i.body.removeClass("debug-bar-partial"),i.body.addClass("debug-bar-maximized")},restore:function(){i.body.removeClass("debug-bar-maximized"),i.body.addClass("debug-bar-partial")},close:function(){i.toggle.visibility(!1)}}},e(wpDebugBar.init)}(jQuery);
--------------------------------------------------------------------------------
/js/debug-bar-js.dev.js:
--------------------------------------------------------------------------------
1 | ( function() {
2 | var count, list, dbjsError,
3 | rawCount = 0,
4 | errors = [];
5 |
6 | window.onerror = function ( errorMsg, url, lineNumber ) {
7 | if ( ! document.getElementById( 'debug-bar-js-error-count' ) ) {
8 | errors[ errors.length ] = [ errorMsg, url, lineNumber ];
9 | } else {
10 | dbjsError( errorMsg, url, lineNumber );
11 | }
12 | };
13 |
14 | jQuery( function () {
15 | for ( err in errors ) {
16 | dbjsError( errors[ err ][0], errors[ err ][1], errors[ err ][2] );
17 | }
18 | } );
19 |
20 | dbjsError = function dbjsError( errorMsg, url, lineNumber ) {
21 | var errorLine, place, button, tab;
22 |
23 | rawCount++;
24 |
25 | if ( ! count ) {
26 | count = document.getElementById( 'debug-bar-js-error-count' );
27 | }
28 | if ( ! list ) {
29 | list = document.getElementById( 'debug-bar-js-errors' );
30 | }
31 |
32 | if ( ! count || ! list ) {
33 | return; // threw way too early... @todo cache these?
34 | }
35 |
36 | if ( 1 == rawCount ) {
37 | button = document.getElementById( 'wp-admin-bar-debug-bar' );
38 |
39 | if ( ! button ) {
40 | return; // how did this happen?
41 | }
42 |
43 | if ( -1 === button.className.indexOf( 'debug-bar-php-warning-summary' ) ) {
44 | button.className = button.className + ' debug-bar-php-warning-summary';
45 | }
46 |
47 | [ 'debug-menu-link-Debug_Bar_JS', 'wp-admin-bar-debug-bar-Debug_Bar_JS' ].map( function( id ) {
48 | tab = document.getElementById( id );
49 | if ( tab ) {
50 | tab.style.display = 'block';
51 | }
52 | } );
53 | }
54 |
55 | count.textContent = rawCount;
56 |
57 | errorLine = document.createElement( 'li' );
58 | errorLine.className = 'debug-bar-js-error';
59 | errorLine.textContent = errorMsg;
60 |
61 | place = document.createElement( 'span' );
62 | place.textContent = url + ' line ' + lineNumber;
63 |
64 | errorLine.appendChild( place );
65 | list.appendChild( errorLine );
66 | };
67 | } )();
68 |
--------------------------------------------------------------------------------
/panels/class-debug-bar-php.php:
--------------------------------------------------------------------------------
1 | title( __( 'Notices / Warnings', 'debug-bar' ) );
14 |
15 | $this->real_error_handler = set_error_handler( array( &$this, 'error_handler' ) );
16 | }
17 |
18 | function is_visible() {
19 | return count( $this->notices ) || count( $this->warnings );
20 | }
21 |
22 | function debug_bar_classes( $classes ) {
23 | if ( count( $this->warnings ) ) {
24 | $classes[] = 'debug-bar-php-warning-summary';
25 | } elseif ( count( $this->notices ) ) {
26 | $classes[] = 'debug-bar-php-notice-summary';
27 | }
28 |
29 | return $classes;
30 | }
31 |
32 | function error_handler( $type, $message, $file, $line ) {
33 | $_key = md5( $file . ':' . $line . ':' . $message );
34 |
35 | if ( ! defined( 'E_DEPRECATED' ) ) {
36 | define( 'E_DEPRECATED', 8192 );
37 | }
38 | if ( ! defined( 'E_USER_DEPRECATED' ) ) {
39 | define( 'E_USER_DEPRECATED', 16384 );
40 | }
41 |
42 | switch ( $type ) {
43 | case E_WARNING:
44 | case E_USER_WARNING:
45 | $this->warnings[ $_key ] = array(
46 | $file . ':' . $line,
47 | $message,
48 | wp_debug_backtrace_summary( __CLASS__ ),
49 | );
50 | break;
51 | case E_NOTICE:
52 | case E_USER_NOTICE:
53 | $this->notices[ $_key ] = array(
54 | $file . ':' . $line,
55 | $message,
56 | wp_debug_backtrace_summary( __CLASS__ ),
57 | );
58 | break;
59 | case E_DEPRECATED:
60 | case E_USER_DEPRECATED:
61 | // TODO
62 | break;
63 | case 0:
64 | // TODO
65 | break;
66 | }
67 |
68 | if ( null != $this->real_error_handler ) {
69 | return call_user_func( $this->real_error_handler, $type, $message, $file, $line );
70 | } else {
71 | return false;
72 | }
73 | }
74 |
75 | function render() {
76 | echo "";
77 | echo '
', __( 'Total Warnings:', 'debug-bar' ), '', number_format_i18n( count( $this->warnings ) ), "
\n";
78 | echo '
', __( 'Total Notices:', 'debug-bar' ), '', number_format_i18n( count( $this->notices ) ), "
\n";
79 |
80 | if ( count( $this->warnings ) ) {
81 | echo '
';
82 | foreach ( $this->warnings as $location_message_stack ) {
83 | list( $location, $message, $stack ) = $location_message_stack;
84 | echo '- ', __( 'WARNING:', 'debug-bar' ), ' ';
85 | echo str_replace( ABSPATH, '', $location ) . ' - ' . strip_tags( $message );
86 | echo '
';
87 | echo $stack;
88 | echo ' ';
89 | }
90 | echo '
';
91 | }
92 |
93 | if ( count( $this->notices ) ) {
94 | echo '
';
95 | foreach ( $this->notices as $location_message_stack ) {
96 | list( $location, $message, $stack ) = $location_message_stack;
97 | echo '- ', __( 'NOTICE:', 'debug-bar' ), ' ';
98 | echo str_replace( ABSPATH, '', $location ) . ' - ' . strip_tags( $message );
99 | echo '
';
100 | echo $stack;
101 | echo ' ';
102 | }
103 | echo '
';
104 | }
105 |
106 | echo "
";
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/panels/class-debug-bar-queries.php:
--------------------------------------------------------------------------------
1 | title( __( 'Queries', 'debug-bar' ) );
7 | }
8 |
9 | function prerender() {
10 | $this->set_visible( defined( 'SAVEQUERIES' ) && SAVEQUERIES || ! empty( $GLOBALS['EZSQL_ERROR'] ) );
11 | }
12 |
13 | function debug_bar_classes( $classes ) {
14 | if ( ! empty( $GLOBALS['EZSQL_ERROR'] ) ) {
15 | $classes[] = 'debug-bar-php-warning-summary';
16 | }
17 |
18 | return $classes;
19 | }
20 |
21 | function render() {
22 | global $wpdb, $EZSQL_ERROR;
23 |
24 | $out = '';
25 | $total_time = 0;
26 |
27 | if ( ! empty( $wpdb->queries ) ) {
28 | $show_many = isset( $_GET['debug_queries'] );
29 |
30 | if ( $wpdb->num_queries > 500 && ! $show_many ) {
31 | /* translators: %s = a url. */
32 | $out .= "" . sprintf( __( 'There are too many queries to show easily! Show them anyway', 'debug-bar' ), esc_url( add_query_arg( 'debug_queries', 'true' ) ) ) . "
";
33 | }
34 |
35 | $out .= '';
36 | $counter = 0;
37 |
38 | foreach ( $wpdb->queries as $q ) {
39 | list( $query, $elapsed, $debug ) = $q;
40 |
41 | $total_time += $elapsed;
42 |
43 | if ( ++$counter > 500 && ! $show_many ) {
44 | continue;
45 | }
46 |
47 | $debug = explode( ', ', $debug );
48 | $debug = array_diff( $debug, array( 'require_once', 'require', 'include_once', 'include' ) );
49 | $debug = implode( ', ', $debug );
50 | $debug = str_replace( array( 'do_action, call_user_func_array' ), array( 'do_action' ), $debug );
51 | $debug = esc_html( $debug );
52 | $query = nl2br( esc_html( $query ) );
53 | /* translators: %s = duration in milliseconds. */
54 | $time = esc_html( sprintf( __( '%s ms', 'debug-bar' ), number_format_i18n( ( $elapsed * 1000 ), 1 ) ) );
55 |
56 | $out .= "- $query
$debug #$counter ($time)
\n";
57 | }
58 | $out .= '
';
59 | } else if ( 0 === $wpdb->num_queries ) {
60 | $out .= "" . __( 'There are no queries on this page.', 'debug-bar' ) . "
";
61 | } else {
62 | $out .= "" . __( 'SAVEQUERIES must be defined to show the query log.', 'debug-bar' ) . "
";
63 | }
64 |
65 | if ( ! empty( $EZSQL_ERROR ) ) {
66 | $out .= '' . __( 'Database Errors', 'debug-bar' ) . '
';
67 | $out .= '';
68 |
69 | foreach ( $EZSQL_ERROR as $error ) {
70 | $query = nl2br( esc_html( $error['query'] ) );
71 | $message = esc_html( $error['error_str'] );
72 | $out .= "- $query
$message
\n";
73 | }
74 | $out .= '
';
75 | }
76 |
77 | $heading = '';
78 | if ( $wpdb->num_queries ) {
79 | $heading .= '' . __( 'Total Queries:', 'debug-bar' ) . '' . number_format_i18n( $wpdb->num_queries ) . "
\n";
80 | }
81 | if ( $total_time ) {
82 | $heading .= '' . __( 'Total query time:', 'debug-bar' ) . '';
83 | /* translators: %s = duration in milliseconds. */
84 | $heading .= sprintf( __( '%s ms', 'debug-bar' ), number_format_i18n( ( $total_time * 1000 ), 1 ) ) . "
\n";
85 | }
86 | if ( ! empty( $EZSQL_ERROR ) ) {
87 | $heading .= '' . __( 'Total DB Errors:', 'debug-bar' ) . '' . number_format_i18n( count( $EZSQL_ERROR ) ) . "
\n";
88 | }
89 |
90 | echo $heading . $out;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/js/debug-bar.dev.js:
--------------------------------------------------------------------------------
1 | var wpDebugBar;
2 |
3 | ( function( $ ) {
4 | var api;
5 |
6 | wpDebugBar = api = {
7 | // The element that we will pad to prevent the debug bar
8 | // from overlapping the bottom of the page.
9 | body: undefined,
10 |
11 | init: function init() {
12 | // If we're not in the admin, pad the body.
13 | api.body = $( document.body );
14 |
15 | api.toggle.init();
16 | api.tabs();
17 | api.actions.init();
18 | },
19 |
20 | isVisible: function isVisible() {
21 | return api.body.hasClass( 'debug-bar-visible' );
22 | },
23 |
24 | toggle: {
25 | init: function init() {
26 | $( '#wp-admin-bar-debug-bar' ).on( 'click', function onClickAdminBarMenu( event ) {
27 | event.preventDefault();
28 |
29 | // Click on submenu item.
30 | if ( event.target.hash ) {
31 | var $menuLink = $( event.target.rel );
32 |
33 | // Open/close debug bar.
34 | if ( ! api.isVisible() ) {
35 | api.toggle.visibility();
36 | } else if ( $menuLink.hasClass( 'current' ) ) {
37 | $menuLink.removeClass( 'current' );
38 | api.toggle.visibility();
39 |
40 | return;
41 | }
42 |
43 | // Deselect other tabs and hide other panels.
44 | $( '.debug-menu-target' ).hide().trigger( 'debug-bar-hide' );
45 | $( '.debug-menu-link' ).removeClass( 'current' );
46 |
47 | $menuLink.addClass( 'current' );
48 | $( event.target.hash ).show().trigger( 'debug-bar-show' );
49 | } else {
50 | api.toggle.visibility();
51 | }
52 | } );
53 | },
54 | visibility: function visibility( show ) {
55 | show = typeof show == 'undefined' ? ! api.isVisible() : show;
56 |
57 | // Show/hide the debug bar.
58 | api.body.toggleClass( 'debug-bar-visible', show );
59 |
60 | // Press/unpress the button.
61 | $( this ).toggleClass( 'active', show );
62 | }
63 | },
64 |
65 | tabs: function tabs() {
66 | var debugMenuLinks = $( '.debug-menu-link' ),
67 | debugMenuTargets = $( '.debug-menu-target' );
68 |
69 | debugMenuLinks.on( 'click', function onClickLink( event ) {
70 | var $this = $( this );
71 |
72 | event.preventDefault();
73 |
74 | if ( $this.hasClass( 'current' ) ) {
75 | return;
76 | }
77 |
78 | // Deselect other tabs and hide other panels.
79 | debugMenuTargets.hide().trigger( 'debug-bar-hide' );
80 | debugMenuLinks.removeClass( 'current' );
81 |
82 | // Select the current tab and show the current panel.
83 | $this.addClass( 'current' );
84 | // The hashed component of the href is the id that we want to display.
85 | $( '#' + this.href.substr( this.href.indexOf( '#' ) + 1 ) ).show().trigger( 'debug-bar-show' );
86 | } );
87 | },
88 |
89 | actions: {
90 | init: function init() {
91 | var actions = $( '#debug-bar-actions' );
92 |
93 | // Close the panel with the esc key if it's open.
94 | $( document ).on( 'keydown', function maybeClosePanel( event ) {
95 | var key = event.key || event.which || event.keyCode;
96 |
97 | if ( (27 === key || 'Escape' === key) && api.isVisible() ) {
98 | event.preventDefault();
99 | api.actions.close();
100 | }
101 | } );
102 |
103 | $( '.maximize', actions ).on( 'click', api.actions.maximize );
104 | $( '.restore', actions ).on( 'click', api.actions.restore );
105 | $( '.close', actions ).on( 'click', api.actions.close );
106 | },
107 | maximize: function maximize() {
108 | api.body.removeClass( 'debug-bar-partial' );
109 | api.body.addClass( 'debug-bar-maximized' );
110 | },
111 | restore: function restore() {
112 | api.body.removeClass( 'debug-bar-maximized' );
113 | api.body.addClass( 'debug-bar-partial' );
114 | },
115 | close: function close() {
116 | api.toggle.visibility( false );
117 | }
118 | }
119 | };
120 |
121 | $( wpDebugBar.init );
122 |
123 | } )( jQuery );
124 |
--------------------------------------------------------------------------------
/panels/class-debug-bar-wp-query.php:
--------------------------------------------------------------------------------
1 | title( __( 'WP Query', 'debug-bar' ) );
6 | }
7 |
8 | function prerender() {
9 | $this->set_visible( defined( 'SAVEQUERIES' ) && SAVEQUERIES );
10 | }
11 |
12 | function render() {
13 | global $template, $wp_query, $wpdb;
14 |
15 | $queried_object = get_queried_object();
16 | if ( $queried_object && isset( $queried_object->post_type ) ) {
17 | $post_type_object = get_post_type_object( $queried_object->post_type );
18 | }
19 |
20 | echo "";
21 | echo '
', __( 'Queried Object ID:', 'debug-bar' ), '', get_queried_object_id(), "
\n";
22 |
23 | // Determine the query type. Follows the template loader order.
24 | $type = '';
25 | if ( is_404() ) {
26 | $type = __( '404', 'debug-bar' );
27 | } elseif ( is_search() ) {
28 | $type = __( 'Search', 'debug-bar' );
29 | } elseif ( is_tax() ) {
30 | $type = __( 'Taxonomy', 'debug-bar' );
31 | } elseif ( is_front_page() ) {
32 | $type = __( 'Front Page', 'debug-bar' );
33 | } elseif ( is_home() ) {
34 | $type = __( 'Home', 'debug-bar' );
35 | } elseif ( is_attachment() ) {
36 | $type = __( 'Attachment', 'debug-bar' );
37 | } elseif ( is_single() ) {
38 | $type = __( 'Single', 'debug-bar' );
39 | } elseif ( is_page() ) {
40 | $type = __( 'Page', 'debug-bar' );
41 | } elseif ( is_category() ) {
42 | $type = __( 'Category', 'debug-bar' );
43 | } elseif ( is_tag() ) {
44 | $type = __( 'Tag', 'debug-bar' );
45 | } elseif ( is_author() ) {
46 | $type = __( 'Author', 'debug-bar' );
47 | } elseif ( is_date() ) {
48 | $type = __( 'Date', 'debug-bar' );
49 | } elseif ( is_archive() ) {
50 | $type = __( 'Archive', 'debug-bar' );
51 | } elseif ( is_paged() ) {
52 | $type = __( 'Paged', 'debug-bar' );
53 | }
54 |
55 | if ( ! empty( $type ) ) {
56 | echo '
', __( 'Query Type:', 'debug-bar' ), '', $type, "
\n";
57 | }
58 |
59 | if ( ! empty( $template ) ) {
60 | echo '
', __( 'Query Template:', 'debug-bar' ), '', basename( $template ), "
\n";
61 | }
62 |
63 | $show_on_front = get_option( 'show_on_front' );
64 | $page_on_front = get_option( 'page_on_front' );
65 | $page_for_posts = get_option( 'page_for_posts' );
66 |
67 | echo '
', __( 'Show on Front:', 'debug-bar' ), '', $show_on_front, "
\n";
68 | if ( 'page' == $show_on_front ) {
69 | echo '
', __( 'Page for Posts:', 'debug-bar' ), '', $page_for_posts, "
\n";
70 | echo '
', __( 'Page on Front:', 'debug-bar' ), '', $page_on_front, "
\n";
71 | }
72 |
73 | if ( isset( $post_type_object ) ) {
74 | echo '
', __( 'Post Type:', 'debug-bar' ), '', $post_type_object->labels->singular_name, "
\n";
75 | }
76 |
77 | echo '
';
78 |
79 | if ( empty( $wp_query->query ) ) {
80 | $query = __( 'None', 'debug-bar' );
81 | } else {
82 | $query = http_build_query( $wp_query->query );
83 | }
84 |
85 | echo '
', __( 'Query Arguments:', 'debug-bar' ), '
';
86 | echo '
' . esc_html( $query ) . '
';
87 |
88 | if ( ! empty( $wp_query->request ) ) {
89 | echo '
', __( 'Query SQL:', 'debug-bar' ), '
';
90 | if ( is_callable( array( $wpdb, 'remove_placeholder_escape' ) ) ) {
91 | echo '
' . esc_html( $wpdb->remove_placeholder_escape( $wp_query->request ) ) . '
';
92 | } else {
93 | echo '
' . esc_html( $wp_query->request ) . '
';
94 | }
95 | }
96 |
97 | if ( ! is_null( $queried_object ) ) {
98 | echo '
', __( 'Queried Object:', 'debug-bar' ), '
';
99 | echo '
';
100 | $this->_recursive_print_kv( $queried_object );
101 | echo '
';
102 | }
103 | echo '
';
104 | }
105 |
106 | protected function _recursive_print_kv( $kv_array ) {
107 | foreach ( $kv_array as $key => $value ) {
108 | if ( is_object( $value ) || is_array( $value ) ) {
109 | echo '| ', $key, ' | ⇒ | ';
110 | $this->_recursive_print_kv( $value );
111 | echo ' |
';
112 | } else {
113 | echo '| ', $key, ' | ⇒ | ', $value, ' |
';
114 | }
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/panels/class-debug-bar-deprecated.php:
--------------------------------------------------------------------------------
1 | title( __( 'Deprecated', 'debug-bar' ) );
12 |
13 | add_action( 'deprecated_function_run', array( $this, 'deprecated_function_run' ), 10, 3 );
14 | add_action( 'deprecated_file_included', array( $this, 'deprecated_file_included' ), 10, 4 );
15 | add_action( 'deprecated_argument_run', array( $this, 'deprecated_argument_run' ), 10, 3 );
16 |
17 | // Silence E_NOTICE for deprecated usage.
18 | foreach ( array( 'function', 'file', 'argument' ) as $item ) {
19 | add_filter( "deprecated_{$item}_trigger_error", '__return_false' );
20 | }
21 | }
22 |
23 | function prerender() {
24 | $this->set_visible(
25 | count( $this->deprecated_functions )
26 | || count( $this->deprecated_files )
27 | || count( $this->deprecated_arguments )
28 | );
29 | }
30 |
31 | function render() {
32 | echo "";
33 | echo '
', __( 'Total Functions:', 'debug-bar' ), '', number_format_i18n( count( $this->deprecated_functions ) ), "
\n";
34 | echo '
', __( 'Total Arguments:', 'debug-bar' ), '', number_format_i18n( count( $this->deprecated_arguments ) ), "
\n";
35 | echo '
', __( 'Total Files:', 'debug-bar' ), '', number_format_i18n( count( $this->deprecated_files ) ), "
\n";
36 | if ( count( $this->deprecated_functions ) ) {
37 | echo '
';
38 | foreach ( $this->deprecated_functions as $location => $message_stack ) {
39 | list( $message, $stack ) = $message_stack;
40 | echo "- ";
41 | echo str_replace( ABSPATH, '', $location ) . ' - ' . strip_tags( $message );
42 | echo "
";
43 | echo $stack;
44 | echo " ";
45 | }
46 | echo '
';
47 | }
48 | if ( count( $this->deprecated_files ) ) {
49 | echo '
';
50 | foreach ( $this->deprecated_files as $location => $message_stack ) {
51 | list( $message, $stack ) = $message_stack;
52 | echo "- ";
53 | echo str_replace( ABSPATH, '', $location ) . ' - ' . strip_tags( $message );
54 | echo "
";
55 | echo $stack;
56 | echo " ";
57 | }
58 | echo '
';
59 | }
60 | if ( count( $this->deprecated_arguments ) ) {
61 | echo '
';
62 | foreach ( $this->deprecated_arguments as $location => $message_stack ) {
63 | list( $message, $stack ) = $message_stack;
64 | echo "- ";
65 | echo str_replace( ABSPATH, '', $location ) . ' - ' . strip_tags( $message );
66 | echo "
";
67 | echo $stack;
68 | echo " ";
69 | }
70 | echo '
';
71 | }
72 | echo "
";
73 | }
74 |
75 | function deprecated_function_run( $function, $replacement, $version ) {
76 | $backtrace = debug_backtrace( false );
77 | $bt = 4;
78 |
79 | // Check if we're a hook callback.
80 | if ( ! isset( $backtrace[4]['file'] ) && 'call_user_func_array' == $backtrace[5]['function'] ) {
81 | $bt = 6;
82 | }
83 |
84 | $location = $backtrace[ $bt ]['file'] . ':' . $backtrace[ $bt ]['line'];
85 |
86 | if ( ! is_null( $replacement ) ) {
87 | /* translators: %1$s is a function or file name, %2$s a version number, %3$s an alternative function or file to use. */
88 | $message = sprintf( __( '%1$s is deprecated since version %2$s! Use %3$s instead.', 'debug-bar' ), $function, $version, $replacement );
89 | } else {
90 | /* translators: %1$s is a function or file name, %2$s a version number. */
91 | $message = sprintf( __( '%1$s is deprecated since version %2$s with no alternative available.', 'debug-bar' ), $function, $version );
92 | }
93 |
94 | $this->deprecated_functions[ $location ] = array( $message, wp_debug_backtrace_summary( null, $bt ) );
95 | }
96 |
97 | function deprecated_file_included( $old_file, $replacement, $version, $message ) {
98 | $backtrace = debug_backtrace( false );
99 | $file = $backtrace[4]['file'];
100 | $file_abs = str_replace( ABSPATH, '', $file );
101 | $location = $file . ':' . $backtrace[4]['line'];
102 | $message = empty( $message ) ? '' : ' ' . $message;
103 |
104 | if ( ! is_null( $replacement ) ) {
105 | /* translators: %1$s is a function or file name, %2$s a version number, %3$s an alternative function or file to use. */
106 | $message = sprintf( __( '%1$s is deprecated since version %2$s! Use %3$s instead.', 'debug-bar' ), $file_abs, $version, $replacement ) . $message;
107 | } else {
108 | /* translators: %1$s is a function or file name, %2$s a version number. */
109 | $message = sprintf( __( '%1$s is deprecated since version %2$s with no alternative available.', 'debug-bar' ), $file_abs, $version ) . $message;
110 | }
111 |
112 | $this->deprecated_files[ $location ] = array( $message, wp_debug_backtrace_summary( null, 4 ) );
113 | }
114 |
115 | function deprecated_argument_run( $function, $message, $version ) {
116 | $backtrace = debug_backtrace( false );
117 |
118 | if ( 'define()' === $function ) {
119 | $this->deprecated_arguments[] = array( $message, '' );
120 |
121 | return;
122 | }
123 |
124 | $bt = 4;
125 | if ( ! isset( $backtrace[4]['file'] ) && 'call_user_func_array' == $backtrace[5]['function'] ) {
126 | $bt = 6;
127 | }
128 |
129 | $location = $backtrace[ $bt ]['file'] . ':' . $backtrace[ $bt ]['line'];
130 |
131 | if ( ! is_null( $message ) ) {
132 | /* translators: 1: PHP function name, 2: Version number, 3: Optional message regarding the change. */
133 | $message = sprintf( __( '%1$s was called with an argument that is deprecated since version %2$s! %3$s', 'debug-bar' ), $function, $version, $message );
134 | } else {
135 | /* translators: 1: PHP function name, 2: Version number. */
136 | $message = sprintf( __( '%1$s was called with an argument that is deprecated since version %2$s with no alternative available.', 'debug-bar' ), $function, $version );
137 | }
138 |
139 | $this->deprecated_arguments[ $location ] = array( $message, wp_debug_backtrace_summary( null, $bt ) );
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/panels/class-debug-bar-wp-http.php:
--------------------------------------------------------------------------------
1 | requests["{$args['time_start']}"] = [
19 | 'url' => $url,
20 | 'args' => $args
21 | ];
22 |
23 | return $args;
24 | }
25 |
26 | function after_http_request( $response, $type, $class, $args, $url ) {
27 | if ( $type !== 'response' ) {
28 | return;
29 | }
30 |
31 | $args['time_stop'] = microtime( true );
32 |
33 | $args['duration'] = $args['time_stop'] - $args['time_start'];
34 | $args['duration'] *= 1000;
35 |
36 | $this->total_time += $args['duration'];
37 |
38 | if ( $this->is_request_error( $response ) ) {
39 | $this->num_errors++;
40 | } else {
41 | if ( ! isset( $_GET['fullbody'] ) ) {
42 | $response['body'] = '[omitted]';
43 | unset( $response['http_response'] );
44 | }
45 | }
46 |
47 | $this->requests["{$args['time_start']}"] = array_merge(
48 | $this->requests["{$args['time_start']}"],
49 | [
50 | 'r' => $response,
51 | 'class' => $class,
52 | 'args' => $args,
53 | 'url' => $url,
54 | 'stack_trace' => wp_debug_backtrace_summary( null, 0, false ),
55 | ]
56 | );
57 | }
58 |
59 | function is_request_error( $response ) {
60 | if (
61 | empty( $response )
62 | || is_wp_error( $response )
63 | || $response['response']['code'] >= 400
64 | ) {
65 | return true;
66 | }
67 |
68 | return false;
69 | }
70 |
71 | function init() {
72 | $this->title( 'WP_Http' );
73 | }
74 |
75 | function prerender() {
76 | $this->set_visible( ! empty( $this->requests ) );
77 | }
78 |
79 | function debug_bar_classes( $classes ) {
80 | if (
81 | $this->num_errors > 0
82 | || $this->total_time > $this->time_limit
83 | ) {
84 | $classes[] = 'debug-bar-php-warning-summary';
85 | }
86 | return $classes;
87 | }
88 |
89 | function render() {
90 | $num_requests = number_format_i18n( count( $this->requests ) );
91 | $elapsed = number_format_i18n( $this->total_time, 1 );
92 | $num_errors = number_format_i18n( $this->num_errors );
93 |
94 | if ( isset( $_GET['fullbody'] ) ) {
95 | $fullbody = '' . esc_html__( 'Request and response bodies are included.', 'debug-bar' ) . ' ' . esc_html__( 'Reload with those omitted.', 'debug-bar' ) . '
';
96 | } else {
97 | $fullbody = '' . esc_html__( 'Request and response bodies are omitted.', 'debug-bar' ) . ' ' . esc_html__( 'Reload with those included.', 'debug-bar' ) . '
';
98 | }
99 |
100 | $elapsed_class = '';
101 | if ( $this->total_time > $this->time_limit ) {
102 | $elapsed_class = 'debug_bar_http_error';
103 | }
104 |
105 | $errors_class = '';
106 | if ( $this->num_errors > 0 ) {
107 | $errors_class = 'debug_bar_http_error';
108 | }
109 |
110 | ?>
111 |
117 |
118 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 |
145 |
146 |
147 | requests as $i => $r ) {
150 | $class = '';
151 | if (
152 | ( ! empty( $r['r'] ) && $this->is_request_error( $r['r'] ) )
153 | || ( ! empty( $r['args']['duration'] ) && $r['args']['duration'] > $this->time_limit )
154 | ) {
155 | $class = 'err';
156 | }
157 |
158 | $start = $r['args']['time_start'] - $_SERVER['REQUEST_TIME_FLOAT'];
159 | $start = number_format_i18n( $start * 1000, 1 );
160 |
161 | $duration = 'error getting request duration';
162 | if ( ! empty( $r['args']['duration'] ) ) {
163 | $duration = sprintf(
164 | /* translators: %s = duration in milliseconds. */
165 | __( '%s ms', 'debug-bar' ),
166 | number_format_i18n( $r['args']['duration'], 1 )
167 | );
168 | }
169 | $method = $r['args']['method'];
170 | $url = $r['url'];
171 |
172 | if ( ! empty( $r['r'] ) && is_wp_error( $r['r'] ) ) {
173 | $code = esc_html( $r['r']->get_error_code() );
174 | } else {
175 | $code = 'error getting response code, most likely a stopped request';
176 | if ( ! empty( $r['r']['response']['code'] ) ) {
177 | $code = $r['r']['response']['code'];
178 | }
179 | }
180 |
181 | $details = esc_html( print_r( $r, true ) );
182 |
183 | $record_id = 'debug_bar_http_record_' . md5( $i );
184 |
185 | ?>
186 |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 |
194 |
195 |
196 | |
197 |
198 |
203 |
204 |
205 | 250ms )
59 |
60 | = 1.1 =
61 | Add a new panel for HTTP requests using the native WP methods.
62 | AMP dev mode compatibility.
63 | Change cache busters to use `filemtime` instead of hardcoded values.
64 | Minor CSS updates, so themes don't override the `pre` styles.
65 |
66 | = 1.0.1 =
67 | Update object cache panel CSS to be ready for new object-cache.php release with better stats()
68 |
69 | = 1.0 =
70 | Improved compatibility with the WordPress.com toolbar in Jetpack
71 |
72 | = 0.9 =
73 | Added panel navigation to toolbar.
74 | Improved localization support.
75 | Security fixes.
76 |
77 | = 0.8.4 =
78 | Updated to avoid incompatibilities with some extensions.
79 |
80 | = 0.8.3 =
81 | Updated to avoid PHP7 Deprecated notices.
82 |
83 | = 0.8.2 =
84 | Updated to handle a new deprecated message in WordPress 4.0.
85 |
86 | = 0.8.1 =
87 | Minor security fix.
88 |
89 | = 0.8 =
90 | WordPress 3.3 compatibility
91 | UI refresh
92 | Removed jQuery UI requirement
93 | Full screen by default
94 | New debug-bar query parameter to show on page load
95 | Removed display cookies
96 | JavaScript error tracking (disabled by default)
97 |
98 | = 0.7 =
99 | Made compatible with PHP < 5.2.0
100 | CSS Tweaks
101 | Load JavaScript in Footer
102 | Fixed display issues for WP_Query debug on CPT archives pages
103 | SQL/DB error tracking
104 |
105 | = 0.6 =
106 | Added maximize/restore button
107 | Added cookie to keep track of debug bar state
108 | Added post type information to WP_Query tab
109 | Bug fix where bottom of page was obscured in the admin
110 |
111 | = 0.5 =
112 | New UI
113 | Backend rewritten with a class for each panel
114 | Many miscellaneous improvements
115 |
116 | = 0.4.1 =
117 | Compatibility updates for trunk
118 |
119 | = 0.4 =
120 | Added DB Version information
121 | Updated PHP Warning and Notice tracking so that multiple different errors on the same line are tracked
122 | Compatibility updates for trunk
123 |
124 | = 0.3 =
125 | Added WordPress Query infomation
126 | Added Request parsing information
127 |
128 | = 0.2 =
129 | Added PHP Notice / Warning tracking when WP_DEBUG enabled
130 | Added deprecated function usage tracking
131 |
132 | = 0.1 =
133 | Initial Release
134 |
135 | == Changelog ==
136 |
137 | = 1.1.7 =
138 | - Resolves a PHP Warning in WP 6.7+.
139 |
140 | = 1.1.6 =
141 | - 1.1.5 didn't have the minified CSS rebuilt.
142 |
143 | = 1.1.5 =
144 | - Update CSS to remove gradient and shadow styles
145 | - Use dashicons as action buttons instead of misaligned text.
146 |
147 | = 1.1.4 =
148 | - Fix PHP8+ critical error if `php_uname` is disabled
149 |
150 | = 1.1.3 =
151 | - Fix notices in HTTP Requests panel when a request is stopped/doesn't finish.
152 | - Decode the SQL in the WP_Query panel.
153 |
154 | = 1.1.2 =
155 | Fix error checking in HTTP Requests panel.
156 |
157 | = 1.1.1 =
158 | Refactor the HTTP Requests panel:
159 | - Remove jQuery usage
160 | - Properly display response codes
161 | - Better CSS to emphasize errors and long requests ( > 250ms )
162 |
163 | = 1.1 =
164 | Add a new panel for HTTP requests using the native WP methods.
165 | AMP dev mode compatibility.
166 | Change cache busters to use `filemtime` instead of hardcoded values.
167 | Minor CSS updates, so themes don't override the `pre` styles.
168 |
169 | = 1.0.1 =
170 | Update object cache panel CSS to be ready for new object-cache.php release with better stats()
171 |
172 | = 1.0 =
173 | Improved compatibility with the WordPress.com toolbar in Jetpack
174 |
175 | = 0.9 =
176 | Added panel navigation to toolbar.
177 | Improved localization support.
178 | Security fixes.
179 |
180 | = 0.8.4 =
181 | Updated to avoid incompatibilities with some extensions.
182 |
183 | = 0.8.3 =
184 | Updated to avoid PHP7 Deprecated notices.
185 |
186 | = 0.8.2 =
187 | Updated to handle a new deprecated message in WordPress 4.0.
188 |
189 | = 0.8.1 =
190 | Minor security fix.
191 |
192 | = 0.8 =
193 | WordPress 3.3 compatibility
194 | UI refresh
195 | Removed jQuery UI requirement
196 | Full screen by default
197 | New debug-bar query parameter to show on page load
198 | Removed display cookies
199 | JavaScript error tracking (disabled by default)
200 |
201 | = 0.7 =
202 | Made compatible with PHP < 5.2.0
203 | CSS Tweaks
204 | Load JavaScript in Footer
205 | Fixed display issues for WP_Query debug on CPT archives pages
206 | SQL/DB error tracking
207 |
208 | = 0.6 =
209 | Added maximize/restore button
210 | Added cookie to keep track of debug bar state
211 | Added post type information to WP_Query tab
212 | Bug fix where bottom of page was obscured in the admin
213 |
214 | = 0.5 =
215 | New UI
216 | Backend rewritten with a class for each panel
217 | Many miscellaneous improvements
218 |
219 | = 0.4.1 =
220 | Compatibility updates for trunk
221 |
222 | = 0.4 =
223 | Added DB Version information
224 | Updated PHP Warning and Notice tracking so that multiple different errors on the same line are tracked
225 | Compatibility updates for trunk
226 |
227 | = 0.3 =
228 | Added WordPress Query infomation
229 | Added Request parsing information
230 |
231 | = 0.2 =
232 | Added PHP Notice / Warning tracking when WP_DEBUG enabled
233 | Added deprecated function usage tracking
234 |
235 | = 0.1 =
236 | Initial Release
237 |
238 | == Installation ==
239 |
240 | Use automatic installer.
241 |
--------------------------------------------------------------------------------
/css/debug-bar.dev.css:
--------------------------------------------------------------------------------
1 | /* =========================================================================
2 | * Admin bar styling
3 | * ========================================================================= */
4 |
5 | #wpadminbar #wp-admin-bar-debug-bar {
6 | float: right;
7 | }
8 |
9 | #wpadminbar #wp-admin-bar-debug-bar.active {
10 | background: #555;
11 | }
12 |
13 | #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-notice-summary,
14 | #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-notice-summary .ab-item:focus {
15 | background-color: #ff8922;
16 | }
17 |
18 | #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-notice-summary .ab-item:hover,
19 | .debug-bar-visible #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-notice-summary,
20 | .debug-bar-visible #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-notice-summary .ab-item:focus {
21 | background-color: #ee6f00;
22 | }
23 | #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-notice-summary .ab-item {
24 | color: #f0f0f1;
25 | }
26 |
27 | #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-warning-summary,
28 | #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-warning-summary .ab-item:focus,
29 | #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-warning-summary .ab-item:hover,
30 | .debug-bar-visible #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-warning-summary,
31 | .debug-bar-visible #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-warning-summary .ab-item:focus {
32 | background-color: #d00;
33 | }
34 | #wpadminbar #wp-admin-bar-debug-bar.debug-bar-php-warning-summary .ab-item {
35 | color: #f0f0f1;
36 | }
37 |
38 | #wpadminbar #wp-admin-bar-debug-bar ul {
39 | right: 0;
40 | }
41 |
42 | /**
43 | * Debug bar styling
44 | */
45 |
46 | #querylist {
47 | direction: ltr;
48 | display: none;
49 | position: fixed;
50 | height: 33%;
51 | min-height: 350px;
52 | font-family: "Helvetica Neue", sans-serif;
53 | left: 0;
54 | right: 0;
55 | bottom: 0;
56 | background: #f1f1f1;
57 | z-index: 99000;
58 | color: #000;
59 | line-height: 150% !important;
60 | text-align: left;
61 | font-size: 12px;
62 | }
63 |
64 | /* reset debug bar links */
65 | #querylist a {
66 | border: 0;
67 | }
68 |
69 | .debug-bar-visible #querylist {
70 | display: block;
71 | }
72 |
73 | .debug-bar-maximized #querylist {
74 | position: fixed;
75 | top: 28px;
76 | height: auto;
77 | }
78 |
79 | body.debug-bar-maximized.debug-bar-visible {
80 | overflow: hidden;
81 | }
82 |
83 | #debug-bar-info {
84 | height: 60px;
85 | width: 100%;
86 | position: absolute;
87 | z-index: 200;
88 |
89 | background: #f1f1f1;
90 | border-bottom: 1px solid #fff;
91 | }
92 |
93 | #debug-bar-menu {
94 | position: absolute;
95 | top: 61px;
96 | left: 0;
97 | width: 250px;
98 | bottom: 0;
99 | z-index: 100;
100 |
101 | overflow: auto;
102 | background: #333;
103 | }
104 |
105 | #debug-menu-targets {
106 | overflow: auto;
107 | position: absolute;
108 | top: 61px;
109 | left: 250px;
110 | right: 0;
111 | bottom: 0;
112 | z-index: 150;
113 | }
114 |
115 | #debug-status {
116 | float: left;
117 | padding-left: 20px;
118 | color: #bbb;
119 | font-size: 14px;
120 | line-height: 60px;
121 | }
122 |
123 | .debug-status {
124 | float: left;
125 | margin-right: 40px;
126 | }
127 |
128 | #debug-status .debug-status-title {
129 | color: #555;
130 | font-weight: 500;
131 | line-height: 18px;
132 | font-size: 12px;
133 | margin-top: 10px;
134 | }
135 | #debug-status .debug-status-data {
136 | color: #999;
137 | font-weight: 200;
138 | line-height: 20px;
139 | font-size: 18px;
140 | }
141 | #debug-status #debug-status-warning {
142 | font-weight: bold;
143 | color: #d00;
144 | }
145 | #debug-status #debug-status-site {
146 | font-weight: bold;
147 | }
148 |
149 | #querylist pre {
150 | text-align: left;
151 | font-size: 12px;
152 | padding: 10px;
153 | }
154 |
155 | #querylist .left {
156 | float: left;
157 | }
158 |
159 | #querylist .right {
160 | float: right;
161 | }
162 |
163 | #querylist h1, #querylist h2, #querylist h3 {
164 | font-weight: normal;
165 | }
166 |
167 | #debug-menu-links {
168 | overflow: hidden;
169 | list-style: none;
170 | margin: 0;
171 | padding: 0;
172 | }
173 |
174 | #debug-menu-links li {
175 | float: left;
176 | margin-bottom: 0 !important;
177 | }
178 |
179 | #debug-menu-links li a {
180 | box-sizing: content-box;
181 | padding: 0 20px;
182 | width: 210px;
183 | line-height: 32px;
184 | outline: none;
185 | display: block;
186 | margin: 0;
187 | color: #fff !important;
188 | text-decoration: none !important;
189 | font-weight: 500 !important;
190 | font-size: 14px;
191 | }
192 |
193 | #debug-menu-links li a.current {
194 | background: rgba( 0, 0, 0, 0.2 );
195 | }
196 |
197 | #querylist h2 {
198 | float: left;
199 | min-width: 150px;
200 | border: 1px solid #eee;
201 | padding: 5px 10px 15px;
202 | clear: none;
203 | text-align: center;
204 | color: #000;
205 | font-family: georgia, times, serif;
206 | font-size: 28px;
207 | margin: 15px 10px 15px 0 !important;
208 | }
209 |
210 | #querylist h2 span {
211 | font-size: 12px;
212 | color: #888;
213 | text-transform: uppercase;
214 | white-space: nowrap;
215 | display: block;
216 | margin-bottom: 5px;
217 | }
218 |
219 | #querylist h2 span#debug-bar-js-error-count {
220 | font-size: inherit;
221 | color: inherit;
222 | text-transform: inherit;
223 | white-space: inherit;
224 | display: inherit;
225 | margin-bottom: inherit;
226 | }
227 |
228 | /* =========================================================================
229 | * Object cache styling
230 | * ========================================================================= */
231 | #object-cache-stats h2 {
232 | border: none;
233 | float: left;
234 | text-align: left;
235 | font-size: 22px;
236 | margin-bottom: 0;
237 | }
238 |
239 |
240 | #object-cache-stats ul.debug-menu-links,
241 | #object-cache-stats-menu-targets {
242 | clear: both;
243 | }
244 |
245 | .object-cache-stats-menu-target pre {
246 | white-space: pre-wrap;
247 | margin: 1rem 0;
248 | }
249 |
250 | #object-cache-stats ul.debug-menu-links li {
251 | float: left;
252 | margin: 0 10px 10px 0;
253 | background: none;
254 | border: 1px solid #eee;
255 | color: #4b5259;
256 | list-style: none;
257 | }
258 |
259 | #object-cache-stats ul.debug-menu-links li:hover {
260 | border-color: #ddd;
261 | }
262 |
263 | #object-cache-stats ul.debug-menu-links li a {
264 | background: none;
265 | color: #4b5259;
266 | overflow: hidden;
267 | display: block;
268 | padding: 5px 9px;
269 | text-decoration: none;
270 | }
271 |
272 | #querylist h3 {
273 | margin-bottom: 15px;
274 | }
275 |
276 | #querylist ol.wpd-queries {
277 | padding: 0 !important;
278 | margin: 0 !important;
279 | list-style: none;
280 | clear: left;
281 | }
282 |
283 | #querylist ol.wpd-queries li {
284 | padding: 10px;
285 | background: #f0f0f0;
286 | margin: 0 0 10px 0;
287 | }
288 |
289 | #querylist ol.wpd-queries li div.qdebug {
290 | background: #e8e8e8;
291 | margin: 10px -10px -10px -10px;
292 | padding: 5px 150px 5px 5px;
293 | font-size: 11px;
294 | position: relative;
295 | min-height: 20px;
296 | }
297 |
298 | #querylist ol.wpd-queries li div.qdebug span {
299 | position: absolute;
300 | right: 10px;
301 | top: 5px;
302 | white-space: nowrap;
303 | }
304 |
305 | #querylist a {
306 | text-decoration: underline !important;
307 | color: blue !important;
308 | cursor: pointer;
309 | }
310 |
311 | #querylist a:hover {
312 | text-decoration: none !important;
313 | }
314 |
315 | #querylist .debug-menu-target {
316 | margin: 20px;
317 | display: none;
318 | }
319 |
320 | #querylist ol {
321 | font: 12px Monaco, "Courier New", Courier, Fixed !important;
322 | line-height: 180% !important;
323 | }
324 |
325 | #querylist table {
326 | table-layout: auto;
327 | }
328 |
329 | #querylist td, #querylist th {
330 | text-transform: none;
331 | }
332 |
333 | #querylist table,
334 | #querylist table th,
335 | #querylist table td {
336 | border: 0px none;
337 | vertical-align: top;
338 | }
339 |
340 | #debug-bar-php ol.debug-bar-php-list {
341 | padding: 0 !important;
342 | margin: 0 !important;
343 | list-style: none;
344 | clear: left;
345 | }
346 |
347 | #debug-bar-php ol.debug-bar-php-list li {
348 | padding: 10px;
349 | margin: 0 0 10px 0;
350 | }
351 |
352 | #debug-bar-php .debug-bar-php-warning {
353 | background-color: #ffebe8;
354 | border: 1px solid #d00;
355 | }
356 |
357 | #debug-bar-php .debug-bar-php-notice {
358 | background-color: #ffffe0;
359 | border: 1px solid #e6db55;
360 | }
361 |
362 | #debug-bar-deprecated ol.debug-bar-deprecated-list {
363 | padding: 0 !important;
364 | margin: 0 !important;
365 | list-style: none;
366 | clear: left;
367 | }
368 |
369 | #debug-bar-deprecated ol.debug-bar-deprecated-list li {
370 | padding: 10px;
371 | margin: 0 0 10px 0;
372 | background: #f0f0f0;
373 | }
374 |
375 | #debug-bar-wp-query table.debug-bar-wp-query-list {
376 | width: 100%;
377 | border-collapse: collapse;
378 | cell-padding: 1em;
379 | clear: both;
380 | }
381 |
382 | #debug-bar-wp-query table.debug-bar-wp-query-list td {
383 | padding: 0.5em 5px;
384 | border-bottom: 1px solid #ccc;
385 | }
386 |
387 | #debug-bar-wp-query table.debug-bar-wp-query-list th {
388 | padding: 0.5em 5px;
389 | font-weight: bold;
390 | border-bottom: 1px solid #ccc;
391 | }
392 |
393 | #debug-bar-wp-query table.debug-bar-wp-query-list tr:nth-child(2n+1) {
394 | background-color: #E8E8E8;
395 | }
396 |
397 | #debug-bar-wp-query table.debug-bar-wp-query-list tr td:first-of-type {
398 | font-size: 140%;
399 | padding: 0.3em 0.5em;
400 | }
401 |
402 | #debug-bar-wp-query h3, #debug-bar-request h3 {
403 | float: none;
404 | clear: both;
405 | font-family: georgia, times, serif;
406 | font-size: 22px;
407 | margin: 15px 10px 15px 0 !important;
408 | }
409 |
410 | #debug-bar-request p {
411 | padding: 10px;
412 | margin: 0 0 10px 0;
413 | background: #f0f0f0;
414 | }
415 |
416 | /* =========================================================================
417 | * Actions: Maximize / restore
418 | * ========================================================================= */
419 |
420 | #debug-bar-actions {
421 | position: absolute;
422 | top: 21px;
423 | right: 20px;
424 | z-index: 300;
425 | }
426 | #debug-bar-actions span {
427 | -moz-border-radius: 20px;
428 | -webkit-border-radius: 20px;
429 | border-radius: 20px;
430 | display: block;
431 | float: left;
432 | height: 20px;
433 | width: 20px;
434 | line-height: 20px;
435 | margin-left: 5px;
436 | font-size: 18px;
437 | text-align: center;
438 | font-weight: bold;
439 | color: #eee;
440 | background: #aaa;
441 | cursor: pointer;
442 | }
443 | #debug-bar-actions span.maximize,
444 | #debug-bar-actions span.restore {
445 | background-color: #9d9;
446 | }
447 | #debug-bar-actions span.close {
448 | background-color: #d99;
449 | }
450 | #debug-bar-actions span:hover {
451 | background: #888;
452 | }
453 | #debug-bar-actions span.maximize:hover,
454 | #debug-bar-actions span.restore:hover {
455 | background: #40bf40;
456 | }
457 | #debug-bar-actions span.close:hover {
458 | background: #bf4040;
459 | }
460 |
461 |
462 | .debug-bar-maximized #debug-bar-actions span.restore {
463 | display: block;
464 | }
465 | .debug-bar-maximized #debug-bar-actions span.maximize {
466 | display: none;
467 | }
468 |
469 | .debug-bar-partial #debug-bar-actions span.restore {
470 | display: none;
471 | }
472 | .debug-bar-partial #debug-bar-actions span.maximize {
473 | display: block;
474 | }
475 |
476 | /* =========================================================================
477 | * JS Error item styling
478 | * ========================================================================= */
479 |
480 | #debug-menu-links li a#debug-menu-link-Debug_Bar_JS,
481 | #wp-admin-bar-debug-bar-Debug_Bar_JS {
482 | display: none;
483 | }
484 |
485 | #debug-bar-js ol.debug-bar-js-list {
486 | padding: 0 !important;
487 | margin: 0 !important;
488 | list-style: none;
489 | clear: left;
490 | }
491 |
492 | #debug-bar-js ol.debug-bar-js-list li {
493 | padding: 10px;
494 | margin: 0 0 10px 0;
495 | }
496 |
497 | #debug-bar-js .debug-bar-js-error {
498 | background-color: #ffebe8;
499 | border: 1px solid #d00;
500 | }
501 |
502 | #debug-bar-js .debug-bar-js-error span {
503 | color: #666;
504 | font-size: 0.8em;
505 | display: block;
506 | }
507 |
508 | #debug-bar-js .debug-bar-js-error:hover span {
509 | color: #000;
510 | }
511 |
--------------------------------------------------------------------------------
/debug-bar.php:
--------------------------------------------------------------------------------
1 | panels[] = $panel;
49 | $panel->early_init();
50 | }
51 |
52 | function init() {
53 | if ( ! $this->enable_debug_bar() ) {
54 | return;
55 | }
56 |
57 | load_plugin_textdomain( 'debug-bar' );
58 |
59 | add_action( 'wp_before_admin_bar_render', array( $this, 'wp_before_admin_bar_render' ), 1000000 );
60 | add_action( 'admin_footer', array( $this, 'render' ), 1000 );
61 | add_action( 'wp_footer', array( $this, 'render' ), 1000 );
62 | add_action( 'wp_head', array( $this, 'ensure_ajaxurl' ), 1 );
63 | add_filter( 'body_class', array( $this, 'body_class' ) );
64 | add_filter( 'admin_body_class', array( $this, 'body_class' ) );
65 |
66 | $this->requirements();
67 | $this->enqueue();
68 | $this->init_panels();
69 | }
70 |
71 | /**
72 | * Are we on the wp-login.php page?
73 | *
74 | * We can get here while logged in and break the page as the admin bar
75 | * is not shown and other things the js relies on are not available.
76 | *
77 | * @return bool
78 | */
79 | function is_wp_login() {
80 | return 'wp-login.php' == basename( $_SERVER['SCRIPT_NAME'] );
81 | }
82 |
83 | /**
84 | * Should the debug bar functionality be enabled?
85 | *
86 | * @since 0.9
87 | *
88 | * @param bool $ajax Whether this is an ajax call or not. Defaults to false.
89 | * @return bool
90 | */
91 | function enable_debug_bar( $ajax = false ) {
92 | $enable = false;
93 |
94 | if ( $ajax && is_super_admin() ) {
95 | $enable = true;
96 | } elseif ( ! $ajax && ( is_super_admin() && is_admin_bar_showing() && ! $this->is_wp_login() ) ) {
97 | $enable = true;
98 | }
99 |
100 | /**
101 | * Allows for overruling of whether the debug bar functionality will be enabled.
102 | *
103 | * @since 0.9
104 | *
105 | * @param bool $enable Whether the debug bar will be enabled or not.
106 | */
107 | return apply_filters( 'debug_bar_enable', $enable );
108 | }
109 |
110 | function init_ajax() {
111 | if ( ! $this->enable_debug_bar( true ) ) {
112 | return;
113 | }
114 |
115 | $this->requirements();
116 | $this->init_panels();
117 | }
118 |
119 | function requirements() {
120 | $path = plugin_dir_path( __FILE__ );
121 | $recs = array( 'panel', 'php', 'queries', 'request', 'wp-query', 'object-cache', 'deprecated', 'js' );
122 |
123 | foreach ( $recs as $rec ) {
124 | require_once "$path/panels/class-debug-bar-$rec.php";
125 | }
126 | }
127 |
128 | function enqueue() {
129 | $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '.dev' : '';
130 |
131 | $style_dependencies = array( 'dashicons' );
132 | $script_dependencies = array( 'jquery' );
133 | if ( $this->is_amp() ) {
134 | // Add admin-bar dependencies so AMP dev mode will stop removing debug-bar assets
135 | // https://weston.ruter.net/2019/09/24/integrating-with-amp-dev-mode-in-wordpress/
136 | $style_dependencies[] = 'admin-bar';
137 | $script_dependencies[] = 'admin-bar';
138 | }
139 |
140 | $css_filename = "css/debug-bar$suffix.css";
141 | wp_enqueue_style(
142 | 'debug-bar',
143 | plugins_url( $css_filename, __FILE__ ),
144 | $style_dependencies,
145 | filemtime( __DIR__ . '/' . $css_filename )
146 | );
147 |
148 | $js_filename = "js/debug-bar$suffix.js";
149 | wp_enqueue_script(
150 | 'debug-bar',
151 | plugins_url( $js_filename, __FILE__ ),
152 | $script_dependencies,
153 | filemtime( __DIR__ . '/' . $js_filename ),
154 | true
155 | );
156 |
157 | do_action( 'debug_bar_enqueue_scripts' );
158 | }
159 |
160 | function init_panels() {
161 | $classes = array(
162 | 'Debug_Bar_PHP',
163 | 'Debug_Bar_Queries',
164 | 'Debug_Bar_WP_Query',
165 | 'Debug_Bar_Deprecated',
166 | 'Debug_Bar_Request',
167 | 'Debug_Bar_Object_Cache',
168 | 'Debug_Bar_JS',
169 | );
170 |
171 | foreach ( $classes as $class ) {
172 | $this->panels[] = new $class;
173 | }
174 |
175 | $this->panels = apply_filters( 'debug_bar_panels', $this->panels );
176 | }
177 |
178 | function ensure_ajaxurl() { ?>
179 |
184 | = 5.2.0 only
188 | function safe_memory_get_peak_usage() {
189 | return function_exists( 'memory_get_peak_usage' ) ? memory_get_peak_usage() : memory_get_usage();
190 | }
191 |
192 | function wp_before_admin_bar_render() {
193 | global $wp_admin_bar;
194 |
195 | $classes = apply_filters( 'debug_bar_classes', array() );
196 | $classes = implode( " ", $classes );
197 |
198 | /* Add the main siteadmin menu item */
199 | $wp_admin_bar->add_menu( array(
200 | 'id' => 'debug-bar',
201 | 'parent' => 'top-secondary',
202 | 'title' => apply_filters( 'debug_bar_title', __( 'Debug', 'debug-bar' ) ),
203 | 'meta' => array( 'class' => $classes ),
204 | ) );
205 |
206 | foreach ( $this->panels as $panel_key => $panel ) {
207 | $panel->prerender();
208 | if ( ! $panel->is_visible() ) {
209 | continue;
210 | }
211 |
212 | $panel_class = get_class( $panel );
213 |
214 | $wp_admin_bar->add_menu( array(
215 | 'parent' => 'debug-bar',
216 | 'id' => "debug-bar-$panel_class",
217 | 'title' => $panel->title(),
218 | 'href' => '#debug-menu-target-' . esc_attr( $panel_class ),
219 | 'meta' => array(
220 | 'rel' => '#debug-menu-link-' . esc_attr( $panel_class ),
221 | ),
222 | ) );
223 | }
224 | }
225 |
226 | function body_class( $classes ) {
227 | if ( is_array( $classes ) ) {
228 | $classes[] = 'debug-bar-maximized';
229 | } else {
230 | $classes .= ' debug-bar-maximized ';
231 | }
232 |
233 | if ( isset( $_GET['debug-bar'] ) ) {
234 | if ( is_array( $classes ) ) {
235 | $classes[] = 'debug-bar-visible';
236 | } else {
237 | $classes .= ' debug-bar-visible ';
238 | }
239 | }
240 |
241 | return $classes;
242 | }
243 |
244 | /*
245 | * AMP Compatibility
246 | * Based primarily on approach described in https://weston.ruter.net/2019/09/24/integrating-with-amp-dev-mode-in-wordpress/
247 | */
248 | function is_amp() {
249 | return function_exists( 'is_amp_endpoint' ) && is_amp_endpoint();
250 | }
251 |
252 | function amp_dev_mode_element_xpaths( $xpaths ) {
253 | // Add data-ampdevmode to jQuery script tag so it will be left intact
254 | $xpaths[] = '//script[ contains( @src, "wp-includes/js/jquery/jquery.js" ) ]';
255 |
256 | // Add data-ampdevmode to object cache scripts used by the debug bar
257 | $xpaths[] = '//*[@id = "object-cache-stats"]//script';
258 |
259 | // Add data-ampdevmode to debug-menu-links because AMP is removing inline onclick handlers
260 | $xpaths[] = '//*[@class = "debug-menu-links"]//a';
261 |
262 | return $xpaths;
263 | }
264 |
265 | function render() {
266 | global $wpdb;
267 |
268 | if ( empty( $this->panels ) ) {
269 | return;
270 | }
271 |
272 | foreach ( $this->panels as $panel_key => $panel ) {
273 | $panel->prerender();
274 | if ( ! $panel->is_visible() ) {
275 | unset( $this->panels[ $panel_key ] );
276 | }
277 | }
278 |
279 | ?>
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 | is_mysql ) ? __( 'DB', 'debug-bar' ) : __( 'MySQL', 'debug-bar' );
311 | $statuses[] = array(
312 | 'db',
313 | $db_title,
314 | $wpdb->db_version(),
315 | );
316 | $statuses[] = array(
317 | 'memory',
318 | __( 'Memory Usage', 'debug-bar' ),
319 | /* translators: %s is a formatted number representing the memory usage. */
320 | sprintf( __( '%s bytes', 'debug-bar' ), number_format_i18n( $this->safe_memory_get_peak_usage() ) ),
321 | );
322 |
323 | if ( ! WP_DEBUG ) {
324 | $statuses[] = array(
325 | 'warning',
326 | __( 'Please Enable', 'debug-bar' ),
327 | 'WP_DEBUG',
328 | );
329 | }
330 |
331 | $statuses = apply_filters( 'debug_bar_statuses', $statuses );
332 |
333 | foreach ( $statuses as $status ):
334 | list( $slug, $title, $data ) = $status;
335 |
336 | ?>
337 |
338 |
339 |
340 |
341 |
342 |
345 |
346 |
347 |
348 |
371 |
372 |
386 |
387 |
388 |
389 | early_init();
395 |
--------------------------------------------------------------------------------