Version Description
Download this release
Release Info
Developer | johnbillion |
Plugin | Query Monitor |
Version | 2.16.1 |
Comparing to | |
See all releases |
Code changes from version 2.15.0 to 2.16.1
- assets/query-monitor.css +23 -13
- assets/query-monitor.js +19 -0
- classes/Backtrace.php +9 -1
- classes/Collector.php +14 -0
- classes/Util.php +40 -1
- collectors/caps.php +170 -0
- collectors/hooks.php +1 -2
- output/Html.php +4 -0
- output/html/caps.php +195 -0
- output/html/db_queries.php +31 -6
- output/html/environment.php +2 -2
- output/html/hooks.php +4 -0
- output/html/http.php +21 -6
- output/html/transients.php +15 -6
- query-monitor.php +1 -1
- readme.txt +6 -2
- wp-content/db.php +11 -1
assets/query-monitor.css
CHANGED
@@ -623,6 +623,8 @@ select.qm-filter {
|
|
623 |
}
|
624 |
|
625 |
.qm-hide,
|
|
|
|
|
626 |
.qm-hide-name,
|
627 |
.qm-hide-type,
|
628 |
.qm-hide-caller,
|
@@ -647,43 +649,51 @@ select.qm-filter {
|
|
647 |
.qm .qm-sort {
|
648 |
color: #767676 !important;
|
649 |
display: block !important;
|
650 |
-
font-style: normal !important;
|
651 |
-
font-weight: normal !important;
|
652 |
-
font-size: 15px !important;
|
653 |
-
line-height: 11px !important;
|
654 |
-
font-family: Menlo, Monaco, Consolas, monospace !important;
|
655 |
border: 0 !important;
|
656 |
padding: 0 !important;
|
657 |
width: 30px !important;
|
658 |
background-color: transparent !important;
|
659 |
cursor: pointer !important;
|
660 |
margin: 0 auto !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
661 |
}
|
662 |
|
663 |
.qm .qm-sort-asc {
|
664 |
-
margin-bottom:
|
665 |
}
|
666 |
.qm .qm-sort-asc:before {
|
667 |
-
|
|
|
668 |
}
|
669 |
.qm .qm-sort-asc:hover:before,
|
670 |
.qm .qm-sort-asc:focus:before,
|
671 |
.qm .qm-sorted-asc .qm-sort-asc:before {
|
672 |
-
color: #333 !important;
|
673 |
-
content: "\25b2" !important;
|
674 |
}
|
675 |
|
676 |
.qm .qm-sort-desc {
|
677 |
-
margin-top:
|
678 |
}
|
679 |
.qm .qm-sort-desc:before {
|
680 |
-
|
|
|
681 |
}
|
682 |
.qm .qm-sort-desc:hover:before,
|
683 |
.qm .qm-sort-desc:focus:before,
|
684 |
.qm .qm-sorted-desc .qm-sort-desc:before {
|
685 |
-
color: #333 !important;
|
686 |
-
content: "\25bc" !important;
|
687 |
}
|
688 |
|
689 |
.qm .screen-reader-text {
|
623 |
}
|
624 |
|
625 |
.qm-hide,
|
626 |
+
.qm-hide-user,
|
627 |
+
.qm-hide-result,
|
628 |
.qm-hide-name,
|
629 |
.qm-hide-type,
|
630 |
.qm-hide-caller,
|
649 |
.qm .qm-sort {
|
650 |
color: #767676 !important;
|
651 |
display: block !important;
|
|
|
|
|
|
|
|
|
|
|
652 |
border: 0 !important;
|
653 |
padding: 0 !important;
|
654 |
width: 30px !important;
|
655 |
background-color: transparent !important;
|
656 |
cursor: pointer !important;
|
657 |
margin: 0 auto !important;
|
658 |
+
height: 10px !important;
|
659 |
+
}
|
660 |
+
|
661 |
+
.qm .qm-sort:before {
|
662 |
+
border-width: 7px 5px !important;
|
663 |
+
border-style: solid !important;
|
664 |
+
border-color: transparent !important;
|
665 |
+
display: block !important;
|
666 |
+
content: '' !important;
|
667 |
+
width: 0 !important;
|
668 |
+
height: 0 !important;
|
669 |
+
position: relative !important;
|
670 |
+
left: 10px !important;
|
671 |
}
|
672 |
|
673 |
.qm .qm-sort-asc {
|
674 |
+
margin-bottom: 2px !important;
|
675 |
}
|
676 |
.qm .qm-sort-asc:before {
|
677 |
+
border-bottom-color: #aaa !important;
|
678 |
+
top: -4px !important;
|
679 |
}
|
680 |
.qm .qm-sort-asc:hover:before,
|
681 |
.qm .qm-sort-asc:focus:before,
|
682 |
.qm .qm-sorted-asc .qm-sort-asc:before {
|
683 |
+
border-bottom-color: #333 !important;
|
|
|
684 |
}
|
685 |
|
686 |
.qm .qm-sort-desc {
|
687 |
+
margin-top: 2px !important;
|
688 |
}
|
689 |
.qm .qm-sort-desc:before {
|
690 |
+
border-top-color: #aaa !important;
|
691 |
+
top: 0px !important;
|
692 |
}
|
693 |
.qm .qm-sort-desc:hover:before,
|
694 |
.qm .qm-sort-desc:focus:before,
|
695 |
.qm .qm-sorted-desc .qm-sort-desc:before {
|
696 |
+
border-top-color: #333 !important;
|
|
|
697 |
}
|
698 |
|
699 |
.qm .screen-reader-text {
|
assets/query-monitor.js
CHANGED
@@ -159,6 +159,15 @@ jQuery( function($) {
|
|
159 |
hilite = $(this).attr('data-highlight'),
|
160 |
time = 0;
|
161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
if ( hilite ) {
|
163 |
table.find('tr').removeClass('qm-highlight');
|
164 |
}
|
@@ -187,6 +196,16 @@ jQuery( function($) {
|
|
187 |
results.find('.qm-items-time').text(time);
|
188 |
});
|
189 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
$('#qm').find('.qm-filter-trigger').on('click',function(e){
|
191 |
var filter = $(this).data('qm-filter'),
|
192 |
value = $(this).data('qm-value'),
|
159 |
hilite = $(this).attr('data-highlight'),
|
160 |
time = 0;
|
161 |
|
162 |
+
if ( window.localStorage ) {
|
163 |
+
key = $(this).attr('id');
|
164 |
+
if ( val ) {
|
165 |
+
localStorage.setItem( key, val );
|
166 |
+
} else {
|
167 |
+
localStorage.removeItem( key );
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
if ( hilite ) {
|
172 |
table.find('tr').removeClass('qm-highlight');
|
173 |
}
|
196 |
results.find('.qm-items-time').text(time);
|
197 |
});
|
198 |
|
199 |
+
if ( window.localStorage ) {
|
200 |
+
$('#qm').find('.qm-filter').each(function () {
|
201 |
+
var key = $(this).attr('id');
|
202 |
+
var value = localStorage.getItem( key );
|
203 |
+
if ( value !== null && $(this).find('option[value="' + value + '"]').length ) {
|
204 |
+
$(this).val(value).change();
|
205 |
+
}
|
206 |
+
});
|
207 |
+
}
|
208 |
+
|
209 |
$('#qm').find('.qm-filter-trigger').on('click',function(e){
|
210 |
var filter = $(this).data('qm-filter'),
|
211 |
value = $(this).data('qm-value'),
|
classes/Backtrace.php
CHANGED
@@ -53,6 +53,10 @@ class QM_Backtrace {
|
|
53 |
'get_sidebar' => 1,
|
54 |
'get_footer' => 1,
|
55 |
'class_exists' => 2,
|
|
|
|
|
|
|
|
|
56 |
);
|
57 |
protected static $filtered = false;
|
58 |
protected $trace = null;
|
@@ -248,7 +252,11 @@ class QM_Backtrace {
|
|
248 |
$args = array();
|
249 |
for ( $i = 0; $i < $show; $i++ ) {
|
250 |
if ( isset( $trace['args'][$i] ) ) {
|
251 |
-
|
|
|
|
|
|
|
|
|
252 |
}
|
253 |
}
|
254 |
$return['id'] = $trace['function'] . '()';
|
53 |
'get_sidebar' => 1,
|
54 |
'get_footer' => 1,
|
55 |
'class_exists' => 2,
|
56 |
+
'current_user_can' => 3,
|
57 |
+
'user_can' => 4,
|
58 |
+
'current_user_can_for_blog' => 4,
|
59 |
+
'author_can' => 4,
|
60 |
);
|
61 |
protected static $filtered = false;
|
62 |
protected $trace = null;
|
252 |
$args = array();
|
253 |
for ( $i = 0; $i < $show; $i++ ) {
|
254 |
if ( isset( $trace['args'][$i] ) ) {
|
255 |
+
if ( is_string( $trace['args'][$i] ) ) {
|
256 |
+
$args[] = '\'' . $trace['args'][$i] . '\'';
|
257 |
+
} else {
|
258 |
+
$args[] = QM_Util::display_variable( $trace['args'][$i] );
|
259 |
+
}
|
260 |
}
|
261 |
}
|
262 |
$return['id'] = $trace['function'] . '()';
|
classes/Collector.php
CHANGED
@@ -21,6 +21,7 @@ abstract class QM_Collector {
|
|
21 |
'types' => array(),
|
22 |
'component_times' => array(),
|
23 |
);
|
|
|
24 |
|
25 |
public function __construct() {}
|
26 |
|
@@ -108,6 +109,19 @@ abstract class QM_Collector {
|
|
108 |
return $user;
|
109 |
}
|
110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
public function process() {}
|
112 |
|
113 |
public function tear_down() {}
|
21 |
'types' => array(),
|
22 |
'component_times' => array(),
|
23 |
);
|
24 |
+
protected static $hide_qm = null;
|
25 |
|
26 |
public function __construct() {}
|
27 |
|
109 |
return $user;
|
110 |
}
|
111 |
|
112 |
+
public static function hide_qm() {
|
113 |
+
if ( null === self::$hide_qm ) {
|
114 |
+
self::$hide_qm = ( defined( 'QM_HIDE_SELF' ) && QM_HIDE_SELF );
|
115 |
+
}
|
116 |
+
|
117 |
+
return self::$hide_qm;
|
118 |
+
}
|
119 |
+
|
120 |
+
public function filter_remove_qm( array $item ) {
|
121 |
+
$component = $item['trace']->get_component();
|
122 |
+
return ( 'query-monitor' !== $component->context );
|
123 |
+
}
|
124 |
+
|
125 |
public function process() {}
|
126 |
|
127 |
public function tear_down() {}
|
classes/Util.php
CHANGED
@@ -157,7 +157,12 @@ class QM_Util {
|
|
157 |
$name = __( 'Parent Theme', 'query-monitor' );
|
158 |
break;
|
159 |
case 'other':
|
160 |
-
|
|
|
|
|
|
|
|
|
|
|
161 |
$context = $file;
|
162 |
break;
|
163 |
case 'core':
|
@@ -330,6 +335,40 @@ class QM_Util {
|
|
330 |
return $type;
|
331 |
}
|
332 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
public static function sort( array &$array, $field ) {
|
334 |
self::$sort_field = $field;
|
335 |
usort( $array, array( __CLASS__, '_sort' ) );
|
157 |
$name = __( 'Parent Theme', 'query-monitor' );
|
158 |
break;
|
159 |
case 'other':
|
160 |
+
// Anything else that's within the content directory should appear as
|
161 |
+
// `wp-content/{dir}` or `wp-content/{file}`
|
162 |
+
$name = self::standard_dir( $file );
|
163 |
+
$name = str_replace( dirname( self::$file_dirs['other'] ), '', $name );
|
164 |
+
$parts = explode( '/', trim( $name, '/' ) );
|
165 |
+
$name = $parts[0] . '/' . $parts[1];
|
166 |
$context = $file;
|
167 |
break;
|
168 |
case 'core':
|
335 |
return $type;
|
336 |
}
|
337 |
|
338 |
+
public static function display_variable( $value ) {
|
339 |
+
if ( is_string( $value ) ) {
|
340 |
+
return $value;
|
341 |
+
} elseif ( is_bool( $value ) ) {
|
342 |
+
return ( $value ) ? 'true' : 'false';
|
343 |
+
} elseif ( is_scalar( $value ) ) {
|
344 |
+
return $value;
|
345 |
+
} elseif ( is_object( $value ) ) {
|
346 |
+
$class = get_class( $value );
|
347 |
+
$id = false;
|
348 |
+
|
349 |
+
switch ( $class ) {
|
350 |
+
|
351 |
+
case 'WP_Post':
|
352 |
+
case 'WP_User':
|
353 |
+
$id = $value->ID;
|
354 |
+
break;
|
355 |
+
|
356 |
+
case 'WP_Term':
|
357 |
+
$id = $value->term_id;
|
358 |
+
break;
|
359 |
+
|
360 |
+
}
|
361 |
+
|
362 |
+
if ( $id ) {
|
363 |
+
return sprintf( '%s (ID:%d)', $class, $id );
|
364 |
+
}
|
365 |
+
|
366 |
+
return $class;
|
367 |
+
} else {
|
368 |
+
return gettype( $value );
|
369 |
+
}
|
370 |
+
}
|
371 |
+
|
372 |
public static function sort( array &$array, $field ) {
|
373 |
self::$sort_field = $field;
|
374 |
usort( $array, array( __CLASS__, '_sort' ) );
|
collectors/caps.php
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Copyright 2009-2017 John Blackbourn
|
4 |
+
|
5 |
+
This program is free software; you can redistribute it and/or modify
|
6 |
+
it under the terms of the GNU General Public License as published by
|
7 |
+
the Free Software Foundation; either version 2 of the License, or
|
8 |
+
(at your option) any later version.
|
9 |
+
|
10 |
+
This program is distributed in the hope that it will be useful,
|
11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13 |
+
GNU General Public License for more details.
|
14 |
+
|
15 |
+
*/
|
16 |
+
|
17 |
+
class QM_Collector_Caps extends QM_Collector {
|
18 |
+
|
19 |
+
public $id = 'caps';
|
20 |
+
|
21 |
+
public function name() {
|
22 |
+
return __( 'Capability Checks', 'query-monitor' );
|
23 |
+
}
|
24 |
+
|
25 |
+
public function __construct() {
|
26 |
+
parent::__construct();
|
27 |
+
add_filter( 'user_has_cap', array( $this, 'filter_user_has_cap' ), 9999, 3 );
|
28 |
+
add_filter( 'map_meta_cap', array( $this, 'filter_map_meta_cap' ), 9999, 4 );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Logs user capability checks.
|
33 |
+
*
|
34 |
+
* This does not get called for Super Admins. See filter_map_meta_cap() below.
|
35 |
+
*
|
36 |
+
* @param bool[] $user_caps Concerned user's capabilities.
|
37 |
+
* @param string[] $required_caps Required primitive capabilities for the requested capability.
|
38 |
+
* @param array $args {
|
39 |
+
* Arguments that accompany the requested capability check.
|
40 |
+
*
|
41 |
+
* @type string $0 Requested capability.
|
42 |
+
* @type int $1 Concerned user ID.
|
43 |
+
* @type mixed ...$2 Optional second and further parameters.
|
44 |
+
* }
|
45 |
+
* @return bool[] Concerned user's capabilities.
|
46 |
+
*/
|
47 |
+
public function filter_user_has_cap( array $user_caps, array $caps, array $args ) {
|
48 |
+
$trace = new QM_Backtrace;
|
49 |
+
$result = true;
|
50 |
+
|
51 |
+
foreach ( $caps as $cap ) {
|
52 |
+
if ( empty( $user_caps[ $cap ] ) ) {
|
53 |
+
$result = false;
|
54 |
+
break;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
$this->data['caps'][] = array(
|
59 |
+
'args' => $args,
|
60 |
+
'trace' => $trace,
|
61 |
+
'result' => $result,
|
62 |
+
);
|
63 |
+
|
64 |
+
return $user_caps;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Logs user capability checks for Super Admins on Multisite.
|
69 |
+
*
|
70 |
+
* This is needed because the `user_has_cap` filter doesn't fire for Super Admins.
|
71 |
+
*
|
72 |
+
* @param string[] $required_caps Required primitive capabilities for the requested capability.
|
73 |
+
* @param string $cap Capability or meta capability being checked.
|
74 |
+
* @param int $user_id Concerned user ID.
|
75 |
+
* @param array $args {
|
76 |
+
* Arguments that accompany the requested capability check.
|
77 |
+
*
|
78 |
+
* @type mixed ...$0 Optional second and further parameters.
|
79 |
+
* }
|
80 |
+
* @return string[] Required capabilities for the requested action.
|
81 |
+
*/
|
82 |
+
public function filter_map_meta_cap( array $required_caps, $cap, $user_id, array $args ) {
|
83 |
+
if ( ! is_multisite() ) {
|
84 |
+
return $required_caps;
|
85 |
+
}
|
86 |
+
|
87 |
+
if ( ! is_super_admin( $user_id ) ) {
|
88 |
+
return $required_caps;
|
89 |
+
}
|
90 |
+
|
91 |
+
$trace = new QM_Backtrace;
|
92 |
+
$result = ( ! in_array( 'do_not_allow', $required_caps, true ) );
|
93 |
+
|
94 |
+
array_unshift( $args, $user_id );
|
95 |
+
array_unshift( $args, $cap );
|
96 |
+
|
97 |
+
$this->data['caps'][] = array(
|
98 |
+
'args' => $args,
|
99 |
+
'trace' => $trace,
|
100 |
+
'result' => $result,
|
101 |
+
);
|
102 |
+
|
103 |
+
return $required_caps;
|
104 |
+
}
|
105 |
+
|
106 |
+
public function process() {
|
107 |
+
if ( empty( $this->data['caps'] ) ) {
|
108 |
+
return;
|
109 |
+
}
|
110 |
+
|
111 |
+
$all_parts = array();
|
112 |
+
$all_users = array();
|
113 |
+
$components = array();
|
114 |
+
|
115 |
+
$this->data['caps'] = array_filter( $this->data['caps'], array( $this, 'filter_remove_noise' ) );
|
116 |
+
|
117 |
+
if ( self::hide_qm() ) {
|
118 |
+
$this->data['caps'] = array_filter( $this->data['caps'], array( $this, 'filter_remove_qm' ) );
|
119 |
+
}
|
120 |
+
|
121 |
+
foreach ( $this->data['caps'] as $i => $cap ) {
|
122 |
+
$name = $cap['args'][0];
|
123 |
+
$parts = array_filter( preg_split( '#[_/-]#', $name ) );
|
124 |
+
$this->data['caps'][ $i ]['parts'] = $parts;
|
125 |
+
$this->data['caps'][ $i ]['name'] = $name;
|
126 |
+
$this->data['caps'][ $i ]['user'] = $cap['args'][1];
|
127 |
+
$this->data['caps'][ $i ]['args'] = array_slice( $cap['args'], 2 );
|
128 |
+
$all_parts = array_merge( $all_parts, $parts );
|
129 |
+
$all_users[] = $cap['args'][1];
|
130 |
+
$component = $cap['trace']->get_component();
|
131 |
+
$components[$component->name] = $component->name;
|
132 |
+
}
|
133 |
+
|
134 |
+
$this->data['parts'] = array_unique( array_filter( $all_parts ) );
|
135 |
+
$this->data['users'] = array_unique( array_filter( $all_users ) );
|
136 |
+
$this->data['components'] = $components;
|
137 |
+
}
|
138 |
+
|
139 |
+
public function filter_remove_noise( array $cap ) {
|
140 |
+
$trace = $cap['trace']->get_trace();
|
141 |
+
|
142 |
+
$exclude_files = array(
|
143 |
+
ABSPATH . 'wp-admin/menu.php',
|
144 |
+
ABSPATH . 'wp-admin/includes/menu.php',
|
145 |
+
);
|
146 |
+
$exclude_functions = array(
|
147 |
+
'_wp_menu_output',
|
148 |
+
'wp_admin_bar_render',
|
149 |
+
);
|
150 |
+
|
151 |
+
foreach ( $trace as $item ) {
|
152 |
+
if ( isset( $item['file'] ) && in_array( $item['file'], $exclude_files, true ) ) {
|
153 |
+
return false;
|
154 |
+
}
|
155 |
+
if ( isset( $item['function'] ) && in_array( $item['function'], $exclude_functions, true ) ) {
|
156 |
+
return false;
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
return true;
|
161 |
+
}
|
162 |
+
|
163 |
+
}
|
164 |
+
|
165 |
+
function register_qm_collector_caps( array $collectors, QueryMonitor $qm ) {
|
166 |
+
$collectors['caps'] = new QM_Collector_Caps;
|
167 |
+
return $collectors;
|
168 |
+
}
|
169 |
+
|
170 |
+
add_filter( 'qm/collectors', 'register_qm_collector_caps', 20, 2 );
|
collectors/hooks.php
CHANGED
@@ -18,7 +18,6 @@ class QM_Collector_Hooks extends QM_Collector {
|
|
18 |
|
19 |
public $id = 'hooks';
|
20 |
protected static $hide_core;
|
21 |
-
protected static $hide_qm;
|
22 |
|
23 |
public function name() {
|
24 |
return __( 'Hooks & Actions', 'query-monitor' );
|
@@ -28,7 +27,7 @@ class QM_Collector_Hooks extends QM_Collector {
|
|
28 |
|
29 |
global $wp_actions, $wp_filter;
|
30 |
|
31 |
-
self::$hide_qm
|
32 |
self::$hide_core = ( defined( 'QM_HIDE_CORE_HOOKS' ) && QM_HIDE_CORE_HOOKS );
|
33 |
|
34 |
if ( is_admin() and ( $admin = QM_Collectors::get( 'admin' ) ) ) {
|
18 |
|
19 |
public $id = 'hooks';
|
20 |
protected static $hide_core;
|
|
|
21 |
|
22 |
public function name() {
|
23 |
return __( 'Hooks & Actions', 'query-monitor' );
|
27 |
|
28 |
global $wp_actions, $wp_filter;
|
29 |
|
30 |
+
self::$hide_qm = self::hide_qm();
|
31 |
self::$hide_core = ( defined( 'QM_HIDE_CORE_HOOKS' ) && QM_HIDE_CORE_HOOKS );
|
32 |
|
33 |
if ( is_admin() and ( $admin = QM_Collectors::get( 'admin' ) ) ) {
|
output/Html.php
CHANGED
@@ -97,6 +97,10 @@ abstract class QM_Output_Html extends QM_Output {
|
|
97 |
'prepend' => array(),
|
98 |
), $args );
|
99 |
|
|
|
|
|
|
|
|
|
100 |
usort( $values, 'strcasecmp' );
|
101 |
|
102 |
$filter_id = 'qm-filter-' . $this->collector->id . '-' . $name;
|
97 |
'prepend' => array(),
|
98 |
), $args );
|
99 |
|
100 |
+
if ( 'component' === $name ) {
|
101 |
+
$args['prepend']['non-core'] = __( 'Non-Core', 'query-monitor' );
|
102 |
+
}
|
103 |
+
|
104 |
usort( $values, 'strcasecmp' );
|
105 |
|
106 |
$filter_id = 'qm-filter-' . $this->collector->id . '-' . $name;
|
output/html/caps.php
ADDED
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Copyright 2009-2017 John Blackbourn
|
4 |
+
|
5 |
+
This program is free software; you can redistribute it and/or modify
|
6 |
+
it under the terms of the GNU General Public License as published by
|
7 |
+
the Free Software Foundation; either version 2 of the License, or
|
8 |
+
(at your option) any later version.
|
9 |
+
|
10 |
+
This program is distributed in the hope that it will be useful,
|
11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13 |
+
GNU General Public License for more details.
|
14 |
+
|
15 |
+
*/
|
16 |
+
|
17 |
+
class QM_Output_Html_Caps extends QM_Output_Html {
|
18 |
+
|
19 |
+
public function __construct( QM_Collector $collector ) {
|
20 |
+
parent::__construct( $collector );
|
21 |
+
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 105 );
|
22 |
+
}
|
23 |
+
|
24 |
+
public function output() {
|
25 |
+
|
26 |
+
$data = $this->collector->get_data();
|
27 |
+
|
28 |
+
echo '<div class="qm" id="' . esc_attr( $this->collector->id() ) . '">';
|
29 |
+
echo '<table cellspacing="0">';
|
30 |
+
|
31 |
+
if ( ! empty( $data['caps'] ) ) {
|
32 |
+
|
33 |
+
$results = array(
|
34 |
+
'true',
|
35 |
+
'false',
|
36 |
+
);
|
37 |
+
$show_user = ( count( $data['users'] ) > 1 );
|
38 |
+
|
39 |
+
echo '<caption class="screen-reader-text">' . esc_html( $this->collector->name() ) . '</caption>';
|
40 |
+
|
41 |
+
echo '<thead>';
|
42 |
+
echo '<tr>';
|
43 |
+
echo '<th scope="col">';
|
44 |
+
echo $this->build_filter( 'name', $data['parts'], __( 'Capability Check', 'query-monitor' ) ); // WPCS: XSS ok;
|
45 |
+
echo '</th>';
|
46 |
+
|
47 |
+
if ( $show_user ) {
|
48 |
+
echo '<th scope="col">';
|
49 |
+
echo $this->build_filter( 'user', $data['users'], __( 'User', 'query-monitor' ) ); // WPCS: XSS ok;
|
50 |
+
echo '</th>';
|
51 |
+
}
|
52 |
+
|
53 |
+
echo '<th scope="col">';
|
54 |
+
echo $this->build_filter( 'result', $results, __( 'Result', 'query-monitor' ) ); // WPCS: XSS ok;
|
55 |
+
echo '</th>';
|
56 |
+
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
57 |
+
echo '<th scope="col">';
|
58 |
+
echo $this->build_filter( 'component', $data['components'], __( 'Component', 'query-monitor' ) ); // WPCS: XSS ok.
|
59 |
+
echo '</th>';
|
60 |
+
echo '</tr>';
|
61 |
+
echo '</thead>';
|
62 |
+
|
63 |
+
echo '<tbody>';
|
64 |
+
|
65 |
+
foreach ( $data['caps'] as $row ) {
|
66 |
+
$component = $row['trace']->get_component();
|
67 |
+
|
68 |
+
$row_attr = array();
|
69 |
+
$row_attr['data-qm-name'] = implode( ' ', $row['parts'] );
|
70 |
+
$row_attr['data-qm-user'] = $row['user'];
|
71 |
+
$row_attr['data-qm-component'] = $component->name;
|
72 |
+
$row_attr['data-qm-result'] = ( $row['result'] ) ? 'true' : 'false';
|
73 |
+
|
74 |
+
if ( 'core' !== $component->context ) {
|
75 |
+
$row_attr['data-qm-component'] .= ' non-core';
|
76 |
+
}
|
77 |
+
|
78 |
+
$attr = '';
|
79 |
+
|
80 |
+
foreach ( $row_attr as $a => $v ) {
|
81 |
+
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
82 |
+
}
|
83 |
+
|
84 |
+
printf( // WPCS: XSS ok.
|
85 |
+
'<tr %s>',
|
86 |
+
$attr
|
87 |
+
);
|
88 |
+
|
89 |
+
$name = esc_html( $row['name'] );
|
90 |
+
|
91 |
+
if ( ! empty( $row['args'] ) ) {
|
92 |
+
foreach ( $row['args'] as $arg ) {
|
93 |
+
$name .= '<br>' . esc_html( QM_Util::display_variable( $arg ) );
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
printf( // WPCS: XSS ok.
|
98 |
+
'<td class="qm-ltr qm-nowrap">%s</td>',
|
99 |
+
$name
|
100 |
+
);
|
101 |
+
|
102 |
+
if ( $show_user ) {
|
103 |
+
printf(
|
104 |
+
'<td class="qm-num">%s</td>',
|
105 |
+
esc_html( $row['user'] )
|
106 |
+
);
|
107 |
+
}
|
108 |
+
|
109 |
+
$result = ( $row['result'] ) ? '<span class="qm-true">true ✓</span>' : '<span class="qm-false">false</span>';
|
110 |
+
printf( // WPCS: XSS ok.
|
111 |
+
'<td class="qm-ltr qm-nowrap">%s</td>',
|
112 |
+
$result
|
113 |
+
);
|
114 |
+
|
115 |
+
$stack = array();
|
116 |
+
$trace = $row['trace']->get_trace();
|
117 |
+
$filtered_trace = $row['trace']->get_display_trace();
|
118 |
+
|
119 |
+
array_pop( $filtered_trace ); // remove the WP_User->has_cap() call
|
120 |
+
array_pop( $filtered_trace ); // remove the *_user_can() call
|
121 |
+
|
122 |
+
if ( ! count( $filtered_trace ) ) {
|
123 |
+
$responsible_name = QM_Util::standard_dir( $trace[1]['file'], '' ) . ':' . $trace[1]['line'];
|
124 |
+
|
125 |
+
$responsible_item = $trace[1];
|
126 |
+
$responsible_item['display'] = $responsible_name;
|
127 |
+
$responsible_item['calling_file'] = $trace[1]['file'];
|
128 |
+
$responsible_item['calling_line'] = $trace[1]['line'];
|
129 |
+
array_unshift( $filtered_trace, $responsible_item );
|
130 |
+
}
|
131 |
+
|
132 |
+
foreach ( $filtered_trace as $item ) {
|
133 |
+
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
134 |
+
}
|
135 |
+
|
136 |
+
echo '<td class="qm-has-toggle qm-nowrap qm-ltr"><ol class="qm-toggler qm-numbered">';
|
137 |
+
|
138 |
+
$caller = array_pop( $stack );
|
139 |
+
|
140 |
+
if ( ! empty( $stack ) ) {
|
141 |
+
echo '<button class="qm-toggle" data-on="+" data-off="-">+</button>';
|
142 |
+
echo '<div class="qm-toggled"><li>' . implode( '</li><li>', $stack ) . '</li></div>'; // WPCS: XSS ok.
|
143 |
+
}
|
144 |
+
|
145 |
+
echo "<li>{$caller}</li>"; // WPCS: XSS ok.
|
146 |
+
echo '</ol></td>';
|
147 |
+
|
148 |
+
printf(
|
149 |
+
'<td class="qm-nowrap">%s</td>',
|
150 |
+
esc_html( $component->name )
|
151 |
+
);
|
152 |
+
|
153 |
+
echo '</tr>';
|
154 |
+
|
155 |
+
}
|
156 |
+
|
157 |
+
echo '</tbody>';
|
158 |
+
|
159 |
+
} else {
|
160 |
+
|
161 |
+
echo '<caption>' . esc_html( $this->collector->name() ) . '</caption>';
|
162 |
+
|
163 |
+
echo '<tbody>';
|
164 |
+
echo '<tr>';
|
165 |
+
echo '<td>';
|
166 |
+
esc_html_e( 'No capability checks were recorded.', 'query-monitor' );
|
167 |
+
echo '</td>';
|
168 |
+
echo '</tr>';
|
169 |
+
echo '</tbody>';
|
170 |
+
|
171 |
+
}
|
172 |
+
|
173 |
+
echo '</table>';
|
174 |
+
echo '</div>';
|
175 |
+
|
176 |
+
}
|
177 |
+
|
178 |
+
public function admin_menu( array $menu ) {
|
179 |
+
$menu[] = $this->menu( array(
|
180 |
+
'title' => $this->collector->name(),
|
181 |
+
) );
|
182 |
+
return $menu;
|
183 |
+
|
184 |
+
}
|
185 |
+
|
186 |
+
}
|
187 |
+
|
188 |
+
function register_qm_output_html_caps( array $output, QM_Collectors $collectors ) {
|
189 |
+
if ( $collector = QM_Collectors::get( 'caps' ) ) {
|
190 |
+
$output['caps'] = new QM_Output_Html_Caps( $collector );
|
191 |
+
}
|
192 |
+
return $output;
|
193 |
+
}
|
194 |
+
|
195 |
+
add_filter( 'qm/outputter/html', 'register_qm_output_html_caps', 105, 2 );
|
output/html/db_queries.php
CHANGED
@@ -79,13 +79,14 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
79 |
echo '<th scope="col">' . esc_html__( 'Query', 'query-monitor' ) . '</th>';
|
80 |
echo '<th scope="col">' . esc_html__( 'Call Stack', 'query-monitor' ) . '</th>';
|
81 |
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
82 |
-
echo '<th scope="col">' . esc_html__( 'Error', 'query-monitor' ) . '</th>';
|
|
|
83 |
echo '</tr>';
|
84 |
echo '</thead>';
|
85 |
echo '<tbody>';
|
86 |
|
87 |
foreach ( $errors as $row ) {
|
88 |
-
$this->output_query_row( $row, array( 'sql', 'stack', 'component', 'result' ) );
|
89 |
}
|
90 |
|
91 |
echo '</tbody>';
|
@@ -185,12 +186,23 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
185 |
echo '</tr>';
|
186 |
}
|
187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
echo '<tr>';
|
189 |
echo '<th scope="col" class="qm-sorted-asc"> ';
|
190 |
echo $this->build_sorter(); // WPCS: XSS ok;
|
191 |
echo '</th>';
|
192 |
echo '<th scope="col">';
|
193 |
-
echo $this->build_filter( 'type',
|
194 |
echo '</th>';
|
195 |
echo '<th scope="col">';
|
196 |
|
@@ -293,7 +305,7 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
293 |
unset( $cols['component'] );
|
294 |
}
|
295 |
if ( !isset( $row['result'] ) ) {
|
296 |
-
unset( $cols['result'] );
|
297 |
}
|
298 |
if ( !isset( $row['stack'] ) ) {
|
299 |
unset( $cols['stack'] );
|
@@ -337,9 +349,16 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
337 |
}
|
338 |
if ( isset( $cols['sql'] ) ) {
|
339 |
$row_attr['data-qm-type'] = $row['type'];
|
|
|
|
|
|
|
340 |
}
|
341 |
if ( isset( $cols['component'] ) && $row['component'] ) {
|
342 |
$row_attr['data-qm-component'] = $row['component']->name;
|
|
|
|
|
|
|
|
|
343 |
}
|
344 |
if ( isset( $cols['caller'] ) ) {
|
345 |
$row_attr['data-qm-caller'] = $row['caller_name'];
|
@@ -393,9 +412,11 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
393 |
}
|
394 |
|
395 |
if ( isset( $cols['stack'] ) ) {
|
396 |
-
echo '<td class="qm-row-caller qm-row-stack qm-nowrap qm-ltr"><ol>';
|
|
|
|
|
|
|
397 |
echo "<li>{$caller_name}</li>"; // WPCS: XSS ok.
|
398 |
-
echo '<li>' . implode( '</li><li>', $stack ) . '</li>'; // WPCS: XSS ok.
|
399 |
echo '</ol></td>';
|
400 |
}
|
401 |
|
@@ -407,6 +428,10 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
407 |
}
|
408 |
}
|
409 |
|
|
|
|
|
|
|
|
|
410 |
if ( isset( $cols['result'] ) ) {
|
411 |
if ( is_wp_error( $row['result'] ) ) {
|
412 |
echo "<td class='qm-row-result qm-row-error'>" . esc_html( $row['result']->get_error_message() ) . "</td>\n";
|
79 |
echo '<th scope="col">' . esc_html__( 'Query', 'query-monitor' ) . '</th>';
|
80 |
echo '<th scope="col">' . esc_html__( 'Call Stack', 'query-monitor' ) . '</th>';
|
81 |
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
82 |
+
echo '<th scope="col">' . esc_html__( 'Error Code', 'query-monitor' ) . '</th>';
|
83 |
+
echo '<th scope="col">' . esc_html__( 'Error Message', 'query-monitor' ) . '</th>';
|
84 |
echo '</tr>';
|
85 |
echo '</thead>';
|
86 |
echo '<tbody>';
|
87 |
|
88 |
foreach ( $errors as $row ) {
|
89 |
+
$this->output_query_row( $row, array( 'sql', 'stack', 'component', 'errno', 'result' ) );
|
90 |
}
|
91 |
|
92 |
echo '</tbody>';
|
186 |
echo '</tr>';
|
187 |
}
|
188 |
|
189 |
+
$types = array_keys( $db->types );
|
190 |
+
$prepend = array();
|
191 |
+
|
192 |
+
if ( count( $types ) > 1 ) {
|
193 |
+
$prepend['non-select'] = __( 'Non-SELECT', 'query-monitor' );
|
194 |
+
}
|
195 |
+
|
196 |
+
$args = array(
|
197 |
+
'prepend' => $prepend,
|
198 |
+
);
|
199 |
+
|
200 |
echo '<tr>';
|
201 |
echo '<th scope="col" class="qm-sorted-asc"> ';
|
202 |
echo $this->build_sorter(); // WPCS: XSS ok;
|
203 |
echo '</th>';
|
204 |
echo '<th scope="col">';
|
205 |
+
echo $this->build_filter( 'type', $types, __( 'Query', 'query-monitor' ), $args ); // WPCS: XSS ok;
|
206 |
echo '</th>';
|
207 |
echo '<th scope="col">';
|
208 |
|
305 |
unset( $cols['component'] );
|
306 |
}
|
307 |
if ( !isset( $row['result'] ) ) {
|
308 |
+
unset( $cols['result'], $cols['errno'] );
|
309 |
}
|
310 |
if ( !isset( $row['stack'] ) ) {
|
311 |
unset( $cols['stack'] );
|
349 |
}
|
350 |
if ( isset( $cols['sql'] ) ) {
|
351 |
$row_attr['data-qm-type'] = $row['type'];
|
352 |
+
if ( 'SELECT' !== $row['type'] ) {
|
353 |
+
$row_attr['data-qm-type'] .= ' non-select';
|
354 |
+
}
|
355 |
}
|
356 |
if ( isset( $cols['component'] ) && $row['component'] ) {
|
357 |
$row_attr['data-qm-component'] = $row['component']->name;
|
358 |
+
|
359 |
+
if ( 'core' !== $row['component']->context ) {
|
360 |
+
$row_attr['data-qm-component'] .= ' non-core';
|
361 |
+
}
|
362 |
}
|
363 |
if ( isset( $cols['caller'] ) ) {
|
364 |
$row_attr['data-qm-caller'] = $row['caller_name'];
|
412 |
}
|
413 |
|
414 |
if ( isset( $cols['stack'] ) ) {
|
415 |
+
echo '<td class="qm-row-caller qm-row-stack qm-nowrap qm-ltr"><ol class="qm-numbered">';
|
416 |
+
if ( ! empty( $stack ) ) {
|
417 |
+
echo '<li>' . implode( '</li><li>', $stack ) . '</li>'; // WPCS: XSS ok.
|
418 |
+
}
|
419 |
echo "<li>{$caller_name}</li>"; // WPCS: XSS ok.
|
|
|
420 |
echo '</ol></td>';
|
421 |
}
|
422 |
|
428 |
}
|
429 |
}
|
430 |
|
431 |
+
if ( isset( $cols['errno'] ) && is_wp_error( $row['result'] ) ) {
|
432 |
+
echo "<td class='qm-row-result qm-row-error'>" . esc_html( $row['result']->get_error_code() ) . "</td>\n";
|
433 |
+
}
|
434 |
+
|
435 |
if ( isset( $cols['result'] ) ) {
|
436 |
if ( is_wp_error( $row['result'] ) ) {
|
437 |
echo "<td class='qm-row-result qm-row-error'>" . esc_html( $row['result']->get_error_message() ) . "</td>\n";
|
output/html/environment.php
CHANGED
@@ -109,7 +109,7 @@ class QM_Output_Html_Environment extends QM_Output_Html {
|
|
109 |
);
|
110 |
|
111 |
echo '<div class="qm-toggled">';
|
112 |
-
echo "<ul class='qm-
|
113 |
echo '</div>';
|
114 |
|
115 |
echo '</div></td>';
|
@@ -125,7 +125,7 @@ class QM_Output_Html_Environment extends QM_Output_Html {
|
|
125 |
esc_html( number_format_i18n( count( $data['php']['extensions'] ) ) )
|
126 |
);
|
127 |
|
128 |
-
echo '<div class="qm-toggled"><ul class="qm-
|
129 |
echo implode( '</li><li>', array_map( 'esc_html', $data['php']['extensions'] ) );
|
130 |
echo '</li></ul></div>';
|
131 |
|
109 |
);
|
110 |
|
111 |
echo '<div class="qm-toggled">';
|
112 |
+
echo "<ul class='qm-supplemental'><li>{$error_levels}</li></ul>"; // WPCS: XSS ok.
|
113 |
echo '</div>';
|
114 |
|
115 |
echo '</div></td>';
|
125 |
esc_html( number_format_i18n( count( $data['php']['extensions'] ) ) )
|
126 |
);
|
127 |
|
128 |
+
echo '<div class="qm-toggled"><ul class="qm-supplemental"><li>';
|
129 |
echo implode( '</li><li>', array_map( 'esc_html', $data['php']['extensions'] ) );
|
130 |
echo '</li></ul></div>';
|
131 |
|
output/html/hooks.php
CHANGED
@@ -80,6 +80,10 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
|
|
80 |
$row_attr['data-qm-name'] = implode( ' ', $hook['parts'] );
|
81 |
$row_attr['data-qm-component'] = implode( ' ', $hook['components'] );
|
82 |
|
|
|
|
|
|
|
|
|
83 |
$attr = '';
|
84 |
|
85 |
if ( !empty( $hook['actions'] ) ) {
|
80 |
$row_attr['data-qm-name'] = implode( ' ', $hook['parts'] );
|
81 |
$row_attr['data-qm-component'] = implode( ' ', $hook['components'] );
|
82 |
|
83 |
+
if ( ! empty( $row_attr['data-qm-component'] ) && 'Core' !== $row_attr['data-qm-component'] ) {
|
84 |
+
$row_attr['data-qm-component'] .= ' non-core';
|
85 |
+
}
|
86 |
+
|
87 |
$attr = '';
|
88 |
|
89 |
if ( !empty( $hook['actions'] ) ) {
|
output/html/http.php
CHANGED
@@ -52,7 +52,7 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
52 |
echo '<th scope="col">';
|
53 |
echo $this->build_filter( 'type', array_keys( $data['types'] ), __( 'Status', 'query-monitor' ) ); // WPCS: XSS ok.
|
54 |
echo '</th>';
|
55 |
-
echo '<th scope="col">' . esc_html__( '
|
56 |
echo '<th scope="col">';
|
57 |
echo $this->build_filter( 'component', wp_list_pluck( $data['component_times'], 'component' ), __( 'Component', 'query-monitor' ) ); // WPCS: XSS ok.
|
58 |
echo '</th>';
|
@@ -123,7 +123,9 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
123 |
|
124 |
$stack = array();
|
125 |
$filtered_trace = $row['trace']->get_display_trace();
|
126 |
-
array_pop( $filtered_trace );
|
|
|
|
|
127 |
|
128 |
foreach ( $filtered_trace as $item ) {
|
129 |
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
@@ -132,6 +134,10 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
132 |
$row_attr['data-qm-component'] = $component->name;
|
133 |
$row_attr['data-qm-type'] = $row['type'];
|
134 |
|
|
|
|
|
|
|
|
|
135 |
$attr = '';
|
136 |
foreach ( $row_attr as $a => $v ) {
|
137 |
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
@@ -155,10 +161,19 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
155 |
'<td>%s</td>',
|
156 |
esc_html( $response )
|
157 |
);
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
printf(
|
163 |
'<td class="qm-nowrap">%s</td>',
|
164 |
esc_html( $component->name )
|
52 |
echo '<th scope="col">';
|
53 |
echo $this->build_filter( 'type', array_keys( $data['types'] ), __( 'Status', 'query-monitor' ) ); // WPCS: XSS ok.
|
54 |
echo '</th>';
|
55 |
+
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
56 |
echo '<th scope="col">';
|
57 |
echo $this->build_filter( 'component', wp_list_pluck( $data['component_times'], 'component' ), __( 'Component', 'query-monitor' ) ); // WPCS: XSS ok.
|
58 |
echo '</th>';
|
123 |
|
124 |
$stack = array();
|
125 |
$filtered_trace = $row['trace']->get_display_trace();
|
126 |
+
array_pop( $filtered_trace ); // remove WP_Http->request()
|
127 |
+
array_pop( $filtered_trace ); // remove WP_Http->{$method}()
|
128 |
+
array_pop( $filtered_trace ); // remove wp_remote_{$method}()
|
129 |
|
130 |
foreach ( $filtered_trace as $item ) {
|
131 |
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
134 |
$row_attr['data-qm-component'] = $component->name;
|
135 |
$row_attr['data-qm-type'] = $row['type'];
|
136 |
|
137 |
+
if ( 'core' !== $component->context ) {
|
138 |
+
$row_attr['data-qm-component'] .= ' non-core';
|
139 |
+
}
|
140 |
+
|
141 |
$attr = '';
|
142 |
foreach ( $row_attr as $a => $v ) {
|
143 |
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
161 |
'<td>%s</td>',
|
162 |
esc_html( $response )
|
163 |
);
|
164 |
+
|
165 |
+
echo '<td class="qm-has-toggle qm-nowrap qm-ltr"><ol class="qm-toggler qm-numbered">';
|
166 |
+
|
167 |
+
$caller = array_pop( $stack );
|
168 |
+
|
169 |
+
if ( ! empty( $stack ) ) {
|
170 |
+
echo '<button class="qm-toggle" data-on="+" data-off="-">+</button>';
|
171 |
+
echo '<div class="qm-toggled"><li>' . implode( '</li><li>', $stack ) . '</li></div>'; // WPCS: XSS ok.
|
172 |
+
}
|
173 |
+
|
174 |
+
echo "<li>{$caller}</li>"; // WPCS: XSS ok.
|
175 |
+
echo '</ol></td>';
|
176 |
+
|
177 |
printf(
|
178 |
'<td class="qm-nowrap">%s</td>',
|
179 |
esc_html( $component->name )
|
output/html/transients.php
CHANGED
@@ -40,7 +40,7 @@ class QM_Output_Html_Transients extends QM_Output_Html {
|
|
40 |
}
|
41 |
echo '<th scope="col">' . esc_html__( 'Expiration', 'query-monitor' ) . '</th>';
|
42 |
echo '<th scope="col">' . esc_html_x( 'Size', 'size of transient value', 'query-monitor' ) . '</th>';
|
43 |
-
echo '<th scope="col">' . esc_html__( '
|
44 |
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
45 |
echo '</tr>';
|
46 |
echo '</thead>';
|
@@ -86,16 +86,25 @@ class QM_Output_Html_Transients extends QM_Output_Html {
|
|
86 |
|
87 |
$stack = array();
|
88 |
$filtered_trace = $row['trace']->get_display_trace();
|
89 |
-
array_pop( $filtered_trace );
|
|
|
90 |
|
91 |
foreach ( $filtered_trace as $item ) {
|
92 |
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
93 |
}
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
printf(
|
100 |
'<td class="qm-nowrap">%s</td>',
|
101 |
esc_html( $component->name )
|
40 |
}
|
41 |
echo '<th scope="col">' . esc_html__( 'Expiration', 'query-monitor' ) . '</th>';
|
42 |
echo '<th scope="col">' . esc_html_x( 'Size', 'size of transient value', 'query-monitor' ) . '</th>';
|
43 |
+
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
44 |
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
45 |
echo '</tr>';
|
46 |
echo '</thead>';
|
86 |
|
87 |
$stack = array();
|
88 |
$filtered_trace = $row['trace']->get_display_trace();
|
89 |
+
array_pop( $filtered_trace ); // remove do_action('setted_(site_)?transient')
|
90 |
+
array_pop( $filtered_trace ); // remove set_(site_)?transient()
|
91 |
|
92 |
foreach ( $filtered_trace as $item ) {
|
93 |
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
94 |
}
|
95 |
|
96 |
+
echo '<td class="qm-has-toggle qm-nowrap qm-ltr"><ol class="qm-toggler qm-numbered">';
|
97 |
+
|
98 |
+
$caller = array_pop( $stack );
|
99 |
+
|
100 |
+
if ( ! empty( $stack ) ) {
|
101 |
+
echo '<button class="qm-toggle" data-on="+" data-off="-">+</button>';
|
102 |
+
echo '<div class="qm-toggled"><li>' . implode( '</li><li>', $stack ) . '</li></div>'; // WPCS: XSS ok.
|
103 |
+
}
|
104 |
+
|
105 |
+
echo "<li>{$caller}</li>"; // WPCS: XSS ok.
|
106 |
+
echo '</ol></td>';
|
107 |
+
|
108 |
printf(
|
109 |
'<td class="qm-nowrap">%s</td>',
|
110 |
esc_html( $component->name )
|
query-monitor.php
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
*
|
11 |
* Plugin Name: Query Monitor
|
12 |
* Description: Monitoring of database queries, hooks, conditionals and more.
|
13 |
-
* Version: 2.
|
14 |
* Plugin URI: https://github.com/johnbillion/query-monitor
|
15 |
* Author: John Blackbourn
|
16 |
* Author URI: https://johnblackbourn.com/
|
10 |
*
|
11 |
* Plugin Name: Query Monitor
|
12 |
* Description: Monitoring of database queries, hooks, conditionals and more.
|
13 |
+
* Version: 2.16.1
|
14 |
* Plugin URI: https://github.com/johnbillion/query-monitor
|
15 |
* Author: John Blackbourn
|
16 |
* Author URI: https://johnblackbourn.com/
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
Contributors: johnbillion
|
3 |
Tags: ajax, debug, debug-bar, debugging, development, developer, performance, profiler, profiling, queries, query monitor, rest-api
|
4 |
Requires at least: 3.7
|
5 |
-
Tested up to: 4.
|
6 |
-
Stable tag: 2.
|
7 |
License: GPLv2 or later
|
8 |
|
9 |
View debugging and performance information on database queries, hooks, conditionals, HTTP requests, redirects and more.
|
@@ -75,6 +75,10 @@ Filtering queries by component or calling function makes it easy to see which pl
|
|
75 |
* Shows the response code, call stack, component, timeout, and time taken
|
76 |
* Highlights erroneous responses, such as failed requests and anything without a `200` response code
|
77 |
|
|
|
|
|
|
|
|
|
78 |
= Redirects =
|
79 |
|
80 |
* Whenever a redirect occurs, Query Monitor adds an `X-QM-Redirect` HTTP header containing the call stack, so you can use your favourite HTTP inspector or browser developer tools to easily trace where a redirect has come from
|
2 |
Contributors: johnbillion
|
3 |
Tags: ajax, debug, debug-bar, debugging, development, developer, performance, profiler, profiling, queries, query monitor, rest-api
|
4 |
Requires at least: 3.7
|
5 |
+
Tested up to: 4.9
|
6 |
+
Stable tag: 2.16.1
|
7 |
License: GPLv2 or later
|
8 |
|
9 |
View debugging and performance information on database queries, hooks, conditionals, HTTP requests, redirects and more.
|
75 |
* Shows the response code, call stack, component, timeout, and time taken
|
76 |
* Highlights erroneous responses, such as failed requests and anything without a `200` response code
|
77 |
|
78 |
+
= User Capability Checks =
|
79 |
+
|
80 |
+
* Shows every user capability check that is performed on the page, along with the result and any parameters passed along with the capability check.
|
81 |
+
|
82 |
= Redirects =
|
83 |
|
84 |
* Whenever a redirect occurs, Query Monitor adds an `X-QM-Redirect` HTTP header containing the call stack, so you can use your favourite HTTP inspector or browser developer tools to easily trace where a redirect has come from
|
wp-content/db.php
CHANGED
@@ -109,7 +109,17 @@ class QM_DB extends wpdb {
|
|
109 |
) );
|
110 |
|
111 |
if ( $this->last_error ) {
|
112 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
} else {
|
114 |
$this->queries[$i]['result'] = $result;
|
115 |
}
|
109 |
) );
|
110 |
|
111 |
if ( $this->last_error ) {
|
112 |
+
$code = 'qmdb';
|
113 |
+
if ( $this->use_mysqli ) {
|
114 |
+
if ( $this->dbh instanceof mysqli ) {
|
115 |
+
$code = mysqli_errno( $this->dbh );
|
116 |
+
}
|
117 |
+
} else {
|
118 |
+
if ( is_resource( $this->dbh ) ) {
|
119 |
+
$code = mysql_errno( $this->dbh );
|
120 |
+
}
|
121 |
+
}
|
122 |
+
$this->queries[$i]['result'] = new WP_Error( $code, $this->last_error );
|
123 |
} else {
|
124 |
$this->queries[$i]['result'] = $result;
|
125 |
}
|