Version Description
- An unknown component now gets marked as such, not as Core.
- Support for invokable objects in action and filter callbacks.
- Fix fatal error when activating Debug Bar plugin after Query Monitor has already been activated.
- Implement escaping inside
QM_Output_Html::format_url()
which can deal with unsafe output. Thanks to Stephen Harris for the responsible disclosure.
Download this release
Release Info
Developer | johnbillion |
Plugin | Query Monitor |
Version | 2.7.4 |
Comparing to | |
See all releases |
Code changes from version 2.7.3 to 2.7.4
- classes/Util.php +21 -11
- collectors/debug_bar.php +49 -1
- output/Html.php +2 -2
- query-monitor.php +3 -3
- readme.txt +10 -4
- wp-content/db.php +2 -2
classes/Util.php
CHANGED
@@ -69,6 +69,7 @@ class QM_Util {
|
|
69 |
self::$file_dirs['template'] = self::standard_dir( get_template_directory() );
|
70 |
self::$file_dirs['other'] = self::standard_dir( WP_CONTENT_DIR );
|
71 |
self::$file_dirs['core'] = self::standard_dir( ABSPATH );
|
|
|
72 |
}
|
73 |
return self::$file_dirs;
|
74 |
}
|
@@ -82,7 +83,7 @@ class QM_Util {
|
|
82 |
}
|
83 |
|
84 |
foreach ( self::get_file_dirs() as $type => $dir ) {
|
85 |
-
if ( 0 === strpos( $file, $dir ) ) {
|
86 |
break;
|
87 |
}
|
88 |
}
|
@@ -129,9 +130,12 @@ class QM_Util {
|
|
129 |
$context = $file;
|
130 |
break;
|
131 |
case 'core':
|
132 |
-
default:
|
133 |
$name = __( 'Core', 'query-monitor' );
|
134 |
break;
|
|
|
|
|
|
|
|
|
135 |
}
|
136 |
|
137 |
return self::$file_components[$file] = (object) compact( 'type', 'name', 'context' );
|
@@ -140,11 +144,8 @@ class QM_Util {
|
|
140 |
|
141 |
public static function populate_callback( array $callback ) {
|
142 |
|
143 |
-
$access = '->';
|
144 |
-
|
145 |
if ( is_string( $callback['function'] ) and ( false !== strpos( $callback['function'], '::' ) ) ) {
|
146 |
$callback['function'] = explode( '::', $callback['function'] );
|
147 |
-
$access = '::';
|
148 |
}
|
149 |
|
150 |
try {
|
@@ -152,19 +153,28 @@ class QM_Util {
|
|
152 |
if ( is_array( $callback['function'] ) ) {
|
153 |
|
154 |
if ( is_object( $callback['function'][0] ) ) {
|
155 |
-
$class
|
|
|
156 |
} else {
|
157 |
-
$class
|
|
|
158 |
}
|
159 |
|
160 |
$callback['name'] = $class . $access . $callback['function'][1] . '()';
|
161 |
$ref = new ReflectionMethod( $class, $callback['function'][1] );
|
162 |
|
163 |
-
} else if ( is_object( $callback['function'] )
|
164 |
|
165 |
-
|
166 |
-
|
167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
} else {
|
170 |
|
69 |
self::$file_dirs['template'] = self::standard_dir( get_template_directory() );
|
70 |
self::$file_dirs['other'] = self::standard_dir( WP_CONTENT_DIR );
|
71 |
self::$file_dirs['core'] = self::standard_dir( ABSPATH );
|
72 |
+
self::$file_dirs['unknown'] = null;
|
73 |
}
|
74 |
return self::$file_dirs;
|
75 |
}
|
83 |
}
|
84 |
|
85 |
foreach ( self::get_file_dirs() as $type => $dir ) {
|
86 |
+
if ( $dir && ( 0 === strpos( $file, $dir ) ) ) {
|
87 |
break;
|
88 |
}
|
89 |
}
|
130 |
$context = $file;
|
131 |
break;
|
132 |
case 'core':
|
|
|
133 |
$name = __( 'Core', 'query-monitor' );
|
134 |
break;
|
135 |
+
case 'unknown':
|
136 |
+
default:
|
137 |
+
$name = __( 'Unknown', 'query-monitor' );
|
138 |
+
break;
|
139 |
}
|
140 |
|
141 |
return self::$file_components[$file] = (object) compact( 'type', 'name', 'context' );
|
144 |
|
145 |
public static function populate_callback( array $callback ) {
|
146 |
|
|
|
|
|
147 |
if ( is_string( $callback['function'] ) and ( false !== strpos( $callback['function'], '::' ) ) ) {
|
148 |
$callback['function'] = explode( '::', $callback['function'] );
|
|
|
149 |
}
|
150 |
|
151 |
try {
|
153 |
if ( is_array( $callback['function'] ) ) {
|
154 |
|
155 |
if ( is_object( $callback['function'][0] ) ) {
|
156 |
+
$class = get_class( $callback['function'][0] );
|
157 |
+
$access = '->';
|
158 |
} else {
|
159 |
+
$class = $callback['function'][0];
|
160 |
+
$access = '::';
|
161 |
}
|
162 |
|
163 |
$callback['name'] = $class . $access . $callback['function'][1] . '()';
|
164 |
$ref = new ReflectionMethod( $class, $callback['function'][1] );
|
165 |
|
166 |
+
} else if ( is_object( $callback['function'] ) ) {
|
167 |
|
168 |
+
if ( is_a( $callback['function'], 'Closure' ) ) {
|
169 |
+
$ref = new ReflectionFunction( $callback['function'] );
|
170 |
+
$file = trim( QM_Util::standard_dir( $ref->getFileName(), '' ), '/' );
|
171 |
+
$callback['name'] = sprintf( __( 'Closure on line %1$d of %2$s', 'query-monitor' ), $ref->getStartLine(), $file );
|
172 |
+
} else {
|
173 |
+
// the object should have a __invoke() method
|
174 |
+
$class = get_class( $callback['function'] );
|
175 |
+
$callback['name'] = $class . '->__invoke()';
|
176 |
+
$ref = new ReflectionMethod( $class, '__invoke' );
|
177 |
+
}
|
178 |
|
179 |
} else {
|
180 |
|
collectors/debug_bar.php
CHANGED
@@ -54,7 +54,7 @@ function register_qm_collectors_debug_bar() {
|
|
54 |
|
55 |
global $debug_bar;
|
56 |
|
57 |
-
if ( class_exists( 'Debug_Bar' ) ) {
|
58 |
return;
|
59 |
}
|
60 |
|
@@ -87,4 +87,52 @@ function register_qm_collectors_debug_bar() {
|
|
87 |
|
88 |
}
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
add_action( 'init', 'register_qm_collectors_debug_bar' );
|
54 |
|
55 |
global $debug_bar;
|
56 |
|
57 |
+
if ( class_exists( 'Debug_Bar' ) || qm_debug_bar_being_activated() ) {
|
58 |
return;
|
59 |
}
|
60 |
|
87 |
|
88 |
}
|
89 |
|
90 |
+
function qm_debug_bar_being_activated() {
|
91 |
+
|
92 |
+
if ( ! is_admin() ) {
|
93 |
+
|
94 |
+
return false;
|
95 |
+
|
96 |
+
}
|
97 |
+
|
98 |
+
if ( ! isset( $_REQUEST['action'] ) ) {
|
99 |
+
|
100 |
+
return false;
|
101 |
+
|
102 |
+
}
|
103 |
+
|
104 |
+
if ( isset( $_GET['action'] ) ) {
|
105 |
+
|
106 |
+
if ( ! isset( $_GET['plugin'] ) || ! isset( $_GET['_wpnonce'] ) ) {
|
107 |
+
|
108 |
+
return false;
|
109 |
+
|
110 |
+
}
|
111 |
+
|
112 |
+
if ( 'activate' === $_GET['action'] && false !== strpos( $_GET['plugin'], 'debug-bar.php' ) ) {
|
113 |
+
|
114 |
+
return true;
|
115 |
+
|
116 |
+
}
|
117 |
+
|
118 |
+
} elseif ( isset( $_POST['action'] ) ) {
|
119 |
+
|
120 |
+
if ( ! isset( $_POST['checked'] ) || ! is_array( $_POST['checked'] ) || ! isset( $_POST['_wpnonce'] ) ) {
|
121 |
+
|
122 |
+
return false;
|
123 |
+
|
124 |
+
}
|
125 |
+
|
126 |
+
if ( 'activate-selected' === $_POST['action'] && in_array( 'debug-bar/debug-bar.php', $_POST['checked'] ) ) {
|
127 |
+
|
128 |
+
return true;
|
129 |
+
|
130 |
+
}
|
131 |
+
|
132 |
+
}
|
133 |
+
|
134 |
+
return false;
|
135 |
+
|
136 |
+
}
|
137 |
+
|
138 |
add_action( 'init', 'register_qm_collectors_debug_bar' );
|
output/Html.php
CHANGED
@@ -126,13 +126,13 @@ abstract class QM_Output_Html implements QM_Output {
|
|
126 |
public static function format_url( $url ) {
|
127 |
$url = str_replace( array(
|
128 |
'=',
|
129 |
-
'&',
|
130 |
'?',
|
131 |
), array(
|
132 |
'<span class="qm-equals">=</span>',
|
133 |
'<br><span class="qm-param">&</span>',
|
134 |
'<br><span class="qm-param">?</span>',
|
135 |
-
), $url );
|
136 |
return $url;
|
137 |
|
138 |
}
|
126 |
public static function format_url( $url ) {
|
127 |
$url = str_replace( array(
|
128 |
'=',
|
129 |
+
'&',
|
130 |
'?',
|
131 |
), array(
|
132 |
'<span class="qm-equals">=</span>',
|
133 |
'<br><span class="qm-param">&</span>',
|
134 |
'<br><span class="qm-param">?</span>',
|
135 |
+
), esc_html( $url ) );
|
136 |
return $url;
|
137 |
|
138 |
}
|
query-monitor.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/*
|
3 |
Plugin Name: Query Monitor
|
4 |
Description: Monitoring of database queries, hooks, conditionals and more.
|
5 |
-
Version: 2.7.
|
6 |
Plugin URI: https://querymonitor.com/
|
7 |
Author: John Blackbourn
|
8 |
Author URI: https://johnblackbourn.com/
|
@@ -30,8 +30,8 @@ if ( defined( 'QM_DISABLED' ) and QM_DISABLED ) {
|
|
30 |
return;
|
31 |
}
|
32 |
|
33 |
-
if ( '
|
34 |
-
# For the time being, let's not load QM when using
|
35 |
# outputting collected data on the CLI. This will change in a future version of QM.
|
36 |
return;
|
37 |
}
|
2 |
/*
|
3 |
Plugin Name: Query Monitor
|
4 |
Description: Monitoring of database queries, hooks, conditionals and more.
|
5 |
+
Version: 2.7.4
|
6 |
Plugin URI: https://querymonitor.com/
|
7 |
Author: John Blackbourn
|
8 |
Author URI: https://johnblackbourn.com/
|
30 |
return;
|
31 |
}
|
32 |
|
33 |
+
if ( defined( 'WP_CLI' ) and WP_CLI ) {
|
34 |
+
# For the time being, let's not load QM when using WP-CLI because we've no persistent storage and no means of
|
35 |
# outputting collected data on the CLI. This will change in a future version of QM.
|
36 |
return;
|
37 |
}
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
Contributors: johnbillion
|
3 |
Tags: debug, debug-bar, debugging, development, developer, performance, profiler, profiling, queries, query monitor
|
4 |
Requires at least: 3.5
|
5 |
-
Tested up to: 4.
|
6 |
-
Stable tag: 2.7.
|
7 |
License: GPLv2 or later
|
8 |
|
9 |
View debugging and performance information on database queries, hooks, conditionals, HTTP requests, redirects and more.
|
@@ -142,9 +142,9 @@ On pages that have an especially high number of database queries (in the hundred
|
|
142 |
|
143 |
= Are there any add-on plugins for Query Monitor? =
|
144 |
|
145 |
-
|
146 |
|
147 |
-
|
148 |
|
149 |
= Where can I suggest a new feature or report a bug? =
|
150 |
|
@@ -156,6 +156,12 @@ No, I do not accept donations. If you like the plugin, I'd love for you to [leav
|
|
156 |
|
157 |
== Changelog ==
|
158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
= 2.7.3 =
|
160 |
* Improvements to the shutdown handler for PHP errors, so it handles syntax and compilation errors too.
|
161 |
|
2 |
Contributors: johnbillion
|
3 |
Tags: debug, debug-bar, debugging, development, developer, performance, profiler, profiling, queries, query monitor
|
4 |
Requires at least: 3.5
|
5 |
+
Tested up to: 4.3
|
6 |
+
Stable tag: 2.7.4
|
7 |
License: GPLv2 or later
|
8 |
|
9 |
View debugging and performance information on database queries, hooks, conditionals, HTTP requests, redirects and more.
|
142 |
|
143 |
= Are there any add-on plugins for Query Monitor? =
|
144 |
|
145 |
+
[A list of add-on plugins for Query Monitor can be found here.](https://github.com/johnbillion/query-monitor/wiki/Query-Monitor-Add-on-Plugins)
|
146 |
|
147 |
+
In addition, Query Monitor transparently supports add-ons for the Debug Bar plugin. If you have any Debug Bar add-ons installed, just deactivate Debug Bar and the add-ons will show up in Query Monitor's menu.
|
148 |
|
149 |
= Where can I suggest a new feature or report a bug? =
|
150 |
|
156 |
|
157 |
== Changelog ==
|
158 |
|
159 |
+
= 2.7.4 =
|
160 |
+
* An unknown component now gets marked as such, not as Core.
|
161 |
+
* Support for invokable objects in action and filter callbacks.
|
162 |
+
* Fix fatal error when activating Debug Bar plugin after Query Monitor has already been activated.
|
163 |
+
* Implement escaping inside `QM_Output_Html::format_url()` which can deal with unsafe output. Thanks to Stephen Harris for the responsible disclosure.
|
164 |
+
|
165 |
= 2.7.3 =
|
166 |
* Improvements to the shutdown handler for PHP errors, so it handles syntax and compilation errors too.
|
167 |
|
wp-content/db.php
CHANGED
@@ -29,8 +29,8 @@ if ( defined( 'QM_DISABLED' ) and QM_DISABLED ) {
|
|
29 |
return;
|
30 |
}
|
31 |
|
32 |
-
if ( '
|
33 |
-
# For the time being, let's not load QM when using
|
34 |
# outputting collected data on the CLI. This will change in a future version of QM.
|
35 |
return;
|
36 |
}
|
29 |
return;
|
30 |
}
|
31 |
|
32 |
+
if ( defined( 'WP_CLI' ) and WP_CLI ) {
|
33 |
+
# For the time being, let's not load QM when using WP-CLI because we've no persistent storage and no means of
|
34 |
# outputting collected data on the CLI. This will change in a future version of QM.
|
35 |
return;
|
36 |
}
|