Version Description
- A new Languages component for debugging languages and text domains. Thanks, @MPolleke!
- REST API debugging in the form of HTTP headers when performing an authenticated REST API request. Shows PHP errors when relevant, along with an overview of memory usage, processing time, database query number, and database query time.
- Various visual improvements, including displaying the relevant file name below stack trace functions, and a more visible stack trace expansion toggle.
- Add
is_embed()
,is_comment_feed()
, andis_user_admin()
to the list of conditional functions. - Add HHVM, SAPI, and MySQL client info to the Environment component.
- QM is now not loaded at all on the CLI.
- Avoid an issue with the CloudFlare Flexible SSL plugin.
- Improve the output of Multisite's
$current_blog
and$current_site
in the Request component. - Fully handle Windows paths when detecting a file component.
- Don't display the symlink warning when using a secondary instance of WPDB.
- Whole bunch of internal structure refactoring, escaping, and other misc tweaks.
Download this release
Release Info
Developer | johnbillion |
Plugin | Query Monitor |
Version | 2.8.0 |
Comparing to | |
See all releases |
Code changes from version 2.7.4 to 2.8.0
- assets/query-monitor.css +10 -4
- assets/query-monitor.js +3 -3
- classes/Collectors.php +12 -0
- classes/Dispatcher.php +44 -5
- classes/Output.php +16 -4
- classes/Plugin.php +16 -8
- classes/Util.php +33 -25
- collectors/conditionals.php +39 -5
- collectors/debug_bar.php +1 -1
- collectors/environment.php +38 -11
- collectors/hooks.php +0 -3
- collectors/languages.php +88 -0
- collectors/request.php +17 -13
- collectors/theme.php +24 -15
- composer.json +12 -1
- dispatchers/{Headers.php → AJAX.php} +46 -10
- dispatchers/Html.php +66 -21
- dispatchers/REST.php +85 -0
- dispatchers/Redirect.php +94 -0
- output/Headers.php +13 -3
- output/Html.php +77 -31
- output/headers/overview.php +56 -0
- output/headers/php_errors.php +8 -13
- output/headers/redirects.php +5 -5
- output/html/admin.php +7 -6
- output/html/assets.php +18 -18
- output/html/conditionals.php +6 -6
- output/html/db_callers.php +18 -12
- output/html/db_components.php +18 -13
- output/html/db_queries.php +116 -57
- output/html/debug_bar.php +1 -1
- output/html/environment.php +70 -52
- output/html/hooks.php +35 -52
- output/html/http.php +90 -39
- output/html/languages.php +105 -0
- output/html/overview.php +32 -16
- output/html/php_errors.php +36 -24
- output/html/request.php +47 -37
- output/html/theme.php +19 -12
- output/html/transients.php +55 -23
- query-monitor.php +15 -99
- readme.txt +42 -22
- wp-content/db.php +3 -3
assets/query-monitor.css
CHANGED
@@ -192,7 +192,7 @@ body.wp-admin.folded #qm {
|
|
192 |
}
|
193 |
|
194 |
.qm table {
|
195 |
-
color: #
|
196 |
border-collapse: collapse !important;
|
197 |
box-shadow: none !important;
|
198 |
width: 100% !important;
|
@@ -215,6 +215,7 @@ body.wp-admin.folded #qm {
|
|
215 |
vertical-align: top !important;
|
216 |
text-shadow: none !important;
|
217 |
text-transform: none !important;
|
|
|
218 |
}
|
219 |
|
220 |
.qm .qm-totally-legit-spacer td {
|
@@ -264,7 +265,7 @@ body.wp-admin.folded #qm {
|
|
264 |
border-collapse: collapse !important;
|
265 |
margin: 0 !important;
|
266 |
background: #fff !important;
|
267 |
-
color: #
|
268 |
border-style: hidden !important;
|
269 |
width: 100% !important;
|
270 |
}
|
@@ -367,8 +368,13 @@ body.wp-admin.folded #qm {
|
|
367 |
|
368 |
.qm a.qm-toggle {
|
369 |
color: #bbb !important;
|
370 |
-
padding:
|
371 |
-
border: 1px solid
|
|
|
|
|
|
|
|
|
|
|
372 |
}
|
373 |
|
374 |
.qm a.qm-toggle:focus,
|
192 |
}
|
193 |
|
194 |
.qm table {
|
195 |
+
color: #444 !important;
|
196 |
border-collapse: collapse !important;
|
197 |
box-shadow: none !important;
|
198 |
width: 100% !important;
|
215 |
vertical-align: top !important;
|
216 |
text-shadow: none !important;
|
217 |
text-transform: none !important;
|
218 |
+
position: relative !important;
|
219 |
}
|
220 |
|
221 |
.qm .qm-totally-legit-spacer td {
|
265 |
border-collapse: collapse !important;
|
266 |
margin: 0 !important;
|
267 |
background: #fff !important;
|
268 |
+
color: #444 !important;
|
269 |
border-style: hidden !important;
|
270 |
width: 100% !important;
|
271 |
}
|
368 |
|
369 |
.qm a.qm-toggle {
|
370 |
color: #bbb !important;
|
371 |
+
padding: 2px 7px !important;
|
372 |
+
border-left: 1px solid #e1e1e1 !important;
|
373 |
+
border-bottom: 1px solid #e1e1e1 !important;
|
374 |
+
position: absolute !important;
|
375 |
+
top: 0 !important;
|
376 |
+
right: 0 !important;
|
377 |
+
background: #fff !important;
|
378 |
}
|
379 |
|
380 |
.qm a.qm-toggle:focus,
|
assets/query-monitor.js
CHANGED
@@ -150,7 +150,7 @@ jQuery( function($) {
|
|
150 |
|
151 |
$('#qm').find('.qm-toggle').on('click',function(e){
|
152 |
var el = $(this);
|
153 |
-
$(this).closest('td').find('.qm-toggled').
|
154 |
if ( el.attr('data-off') == el.text() )
|
155 |
el.text(el.attr('data-on'));
|
156 |
else
|
@@ -183,7 +183,7 @@ jQuery( function($) {
|
|
183 |
|
184 |
$( document ).ajaxSuccess( function( event, response, options ) {
|
185 |
|
186 |
-
var errors = response.getResponseHeader( 'X-QM-
|
187 |
|
188 |
if ( !errors )
|
189 |
return event;
|
@@ -192,7 +192,7 @@ jQuery( function($) {
|
|
192 |
|
193 |
for ( var key = 1; key <= errors; key++ ) {
|
194 |
|
195 |
-
error = $.parseJSON( response.getResponseHeader( 'X-QM-
|
196 |
|
197 |
if ( window.console ) {
|
198 |
console.debug( '=== ' + qm_l10n.ajax_error + ' ===' );
|
150 |
|
151 |
$('#qm').find('.qm-toggle').on('click',function(e){
|
152 |
var el = $(this);
|
153 |
+
$(this).closest('td').find('.qm-toggled').slideToggle(100,function(){
|
154 |
if ( el.attr('data-off') == el.text() )
|
155 |
el.text(el.attr('data-on'));
|
156 |
else
|
183 |
|
184 |
$( document ).ajaxSuccess( function( event, response, options ) {
|
185 |
|
186 |
+
var errors = response.getResponseHeader( 'X-QM-error-count' );
|
187 |
|
188 |
if ( !errors )
|
189 |
return event;
|
192 |
|
193 |
for ( var key = 1; key <= errors; key++ ) {
|
194 |
|
195 |
+
error = $.parseJSON( response.getResponseHeader( 'X-QM-error-' + key ) );
|
196 |
|
197 |
if ( window.console ) {
|
198 |
console.debug( '=== ' + qm_l10n.ajax_error + ' ===' );
|
classes/Collectors.php
CHANGED
@@ -18,6 +18,7 @@ if ( ! class_exists( 'QM_Collectors' ) ) {
|
|
18 |
class QM_Collectors implements IteratorAggregate {
|
19 |
|
20 |
private $items = array();
|
|
|
21 |
|
22 |
public function getIterator() {
|
23 |
return new ArrayIterator( $this->items );
|
@@ -47,5 +48,16 @@ class QM_Collectors implements IteratorAggregate {
|
|
47 |
|
48 |
}
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
}
|
18 |
class QM_Collectors implements IteratorAggregate {
|
19 |
|
20 |
private $items = array();
|
21 |
+
private $processed = false;
|
22 |
|
23 |
public function getIterator() {
|
24 |
return new ArrayIterator( $this->items );
|
48 |
|
49 |
}
|
50 |
|
51 |
+
public function process() {
|
52 |
+
if ( $this->processed ) {
|
53 |
+
return;
|
54 |
+
}
|
55 |
+
foreach ( $this as $collector ) {
|
56 |
+
$collector->tear_down();
|
57 |
+
$collector->process();
|
58 |
+
}
|
59 |
+
$this->processed = true;
|
60 |
+
}
|
61 |
+
|
62 |
}
|
63 |
}
|
classes/Dispatcher.php
CHANGED
@@ -24,19 +24,58 @@ abstract class QM_Dispatcher {
|
|
24 |
define( 'QM_COOKIE', 'query_monitor_' . COOKIEHASH );
|
25 |
}
|
26 |
|
|
|
|
|
27 |
}
|
28 |
|
29 |
abstract public function is_active();
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
public function init() {
|
|
|
32 |
// nothing
|
33 |
}
|
34 |
|
35 |
-
|
36 |
// nothing
|
37 |
}
|
38 |
|
39 |
-
|
40 |
// nothing
|
41 |
}
|
42 |
|
@@ -50,13 +89,13 @@ abstract class QM_Dispatcher {
|
|
50 |
return true;
|
51 |
}
|
52 |
|
53 |
-
return
|
54 |
|
55 |
}
|
56 |
|
57 |
-
public function user_verified() {
|
58 |
if ( isset( $_COOKIE[QM_COOKIE] ) ) {
|
59 |
-
return
|
60 |
}
|
61 |
return false;
|
62 |
}
|
24 |
define( 'QM_COOKIE', 'query_monitor_' . COOKIEHASH );
|
25 |
}
|
26 |
|
27 |
+
add_action( 'init', array( $this, 'init' ) );
|
28 |
+
|
29 |
}
|
30 |
|
31 |
abstract public function is_active();
|
32 |
|
33 |
+
final public function should_dispatch() {
|
34 |
+
|
35 |
+
$e = error_get_last();
|
36 |
+
|
37 |
+
# Don't dispatch if a fatal has occurred:
|
38 |
+
if ( ! empty( $e ) and ( $e['type'] & ( E_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR ) ) ) {
|
39 |
+
return false;
|
40 |
+
}
|
41 |
+
|
42 |
+
# Allow users to disable this dispatcher
|
43 |
+
if ( ! apply_filters( "qm/dispatch/{$this->id}", true ) ) {
|
44 |
+
return false;
|
45 |
+
}
|
46 |
+
|
47 |
+
return $this->is_active();
|
48 |
+
|
49 |
+
}
|
50 |
+
|
51 |
+
public function get_outputters( $outputter_id ) {
|
52 |
+
|
53 |
+
$out = array();
|
54 |
+
|
55 |
+
$collectors = QM_Collectors::init();
|
56 |
+
$collectors->process();
|
57 |
+
|
58 |
+
$this->outputters = apply_filters( "qm/outputter/{$outputter_id}", array(), $collectors );
|
59 |
+
|
60 |
+
/* @var QM_Output[] */
|
61 |
+
foreach ( $this->outputters as $id => $outputter ) {
|
62 |
+
$out[ $id ] = $outputter;
|
63 |
+
}
|
64 |
+
|
65 |
+
return $out;
|
66 |
+
|
67 |
+
}
|
68 |
+
|
69 |
public function init() {
|
70 |
+
// @TODO should be abstract?
|
71 |
// nothing
|
72 |
}
|
73 |
|
74 |
+
protected function before_output() {
|
75 |
// nothing
|
76 |
}
|
77 |
|
78 |
+
protected function after_output() {
|
79 |
// nothing
|
80 |
}
|
81 |
|
89 |
return true;
|
90 |
}
|
91 |
|
92 |
+
return self::user_verified();
|
93 |
|
94 |
}
|
95 |
|
96 |
+
public static function user_verified() {
|
97 |
if ( isset( $_COOKIE[QM_COOKIE] ) ) {
|
98 |
+
return self::verify_cookie( stripslashes( $_COOKIE[QM_COOKIE] ) );
|
99 |
}
|
100 |
return false;
|
101 |
}
|
classes/Output.php
CHANGED
@@ -14,12 +14,24 @@ GNU General Public License for more details.
|
|
14 |
|
15 |
*/
|
16 |
|
17 |
-
if ( !
|
18 |
-
|
19 |
|
20 |
-
|
21 |
|
22 |
-
public function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
}
|
25 |
}
|
14 |
|
15 |
*/
|
16 |
|
17 |
+
if ( ! class_exists( 'QM_Output' ) ) {
|
18 |
+
abstract class QM_Output {
|
19 |
|
20 |
+
protected $collector;
|
21 |
|
22 |
+
public function __construct( QM_Collector $collector ) {
|
23 |
+
$this->collector = $collector;
|
24 |
+
}
|
25 |
+
|
26 |
+
abstract public function get_output();
|
27 |
+
|
28 |
+
public function output() {
|
29 |
+
// nothing
|
30 |
+
}
|
31 |
+
|
32 |
+
public function get_collector() {
|
33 |
+
return $this->collector;
|
34 |
+
}
|
35 |
|
36 |
}
|
37 |
}
|
classes/Plugin.php
CHANGED
@@ -17,6 +17,8 @@ GNU General Public License for more details.
|
|
17 |
if ( ! class_exists( 'QM_Plugin' ) ) {
|
18 |
abstract class QM_Plugin {
|
19 |
|
|
|
|
|
20 |
/**
|
21 |
* Class constructor
|
22 |
*
|
@@ -74,15 +76,21 @@ abstract class QM_Plugin {
|
|
74 |
*
|
75 |
* @author John Blackbourn
|
76 |
**/
|
77 |
-
final
|
78 |
-
if ( !
|
79 |
-
$
|
80 |
-
'url'
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
}
|
85 |
-
return $this->plugin[$item] . ltrim( $file, '/' );
|
86 |
}
|
87 |
|
88 |
}
|
17 |
if ( ! class_exists( 'QM_Plugin' ) ) {
|
18 |
abstract class QM_Plugin {
|
19 |
|
20 |
+
private $plugin = array();
|
21 |
+
|
22 |
/**
|
23 |
* Class constructor
|
24 |
*
|
76 |
*
|
77 |
* @author John Blackbourn
|
78 |
**/
|
79 |
+
final private function _plugin( $item, $file = '' ) {
|
80 |
+
if ( ! array_key_exists( $item, $this->plugin ) ) {
|
81 |
+
switch ( $item ) {
|
82 |
+
case 'url':
|
83 |
+
$this->plugin[ $item ] = plugin_dir_url( $this->file );
|
84 |
+
break;
|
85 |
+
case 'path':
|
86 |
+
$this->plugin[ $item ] = plugin_dir_path( $this->file );
|
87 |
+
break;
|
88 |
+
case 'base':
|
89 |
+
$this->plugin[ $item ] = plugin_basename( $this->file );
|
90 |
+
break;
|
91 |
+
}
|
92 |
}
|
93 |
+
return $this->plugin[ $item ] . ltrim( $file, '/' );
|
94 |
}
|
95 |
|
96 |
}
|
classes/Util.php
CHANGED
@@ -78,6 +78,8 @@ class QM_Util {
|
|
78 |
|
79 |
# @TODO turn this into a class (eg QM_File_Component)
|
80 |
|
|
|
|
|
81 |
if ( isset( self::$file_components[$file] ) ) {
|
82 |
return self::$file_components[$file];
|
83 |
}
|
@@ -167,7 +169,7 @@ class QM_Util {
|
|
167 |
|
168 |
if ( is_a( $callback['function'], 'Closure' ) ) {
|
169 |
$ref = new ReflectionFunction( $callback['function'] );
|
170 |
-
$file =
|
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
|
@@ -186,16 +188,26 @@ class QM_Util {
|
|
186 |
$callback['file'] = $ref->getFileName();
|
187 |
$callback['line'] = $ref->getStartLine();
|
188 |
|
189 |
-
|
|
|
|
|
|
|
190 |
if ( preg_match( '|(?P<file>.*)\((?P<line>[0-9]+)\)|', $callback['file'], $matches ) ) {
|
191 |
$callback['file'] = $matches['file'];
|
192 |
$callback['line'] = $matches['line'];
|
193 |
$file = trim( QM_Util::standard_dir( $callback['file'], '' ), '/' );
|
194 |
$callback['name'] = sprintf( __( 'Anonymous function on line %1$d of %2$s', 'query-monitor' ), $callback['line'], $file );
|
|
|
|
|
|
|
|
|
|
|
195 |
}
|
196 |
}
|
197 |
|
198 |
-
|
|
|
|
|
199 |
|
200 |
} catch ( ReflectionException $e ) {
|
201 |
|
@@ -236,31 +248,13 @@ class QM_Util {
|
|
236 |
return ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
237 |
}
|
238 |
|
239 |
-
public static function include_files( $path ) {
|
240 |
-
|
241 |
-
if ( class_exists( 'DirectoryIterator' ) and method_exists( 'DirectoryIterator', 'getExtension' ) ) {
|
242 |
-
|
243 |
-
$output_iterator = new DirectoryIterator( $path );
|
244 |
-
|
245 |
-
foreach ( $output_iterator as $output ) {
|
246 |
-
if ( $output->getExtension() === 'php' ) {
|
247 |
-
include $output->getPathname();
|
248 |
-
}
|
249 |
-
}
|
250 |
-
|
251 |
-
} else {
|
252 |
-
|
253 |
-
foreach ( glob( sprintf( '%s/*.php', $path ) ) as $file ) {
|
254 |
-
include $file;
|
255 |
-
}
|
256 |
-
|
257 |
-
}
|
258 |
-
|
259 |
-
}
|
260 |
-
|
261 |
public static function is_multi_network() {
|
262 |
global $wpdb;
|
263 |
|
|
|
|
|
|
|
|
|
264 |
if ( ! is_multisite() ) {
|
265 |
return false;
|
266 |
}
|
@@ -273,5 +267,19 @@ class QM_Util {
|
|
273 |
return ( $num_sites > 1 );
|
274 |
}
|
275 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
276 |
}
|
277 |
}
|
78 |
|
79 |
# @TODO turn this into a class (eg QM_File_Component)
|
80 |
|
81 |
+
$file = self::standard_dir( $file );
|
82 |
+
|
83 |
if ( isset( self::$file_components[$file] ) ) {
|
84 |
return self::$file_components[$file];
|
85 |
}
|
169 |
|
170 |
if ( is_a( $callback['function'], 'Closure' ) ) {
|
171 |
$ref = new ReflectionFunction( $callback['function'] );
|
172 |
+
$file = QM_Util::standard_dir( $ref->getFileName(), '' );
|
173 |
$callback['name'] = sprintf( __( 'Closure on line %1$d of %2$s', 'query-monitor' ), $ref->getStartLine(), $file );
|
174 |
} else {
|
175 |
// the object should have a __invoke() method
|
188 |
$callback['file'] = $ref->getFileName();
|
189 |
$callback['line'] = $ref->getStartLine();
|
190 |
|
191 |
+
// https://github.com/facebook/hhvm/issues/5856
|
192 |
+
$name = trim( $ref->getName() );
|
193 |
+
|
194 |
+
if ( '__lambda_func' === $name || 0 === strpos( $name, 'lambda_' ) ) {
|
195 |
if ( preg_match( '|(?P<file>.*)\((?P<line>[0-9]+)\)|', $callback['file'], $matches ) ) {
|
196 |
$callback['file'] = $matches['file'];
|
197 |
$callback['line'] = $matches['line'];
|
198 |
$file = trim( QM_Util::standard_dir( $callback['file'], '' ), '/' );
|
199 |
$callback['name'] = sprintf( __( 'Anonymous function on line %1$d of %2$s', 'query-monitor' ), $callback['line'], $file );
|
200 |
+
} else {
|
201 |
+
// https://github.com/facebook/hhvm/issues/5807
|
202 |
+
unset( $callback['line'], $callback['file'] );
|
203 |
+
$callback['name'] = $name . '()';
|
204 |
+
$callback['error'] = new WP_Error( 'unknown_lambda', __( 'Unable to determine source of lambda function', 'query-monitor' ) );
|
205 |
}
|
206 |
}
|
207 |
|
208 |
+
if ( ! empty( $callback['file'] ) ) {
|
209 |
+
$callback['component'] = self::get_file_component( $callback['file'] );
|
210 |
+
}
|
211 |
|
212 |
} catch ( ReflectionException $e ) {
|
213 |
|
248 |
return ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
249 |
}
|
250 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
public static function is_multi_network() {
|
252 |
global $wpdb;
|
253 |
|
254 |
+
if ( function_exists( 'is_multi_network' ) ) {
|
255 |
+
return is_multi_network();
|
256 |
+
}
|
257 |
+
|
258 |
if ( ! is_multisite() ) {
|
259 |
return false;
|
260 |
}
|
267 |
return ( $num_sites > 1 );
|
268 |
}
|
269 |
|
270 |
+
public static function get_client_version( $client ) {
|
271 |
+
|
272 |
+
$client = intval( $client );
|
273 |
+
|
274 |
+
$hello = $client % 10000;
|
275 |
+
|
276 |
+
$major = intval( floor( $client / 10000 ) );
|
277 |
+
$minor = intval( floor( $hello / 100 ) );
|
278 |
+
$patch = intval( $hello % 100 );
|
279 |
+
|
280 |
+
return compact( 'major', 'minor', 'patch' );
|
281 |
+
|
282 |
+
}
|
283 |
+
|
284 |
}
|
285 |
}
|
collectors/conditionals.php
CHANGED
@@ -25,11 +25,45 @@ class QM_Collector_Conditionals extends QM_Collector {
|
|
25 |
public function process() {
|
26 |
|
27 |
$conds = apply_filters( 'qm/collect/conditionals', array(
|
28 |
-
'is_404',
|
29 |
-
'
|
30 |
-
'
|
31 |
-
'
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
$conds = apply_filters( 'query_monitor_conditionals', $conds );
|
34 |
|
35 |
$true = $false = $na = array();
|
25 |
public function process() {
|
26 |
|
27 |
$conds = apply_filters( 'qm/collect/conditionals', array(
|
28 |
+
'is_404',
|
29 |
+
'is_admin',
|
30 |
+
'is_archive',
|
31 |
+
'is_attachment',
|
32 |
+
'is_author',
|
33 |
+
'is_blog_admin',
|
34 |
+
'is_category',
|
35 |
+
'is_comment_feed',
|
36 |
+
'is_comments_popup',
|
37 |
+
'is_customize_preview',
|
38 |
+
'is_date',
|
39 |
+
'is_day',
|
40 |
+
'is_embed',
|
41 |
+
'is_feed',
|
42 |
+
'is_front_page',
|
43 |
+
'is_home',
|
44 |
+
'is_main_network',
|
45 |
+
'is_main_site',
|
46 |
+
'is_month',
|
47 |
+
'is_network_admin',
|
48 |
+
'is_page',
|
49 |
+
'is_page_template',
|
50 |
+
'is_paged',
|
51 |
+
'is_post_type_archive',
|
52 |
+
'is_preview',
|
53 |
+
'is_robots',
|
54 |
+
'is_rtl',
|
55 |
+
'is_search',
|
56 |
+
'is_single',
|
57 |
+
'is_singular',
|
58 |
+
'is_ssl',
|
59 |
+
'is_sticky',
|
60 |
+
'is_tag',
|
61 |
+
'is_tax',
|
62 |
+
'is_time',
|
63 |
+
'is_trackback',
|
64 |
+
'is_user_admin',
|
65 |
+
'is_year',
|
66 |
+
) );
|
67 |
$conds = apply_filters( 'query_monitor_conditionals', $conds );
|
68 |
|
69 |
$true = $false = $na = array();
|
collectors/debug_bar.php
CHANGED
@@ -25,7 +25,7 @@ final class QM_Collector_Debug_Bar extends QM_Collector {
|
|
25 |
|
26 |
public function name() {
|
27 |
$title = $this->get_panel()->title();
|
28 |
-
return sprintf( 'Debug Bar: %s', $title );
|
29 |
}
|
30 |
|
31 |
public function set_panel( Debug_Bar_Panel $panel ) {
|
25 |
|
26 |
public function name() {
|
27 |
$title = $this->get_panel()->title();
|
28 |
+
return sprintf( __( 'Debug Bar: %s', 'query-monitor' ), $title );
|
29 |
}
|
30 |
|
31 |
public function set_panel( Debug_Bar_Panel $panel ) {
|
collectors/environment.php
CHANGED
@@ -109,28 +109,50 @@ class QM_Collector_Environment extends QM_Collector {
|
|
109 |
" );
|
110 |
|
111 |
if ( is_resource( $db->dbh ) ) {
|
112 |
-
#
|
113 |
-
$
|
114 |
} else if ( is_object( $db->dbh ) ) {
|
115 |
# mysqli or PDO
|
116 |
-
$
|
117 |
} else {
|
118 |
# Who knows?
|
119 |
-
$
|
120 |
}
|
121 |
|
122 |
if ( method_exists( $db, 'db_version' ) ) {
|
123 |
-
$
|
124 |
} else {
|
125 |
-
$
|
126 |
}
|
127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
$this->data['db'][$id] = array(
|
129 |
-
'
|
130 |
-
'driver' => $driver,
|
131 |
-
'user' => $db->dbuser,
|
132 |
-
'host' => $db->dbhost,
|
133 |
-
'name' => $db->dbname,
|
134 |
'vars' => $mysql_vars,
|
135 |
'variables' => $variables
|
136 |
);
|
@@ -140,8 +162,13 @@ class QM_Collector_Environment extends QM_Collector {
|
|
140 |
}
|
141 |
|
142 |
$this->data['php']['version'] = phpversion();
|
|
|
143 |
$this->data['php']['user'] = self::get_current_user();
|
144 |
|
|
|
|
|
|
|
|
|
145 |
foreach ( $this->php_vars as $setting ) {
|
146 |
$this->data['php']['variables'][$setting]['after'] = ini_get( $setting );
|
147 |
}
|
109 |
" );
|
110 |
|
111 |
if ( is_resource( $db->dbh ) ) {
|
112 |
+
# Old mysql extension
|
113 |
+
$extension = 'mysql';
|
114 |
} else if ( is_object( $db->dbh ) ) {
|
115 |
# mysqli or PDO
|
116 |
+
$extension = get_class( $db->dbh );
|
117 |
} else {
|
118 |
# Who knows?
|
119 |
+
$extension = null;
|
120 |
}
|
121 |
|
122 |
if ( method_exists( $db, 'db_version' ) ) {
|
123 |
+
$server = $db->db_version();
|
124 |
} else {
|
125 |
+
$server = null;
|
126 |
}
|
127 |
|
128 |
+
if ( isset( $db->use_mysqli ) && $db->use_mysqli ) {
|
129 |
+
$client = mysqli_get_client_version( $db->dbh );
|
130 |
+
} else {
|
131 |
+
if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) {
|
132 |
+
$client = $matches[0];
|
133 |
+
} else {
|
134 |
+
$client = null;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
if ( $client ) {
|
139 |
+
$client_version = implode( '.', QM_Util::get_client_version( $client ) );
|
140 |
+
$client_version = sprintf( '%s (%s)', $client, $client_version );
|
141 |
+
} else {
|
142 |
+
$client_version = null;
|
143 |
+
}
|
144 |
+
|
145 |
+
$info = array(
|
146 |
+
'extension' => $extension,
|
147 |
+
'server version' => $server,
|
148 |
+
'client version' => $client_version,
|
149 |
+
'user' => $db->dbuser,
|
150 |
+
'host' => $db->dbhost,
|
151 |
+
'database' => $db->dbname,
|
152 |
+
);
|
153 |
+
|
154 |
$this->data['db'][$id] = array(
|
155 |
+
'info' => $info,
|
|
|
|
|
|
|
|
|
156 |
'vars' => $mysql_vars,
|
157 |
'variables' => $variables
|
158 |
);
|
162 |
}
|
163 |
|
164 |
$this->data['php']['version'] = phpversion();
|
165 |
+
$this->data['php']['sapi'] = php_sapi_name();
|
166 |
$this->data['php']['user'] = self::get_current_user();
|
167 |
|
168 |
+
if ( defined( 'HHVM_VERSION' ) ) {
|
169 |
+
$this->data['php']['hhvm'] = HHVM_VERSION;
|
170 |
+
}
|
171 |
+
|
172 |
foreach ( $this->php_vars as $setting ) {
|
173 |
$this->data['php']['variables'][$setting]['after'] = ini_get( $setting );
|
174 |
}
|
collectors/hooks.php
CHANGED
@@ -37,10 +37,7 @@ class QM_Collector_Hooks extends QM_Collector {
|
|
37 |
$hooks = $all_parts = $components = array();
|
38 |
|
39 |
if ( has_filter( 'all' ) ) {
|
40 |
-
|
41 |
$hooks['all'] = $this->process_action( 'all', $wp_filter );
|
42 |
-
$this->data['warnings']['all_hooked'] = $hooks['all'];
|
43 |
-
|
44 |
}
|
45 |
|
46 |
foreach ( $wp_actions as $name => $count ) {
|
37 |
$hooks = $all_parts = $components = array();
|
38 |
|
39 |
if ( has_filter( 'all' ) ) {
|
|
|
40 |
$hooks['all'] = $this->process_action( 'all', $wp_filter );
|
|
|
|
|
41 |
}
|
42 |
|
43 |
foreach ( $wp_actions as $name => $count ) {
|
collectors/languages.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Copyright 2009-2015 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_Languages extends QM_Collector {
|
18 |
+
|
19 |
+
public $id = 'languages';
|
20 |
+
|
21 |
+
public function name() {
|
22 |
+
return __( 'Languages', 'query-monitor' );
|
23 |
+
}
|
24 |
+
|
25 |
+
public function __construct() {
|
26 |
+
|
27 |
+
parent::__construct();
|
28 |
+
|
29 |
+
add_filter( 'override_load_textdomain', array( $this, 'log_file_load' ), 99, 3 );
|
30 |
+
|
31 |
+
}
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Store log data.
|
36 |
+
*
|
37 |
+
* @param bool $override Whether to override the text domain. Default false.
|
38 |
+
* @param string $domain Text domain. Unique identifier for retrieving translated strings.
|
39 |
+
* @param string $mofile Path to the MO file.
|
40 |
+
* @return bool
|
41 |
+
*/
|
42 |
+
public function log_file_load( $override, $domain, $mofile ) {
|
43 |
+
|
44 |
+
$trace = new QM_Backtrace;
|
45 |
+
$filtered = $trace->get_filtered_trace();
|
46 |
+
$caller = array();
|
47 |
+
|
48 |
+
foreach ( $filtered as $i => $item ) {
|
49 |
+
|
50 |
+
if ( in_array( $item['function'], array(
|
51 |
+
'load_plugin_textdomain',
|
52 |
+
'load_theme_textdomain',
|
53 |
+
'load_default_textdomain',
|
54 |
+
), true ) ) {
|
55 |
+
$caller = $item;
|
56 |
+
$display = $i + 1;
|
57 |
+
if ( isset( $filtered[ $display ] ) ) {
|
58 |
+
$caller['display'] = $filtered[ $display ]['display'];
|
59 |
+
}
|
60 |
+
break;
|
61 |
+
}
|
62 |
+
|
63 |
+
}
|
64 |
+
|
65 |
+
if ( empty( $caller ) ) {
|
66 |
+
$caller = $filtered[1];
|
67 |
+
}
|
68 |
+
|
69 |
+
$this->data['languages'][] = array(
|
70 |
+
'caller' => $caller,
|
71 |
+
'domain' => $domain,
|
72 |
+
'mofile' => $mofile,
|
73 |
+
'found' => file_exists( $mofile ) ? filesize( $mofile ): false,
|
74 |
+
);
|
75 |
+
|
76 |
+
return $override;
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
}
|
82 |
+
|
83 |
+
function register_qm_collector_languages( array $collectors, QueryMonitor $qm ) {
|
84 |
+
$collectors['languages'] = new QM_Collector_Languages;
|
85 |
+
return $collectors;
|
86 |
+
}
|
87 |
+
|
88 |
+
add_filter( 'qm/collectors', 'register_qm_collector_languages', 21, 2 );
|
collectors/request.php
CHANGED
@@ -29,11 +29,17 @@ class QM_Collector_Request extends QM_Collector {
|
|
29 |
$qo = get_queried_object();
|
30 |
|
31 |
if ( is_multisite() ) {
|
32 |
-
$this->data['multisite']['current_blog'] =
|
|
|
|
|
|
|
33 |
}
|
34 |
|
35 |
if ( QM_Util::is_multi_network() ) {
|
36 |
-
$this->data['multisite']['current_site'] =
|
|
|
|
|
|
|
37 |
}
|
38 |
|
39 |
if ( is_admin() ) {
|
@@ -88,8 +94,7 @@ class QM_Collector_Request extends QM_Collector {
|
|
88 |
|
89 |
case is_a( $qo, 'WP_Post' ):
|
90 |
// Single post
|
91 |
-
$this->data['
|
92 |
-
$this->data['queried_object_title'] = sprintf( __( 'Single %s: #%d', 'query-monitor' ),
|
93 |
get_post_type_object( $qo->post_type )->labels->singular_name,
|
94 |
$qo->ID
|
95 |
);
|
@@ -97,37 +102,36 @@ class QM_Collector_Request extends QM_Collector {
|
|
97 |
|
98 |
case is_a( $qo, 'WP_User' ):
|
99 |
// Author archive
|
100 |
-
$this->data['
|
101 |
-
$this->data['queried_object_title'] = sprintf( __( 'Author archive: %s', 'query-monitor' ),
|
102 |
$qo->user_nicename
|
103 |
);
|
104 |
break;
|
105 |
|
|
|
106 |
case property_exists( $qo, 'term_id' ):
|
107 |
// Term archive
|
108 |
-
$this->data['
|
109 |
-
$this->data['queried_object_title'] = sprintf( __( 'Term archive: %s', 'query-monitor' ),
|
110 |
$qo->slug
|
111 |
);
|
112 |
break;
|
113 |
|
114 |
case property_exists( $qo, 'has_archive' ):
|
115 |
// Post type archive
|
116 |
-
$this->data['
|
117 |
-
$this->data['queried_object_title'] = sprintf( __( 'Post type archive: %s', 'query-monitor' ),
|
118 |
$qo->name
|
119 |
);
|
120 |
break;
|
121 |
|
122 |
default:
|
123 |
// Unknown, but we have a queried object
|
124 |
-
$this->data['
|
125 |
-
$this->data['queried_object_title'] = __( 'Unknown queried object', 'query-monitor' );
|
126 |
break;
|
127 |
|
128 |
}
|
129 |
|
130 |
-
|
|
|
|
|
131 |
|
132 |
}
|
133 |
|
29 |
$qo = get_queried_object();
|
30 |
|
31 |
if ( is_multisite() ) {
|
32 |
+
$this->data['multisite']['current_blog'] = array(
|
33 |
+
'title' => sprintf( 'Current blog: #%d', $current_blog->blog_id ),
|
34 |
+
'data' => $current_blog,
|
35 |
+
);
|
36 |
}
|
37 |
|
38 |
if ( QM_Util::is_multi_network() ) {
|
39 |
+
$this->data['multisite']['current_site'] = array(
|
40 |
+
'title' => sprintf( 'Current site: #%d', $current_site->id ),
|
41 |
+
'data' => $current_site,
|
42 |
+
);
|
43 |
}
|
44 |
|
45 |
if ( is_admin() ) {
|
94 |
|
95 |
case is_a( $qo, 'WP_Post' ):
|
96 |
// Single post
|
97 |
+
$this->data['queried_object']['title'] = sprintf( __( 'Single %s: #%d', 'query-monitor' ),
|
|
|
98 |
get_post_type_object( $qo->post_type )->labels->singular_name,
|
99 |
$qo->ID
|
100 |
);
|
102 |
|
103 |
case is_a( $qo, 'WP_User' ):
|
104 |
// Author archive
|
105 |
+
$this->data['queried_object']['title'] = sprintf( __( 'Author archive: %s', 'query-monitor' ),
|
|
|
106 |
$qo->user_nicename
|
107 |
);
|
108 |
break;
|
109 |
|
110 |
+
case is_a( $qo, 'WP_Term' ):
|
111 |
case property_exists( $qo, 'term_id' ):
|
112 |
// Term archive
|
113 |
+
$this->data['queried_object']['title'] = sprintf( __( 'Term archive: %s', 'query-monitor' ),
|
|
|
114 |
$qo->slug
|
115 |
);
|
116 |
break;
|
117 |
|
118 |
case property_exists( $qo, 'has_archive' ):
|
119 |
// Post type archive
|
120 |
+
$this->data['queried_object']['title'] = sprintf( __( 'Post type archive: %s', 'query-monitor' ),
|
|
|
121 |
$qo->name
|
122 |
);
|
123 |
break;
|
124 |
|
125 |
default:
|
126 |
// Unknown, but we have a queried object
|
127 |
+
$this->data['queried_object']['title'] = __( 'Unknown queried object', 'query-monitor' );
|
|
|
128 |
break;
|
129 |
|
130 |
}
|
131 |
|
132 |
+
if ( ! is_null( $qo ) ) {
|
133 |
+
$this->data['queried_object']['data'] = $qo;
|
134 |
+
}
|
135 |
|
136 |
}
|
137 |
|
collectors/theme.php
CHANGED
@@ -24,7 +24,8 @@ class QM_Collector_Theme extends QM_Collector {
|
|
24 |
|
25 |
public function __construct() {
|
26 |
parent::__construct();
|
27 |
-
add_filter( 'body_class',
|
|
|
28 |
}
|
29 |
|
30 |
public function filter_body_class( $class ) {
|
@@ -32,25 +33,33 @@ class QM_Collector_Theme extends QM_Collector {
|
|
32 |
return $class;
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
35 |
public function process() {
|
36 |
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
48 |
|
49 |
-
$this->data['
|
50 |
-
$this->data['
|
51 |
-
$this->data['theme_template'] = $theme_template;
|
52 |
-
$this->data['stylesheet'] = get_stylesheet();
|
53 |
-
$this->data['template'] = get_template();
|
54 |
|
55 |
if ( isset( $this->data['body_class'] ) ) {
|
56 |
asort( $this->data['body_class'] );
|
24 |
|
25 |
public function __construct() {
|
26 |
parent::__construct();
|
27 |
+
add_filter( 'body_class', array( $this, 'filter_body_class' ), 999 );
|
28 |
+
add_filter( 'template_include', array( $this, 'filter_template_include' ), 999 );
|
29 |
}
|
30 |
|
31 |
public function filter_body_class( $class ) {
|
33 |
return $class;
|
34 |
}
|
35 |
|
36 |
+
public function filter_template_include( $template_path ) {
|
37 |
+
$this->data['template_path'] = $template_path;
|
38 |
+
return $template_path;
|
39 |
+
}
|
40 |
+
|
41 |
public function process() {
|
42 |
|
43 |
+
if ( ! empty( $this->data['template_path'] ) ) {
|
44 |
+
|
45 |
+
$template_path = QM_Util::standard_dir( $this->data['template_path'] );
|
46 |
+
$stylesheet_directory = QM_Util::standard_dir( get_stylesheet_directory() );
|
47 |
+
$template_directory = QM_Util::standard_dir( get_template_directory() );
|
48 |
+
$theme_directory = QM_Util::standard_dir( get_theme_root() );
|
49 |
|
50 |
+
$template_file = str_replace( array( $stylesheet_directory, $template_directory ), '', $template_path );
|
51 |
+
$template_file = ltrim( $template_file, '/' );
|
52 |
+
$theme_template = str_replace( $theme_directory, '', $template_path );
|
53 |
+
$theme_template = ltrim( $theme_template, '/' );
|
54 |
|
55 |
+
$this->data['template_path'] = $template_path;
|
56 |
+
$this->data['template_file'] = $template_file;
|
57 |
+
$this->data['theme_template'] = $theme_template;
|
58 |
+
|
59 |
+
}
|
60 |
|
61 |
+
$this->data['stylesheet'] = get_stylesheet();
|
62 |
+
$this->data['template'] = get_template();
|
|
|
|
|
|
|
63 |
|
64 |
if ( isset( $this->data['body_class'] ) ) {
|
65 |
asort( $this->data['body_class'] );
|
composer.json
CHANGED
@@ -10,7 +10,18 @@
|
|
10 |
"homepage": "https://johnblackbourn.com/"
|
11 |
}
|
12 |
],
|
|
|
|
|
|
|
|
|
|
|
13 |
"require": {
|
14 |
"composer/installers": "~1.0"
|
15 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
}
|
10 |
"homepage": "https://johnblackbourn.com/"
|
11 |
}
|
12 |
],
|
13 |
+
"support": {
|
14 |
+
"issues": "https://github.com/johnbillion/query-monitor/issues",
|
15 |
+
"forum": "https://wordpress.org/support/plugin/query-monitor",
|
16 |
+
"source": "https://github.com/johnbillion/query-monitor"
|
17 |
+
},
|
18 |
"require": {
|
19 |
"composer/installers": "~1.0"
|
20 |
+
},
|
21 |
+
"require-dev" : {
|
22 |
+
"phpunit/phpunit": ">=3.7@stable"
|
23 |
+
},
|
24 |
+
"config": {
|
25 |
+
"bin-dir": "bin/"
|
26 |
+
}
|
27 |
}
|
dispatchers/{Headers.php → AJAX.php}
RENAMED
@@ -14,12 +14,15 @@ GNU General Public License for more details.
|
|
14 |
|
15 |
*/
|
16 |
|
17 |
-
class
|
18 |
|
19 |
-
public $id = '
|
20 |
|
21 |
public function __construct( QM_Plugin $qm ) {
|
22 |
parent::__construct( $qm );
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
public function init() {
|
@@ -34,18 +37,36 @@ class QM_Dispatcher_Headers extends QM_Dispatcher {
|
|
34 |
|
35 |
}
|
36 |
|
37 |
-
public function
|
38 |
|
39 |
-
|
|
|
|
|
40 |
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
43 |
}
|
44 |
|
45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
# flush once, because we're nice
|
48 |
-
if (
|
49 |
ob_flush();
|
50 |
}
|
51 |
|
@@ -53,6 +74,10 @@ class QM_Dispatcher_Headers extends QM_Dispatcher {
|
|
53 |
|
54 |
public function is_active() {
|
55 |
|
|
|
|
|
|
|
|
|
56 |
if ( ! $this->user_can_view() ) {
|
57 |
return false;
|
58 |
}
|
@@ -62,15 +87,26 @@ class QM_Dispatcher_Headers extends QM_Dispatcher {
|
|
62 |
return false;
|
63 |
}
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
return true;
|
66 |
|
67 |
}
|
68 |
|
69 |
}
|
70 |
|
71 |
-
function
|
72 |
-
$dispatchers['
|
73 |
return $dispatchers;
|
74 |
}
|
75 |
|
76 |
-
add_filter( 'qm/dispatchers', '
|
14 |
|
15 |
*/
|
16 |
|
17 |
+
class QM_Dispatcher_AJAX extends QM_Dispatcher {
|
18 |
|
19 |
+
public $id = 'ajax';
|
20 |
|
21 |
public function __construct( QM_Plugin $qm ) {
|
22 |
parent::__construct( $qm );
|
23 |
+
|
24 |
+
add_action( 'shutdown', array( $this, 'dispatch' ), 0 );
|
25 |
+
|
26 |
}
|
27 |
|
28 |
public function init() {
|
37 |
|
38 |
}
|
39 |
|
40 |
+
public function dispatch() {
|
41 |
|
42 |
+
if ( ! $this->should_dispatch() ) {
|
43 |
+
return;
|
44 |
+
}
|
45 |
|
46 |
+
$this->before_output();
|
47 |
+
|
48 |
+
/* @var QM_Output_Headers[] */
|
49 |
+
foreach ( $this->get_outputters( 'headers' ) as $id => $output ) {
|
50 |
+
$output->output();
|
51 |
+
}
|
52 |
+
|
53 |
+
$this->after_output();
|
54 |
|
55 |
}
|
56 |
|
57 |
+
protected function before_output() {
|
58 |
+
|
59 |
+
require_once $this->qm->plugin_path( 'output/Headers.php' );
|
60 |
+
|
61 |
+
foreach ( glob( $this->qm->plugin_path( 'output/headers/*.php' ) ) as $file ) {
|
62 |
+
require_once $file;
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
protected function after_output() {
|
67 |
|
68 |
# flush once, because we're nice
|
69 |
+
if ( ob_get_length() ) {
|
70 |
ob_flush();
|
71 |
}
|
72 |
|
74 |
|
75 |
public function is_active() {
|
76 |
|
77 |
+
if ( ! QM_Util::is_ajax() ) {
|
78 |
+
return false;
|
79 |
+
}
|
80 |
+
|
81 |
if ( ! $this->user_can_view() ) {
|
82 |
return false;
|
83 |
}
|
87 |
return false;
|
88 |
}
|
89 |
|
90 |
+
# Don't process if the minimum required actions haven't fired:
|
91 |
+
if ( is_admin() ) {
|
92 |
+
if ( ! did_action( 'admin_init' ) ) {
|
93 |
+
return false;
|
94 |
+
}
|
95 |
+
} else {
|
96 |
+
if ( ! did_action( 'wp' ) ) {
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
return true;
|
102 |
|
103 |
}
|
104 |
|
105 |
}
|
106 |
|
107 |
+
function register_qm_dispatcher_ajax( array $dispatchers, QM_Plugin $qm ) {
|
108 |
+
$dispatchers['ajax'] = new QM_Dispatcher_AJAX( $qm );
|
109 |
return $dispatchers;
|
110 |
}
|
111 |
|
112 |
+
add_filter( 'qm/dispatchers', 'register_qm_dispatcher_ajax', 10, 2 );
|
dispatchers/Html.php
CHANGED
@@ -17,6 +17,7 @@ GNU General Public License for more details.
|
|
17 |
class QM_Dispatcher_Html extends QM_Dispatcher {
|
18 |
|
19 |
public $id = 'html';
|
|
|
20 |
|
21 |
public function __construct( QM_Plugin $qm ) {
|
22 |
|
@@ -25,10 +26,20 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
25 |
add_action( 'wp_ajax_qm_auth_off', array( $this, 'ajax_off' ) );
|
26 |
add_action( 'wp_ajax_nopriv_qm_auth_off', array( $this, 'ajax_off' ) );
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
parent::__construct( $qm );
|
29 |
|
30 |
}
|
31 |
|
|
|
|
|
|
|
|
|
32 |
/**
|
33 |
* Helper function. Should the authentication cookie be secure?
|
34 |
*
|
@@ -44,7 +55,7 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
44 |
wp_send_json_error( __( 'Could not set authentication cookie.', 'query-monitor' ) );
|
45 |
}
|
46 |
|
47 |
-
$expiration = time() +
|
48 |
$secure = self::secure_cookie();
|
49 |
$cookie = wp_generate_auth_cookie( get_current_user_id(), $expiration, 'logged_in' );
|
50 |
|
@@ -58,7 +69,7 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
58 |
|
59 |
public function ajax_off() {
|
60 |
|
61 |
-
if ( !
|
62 |
wp_send_json_error( __( 'Could not clear authentication cookie.', 'query-monitor' ) );
|
63 |
}
|
64 |
|
@@ -78,23 +89,22 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
78 |
return;
|
79 |
}
|
80 |
|
81 |
-
$class = implode( ' ', array( 'hide-if-js' ) );
|
82 |
$title = __( 'Query Monitor', 'query-monitor' );
|
83 |
|
84 |
$wp_admin_bar->add_menu( array(
|
85 |
'id' => 'query-monitor',
|
86 |
-
'title' => $title,
|
87 |
'href' => '#qm-overview',
|
88 |
'meta' => array(
|
89 |
-
'classname' =>
|
90 |
-
)
|
91 |
) );
|
92 |
|
93 |
$wp_admin_bar->add_menu( array(
|
94 |
'parent' => 'query-monitor',
|
95 |
'id' => 'query-monitor-placeholder',
|
96 |
-
'title' => $title,
|
97 |
-
'href' => '#qm-overview'
|
98 |
) );
|
99 |
|
100 |
}
|
@@ -162,11 +172,30 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
162 |
|
163 |
}
|
164 |
|
165 |
-
public function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
|
167 |
require_once $this->qm->plugin_path( 'output/Html.php' );
|
168 |
|
169 |
-
|
|
|
|
|
170 |
|
171 |
$class = array(
|
172 |
'qm-no-js',
|
@@ -183,13 +212,13 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
183 |
$class[] = 'qm-show';
|
184 |
}
|
185 |
|
186 |
-
echo '<div id="qm" class="' . implode( ' ', $class ) . '">';
|
187 |
echo '<div id="qm-wrapper">';
|
188 |
-
echo '<p>' .
|
189 |
|
190 |
}
|
191 |
|
192 |
-
|
193 |
|
194 |
echo '<div class="qm qm-half" id="qm-authentication">';
|
195 |
echo '<table cellspacing="0">';
|
@@ -200,22 +229,22 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
200 |
echo '</thead>';
|
201 |
echo '<tbody>';
|
202 |
|
203 |
-
if (
|
204 |
|
205 |
echo '<tr>';
|
206 |
-
echo '<td>' .
|
207 |
echo '</tr>';
|
208 |
echo '<tr>';
|
209 |
-
echo '<td><a href="#" class="qm-auth" data-action="on">' .
|
210 |
echo '</tr>';
|
211 |
|
212 |
} else {
|
213 |
|
214 |
echo '<tr>';
|
215 |
-
echo '<td>' .
|
216 |
echo '</tr>';
|
217 |
echo '<tr>';
|
218 |
-
echo '<td><a href="#" class="qm-auth" data-action="off">' .
|
219 |
echo '</tr>';
|
220 |
|
221 |
}
|
@@ -249,7 +278,7 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
249 |
$title = implode( ' ', apply_filters( 'qm/output/title', array() ) );
|
250 |
|
251 |
if ( empty( $title ) ) {
|
252 |
-
$title =
|
253 |
}
|
254 |
|
255 |
$admin_bar_menu = array(
|
@@ -261,7 +290,7 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
261 |
);
|
262 |
|
263 |
foreach ( apply_filters( 'qm/output/menus', array() ) as $menu ) {
|
264 |
-
$admin_bar_menu['sub'][] = $menu;
|
265 |
}
|
266 |
|
267 |
return $admin_bar_menu;
|
@@ -274,7 +303,7 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
274 |
return false;
|
275 |
}
|
276 |
|
277 |
-
if ( !
|
278 |
return false;
|
279 |
}
|
280 |
|
@@ -282,6 +311,22 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
|
|
282 |
return false;
|
283 |
}
|
284 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
return true;
|
286 |
|
287 |
}
|
17 |
class QM_Dispatcher_Html extends QM_Dispatcher {
|
18 |
|
19 |
public $id = 'html';
|
20 |
+
public $did_footer = false;
|
21 |
|
22 |
public function __construct( QM_Plugin $qm ) {
|
23 |
|
26 |
add_action( 'wp_ajax_qm_auth_off', array( $this, 'ajax_off' ) );
|
27 |
add_action( 'wp_ajax_nopriv_qm_auth_off', array( $this, 'ajax_off' ) );
|
28 |
|
29 |
+
add_action( 'shutdown', array( $this, 'dispatch' ), 0 );
|
30 |
+
|
31 |
+
add_action( 'wp_footer', array( $this, 'action_footer' ) );
|
32 |
+
add_action( 'admin_footer', array( $this, 'action_footer' ) );
|
33 |
+
add_action( 'login_footer', array( $this, 'action_footer' ) );
|
34 |
+
|
35 |
parent::__construct( $qm );
|
36 |
|
37 |
}
|
38 |
|
39 |
+
public function action_footer() {
|
40 |
+
$this->did_footer = true;
|
41 |
+
}
|
42 |
+
|
43 |
/**
|
44 |
* Helper function. Should the authentication cookie be secure?
|
45 |
*
|
55 |
wp_send_json_error( __( 'Could not set authentication cookie.', 'query-monitor' ) );
|
56 |
}
|
57 |
|
58 |
+
$expiration = time() + ( 2 * DAY_IN_SECONDS );
|
59 |
$secure = self::secure_cookie();
|
60 |
$cookie = wp_generate_auth_cookie( get_current_user_id(), $expiration, 'logged_in' );
|
61 |
|
69 |
|
70 |
public function ajax_off() {
|
71 |
|
72 |
+
if ( ! self::user_verified() or ! check_ajax_referer( 'qm-auth-off', 'nonce', false ) ) {
|
73 |
wp_send_json_error( __( 'Could not clear authentication cookie.', 'query-monitor' ) );
|
74 |
}
|
75 |
|
89 |
return;
|
90 |
}
|
91 |
|
|
|
92 |
$title = __( 'Query Monitor', 'query-monitor' );
|
93 |
|
94 |
$wp_admin_bar->add_menu( array(
|
95 |
'id' => 'query-monitor',
|
96 |
+
'title' => esc_html( $title ),
|
97 |
'href' => '#qm-overview',
|
98 |
'meta' => array(
|
99 |
+
'classname' => 'hide-if-js',
|
100 |
+
),
|
101 |
) );
|
102 |
|
103 |
$wp_admin_bar->add_menu( array(
|
104 |
'parent' => 'query-monitor',
|
105 |
'id' => 'query-monitor-placeholder',
|
106 |
+
'title' => esc_html( $title ),
|
107 |
+
'href' => '#qm-overview',
|
108 |
) );
|
109 |
|
110 |
}
|
172 |
|
173 |
}
|
174 |
|
175 |
+
public function dispatch() {
|
176 |
+
|
177 |
+
if ( ! $this->should_dispatch() ) {
|
178 |
+
return;
|
179 |
+
}
|
180 |
+
|
181 |
+
$this->before_output();
|
182 |
+
|
183 |
+
/* @var QM_Output_Html[] */
|
184 |
+
foreach ( $this->get_outputters( 'html' ) as $id => $output ) {
|
185 |
+
$output->output();
|
186 |
+
}
|
187 |
+
|
188 |
+
$this->after_output();
|
189 |
+
|
190 |
+
}
|
191 |
+
|
192 |
+
protected function before_output() {
|
193 |
|
194 |
require_once $this->qm->plugin_path( 'output/Html.php' );
|
195 |
|
196 |
+
foreach ( glob( $this->qm->plugin_path( 'output/html/*.php' ) ) as $file ) {
|
197 |
+
require_once $file;
|
198 |
+
}
|
199 |
|
200 |
$class = array(
|
201 |
'qm-no-js',
|
212 |
$class[] = 'qm-show';
|
213 |
}
|
214 |
|
215 |
+
echo '<div id="qm" class="' . implode( ' ', array_map( 'esc_attr', $class ) ) . '">';
|
216 |
echo '<div id="qm-wrapper">';
|
217 |
+
echo '<p>' . esc_html__( 'Query Monitor', 'query-monitor' ) . '</p>';
|
218 |
|
219 |
}
|
220 |
|
221 |
+
protected function after_output() {
|
222 |
|
223 |
echo '<div class="qm qm-half" id="qm-authentication">';
|
224 |
echo '<table cellspacing="0">';
|
229 |
echo '</thead>';
|
230 |
echo '<tbody>';
|
231 |
|
232 |
+
if ( ! self::user_verified() ) {
|
233 |
|
234 |
echo '<tr>';
|
235 |
+
echo '<td>' . esc_html__( 'You can set an authentication cookie which allows you to view Query Monitor output when you’re not logged in.', 'query-monitor' ) . '</td>';
|
236 |
echo '</tr>';
|
237 |
echo '<tr>';
|
238 |
+
echo '<td><a href="#" class="qm-auth" data-action="on">' . esc_html__( 'Set authentication cookie', 'query-monitor' ) . '</a></td>';
|
239 |
echo '</tr>';
|
240 |
|
241 |
} else {
|
242 |
|
243 |
echo '<tr>';
|
244 |
+
echo '<td>' . esc_html__( 'You currently have an authentication cookie which allows you to view Query Monitor output.', 'query-monitor' ) . '</td>';
|
245 |
echo '</tr>';
|
246 |
echo '<tr>';
|
247 |
+
echo '<td><a href="#" class="qm-auth" data-action="off">' . esc_html__( 'Clear authentication cookie', 'query-monitor' ) . '</a></td>';
|
248 |
echo '</tr>';
|
249 |
|
250 |
}
|
278 |
$title = implode( ' ', apply_filters( 'qm/output/title', array() ) );
|
279 |
|
280 |
if ( empty( $title ) ) {
|
281 |
+
$title = esc_html__( 'Query Monitor', 'query-monitor' );
|
282 |
}
|
283 |
|
284 |
$admin_bar_menu = array(
|
290 |
);
|
291 |
|
292 |
foreach ( apply_filters( 'qm/output/menus', array() ) as $menu ) {
|
293 |
+
$admin_bar_menu['sub'][ $menu['id'] ] = $menu;
|
294 |
}
|
295 |
|
296 |
return $admin_bar_menu;
|
303 |
return false;
|
304 |
}
|
305 |
|
306 |
+
if ( ! $this->did_footer ) {
|
307 |
return false;
|
308 |
}
|
309 |
|
311 |
return false;
|
312 |
}
|
313 |
|
314 |
+
# Don't process if the minimum required actions haven't fired:
|
315 |
+
if ( is_admin() ) {
|
316 |
+
if ( ! did_action( 'admin_init' ) ) {
|
317 |
+
return false;
|
318 |
+
}
|
319 |
+
} else {
|
320 |
+
if ( ! ( did_action( 'wp' ) || did_action( 'login_init' ) ) ) {
|
321 |
+
return false;
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
# Back-compat filter. Please use `qm/dispatch/html` instead
|
326 |
+
if ( ! apply_filters( 'qm/process', true, is_admin_bar_showing() ) ) {
|
327 |
+
return false;
|
328 |
+
}
|
329 |
+
|
330 |
return true;
|
331 |
|
332 |
}
|
dispatchers/REST.php
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Copyright 2009-2015 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_Dispatcher_REST extends QM_Dispatcher {
|
18 |
+
|
19 |
+
public $id = 'rest';
|
20 |
+
|
21 |
+
public function __construct( QM_Plugin $qm ) {
|
22 |
+
parent::__construct( $qm );
|
23 |
+
|
24 |
+
add_filter( 'rest_post_dispatch', array( $this, 'filter_rest_post_dispatch' ), 1, 3 );
|
25 |
+
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
*
|
30 |
+
* @param WP_HTTP_Response $result Result to send to the client. Usually a WP_REST_Response.
|
31 |
+
* @param WP_REST_Server $server Server instance.
|
32 |
+
* @param WP_REST_Request $request Request used to generate the response.
|
33 |
+
* @return WP_HTTP_Response Result to send to the client.
|
34 |
+
*/
|
35 |
+
public function filter_rest_post_dispatch( WP_HTTP_Response $result, WP_REST_Server $server, WP_REST_Request $request ) {
|
36 |
+
|
37 |
+
if ( ! $this->should_dispatch() ) {
|
38 |
+
return $result;
|
39 |
+
}
|
40 |
+
|
41 |
+
$this->before_output();
|
42 |
+
|
43 |
+
/* @var QM_Output_Headers[] */
|
44 |
+
foreach ( $this->get_outputters( 'headers' ) as $id => $output ) {
|
45 |
+
$output->output();
|
46 |
+
}
|
47 |
+
|
48 |
+
$this->after_output();
|
49 |
+
|
50 |
+
return $result;
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
public function before_output() {
|
55 |
+
|
56 |
+
require_once $this->qm->plugin_path( 'output/Headers.php' );
|
57 |
+
|
58 |
+
foreach ( glob( $this->qm->plugin_path( 'output/headers/*.php' ) ) as $file ) {
|
59 |
+
include $file;
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
public function is_active() {
|
64 |
+
|
65 |
+
# If the headers have already been sent then we can't do anything about it
|
66 |
+
if ( headers_sent() ) {
|
67 |
+
return false;
|
68 |
+
}
|
69 |
+
|
70 |
+
if ( ! $this->user_can_view() ) {
|
71 |
+
return false;
|
72 |
+
}
|
73 |
+
|
74 |
+
return true;
|
75 |
+
|
76 |
+
}
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
function register_qm_dispatcher_rest( array $dispatchers, QM_Plugin $qm ) {
|
81 |
+
$dispatchers['rest'] = new QM_Dispatcher_REST( $qm );
|
82 |
+
return $dispatchers;
|
83 |
+
}
|
84 |
+
|
85 |
+
add_filter( 'qm/dispatchers', 'register_qm_dispatcher_rest', 10, 2 );
|
dispatchers/Redirect.php
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Copyright 2009-2015 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_Dispatcher_Redirect extends QM_Dispatcher {
|
18 |
+
|
19 |
+
public $id = 'redirect';
|
20 |
+
|
21 |
+
public function __construct( QM_Plugin $qm ) {
|
22 |
+
parent::__construct( $qm );
|
23 |
+
|
24 |
+
add_filter( 'wp_redirect', array( $this, 'filter_wp_redirect' ), 999, 2 );
|
25 |
+
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
*
|
30 |
+
* @param string $location The path to redirect to.
|
31 |
+
* @param int $status Status code to use.
|
32 |
+
*/
|
33 |
+
public function filter_wp_redirect( $location, $status ) {
|
34 |
+
|
35 |
+
if ( ! $this->should_dispatch() ) {
|
36 |
+
return $location;
|
37 |
+
}
|
38 |
+
|
39 |
+
$this->before_output();
|
40 |
+
|
41 |
+
/* @var QM_Output_Headers[] */
|
42 |
+
foreach ( $this->get_outputters( 'headers' ) as $id => $output ) {
|
43 |
+
$output->output();
|
44 |
+
}
|
45 |
+
|
46 |
+
$this->after_output();
|
47 |
+
|
48 |
+
return $location;
|
49 |
+
|
50 |
+
}
|
51 |
+
|
52 |
+
protected function before_output() {
|
53 |
+
|
54 |
+
require_once $this->qm->plugin_path( 'output/Headers.php' );
|
55 |
+
|
56 |
+
foreach ( glob( $this->qm->plugin_path( 'output/headers/*.php' ) ) as $file ) {
|
57 |
+
require_once $file;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
public function is_active() {
|
62 |
+
|
63 |
+
if ( ! $this->user_can_view() ) {
|
64 |
+
return false;
|
65 |
+
}
|
66 |
+
|
67 |
+
# If the headers have already been sent then we can't do anything about it
|
68 |
+
if ( headers_sent() ) {
|
69 |
+
return false;
|
70 |
+
}
|
71 |
+
|
72 |
+
# Don't process if the minimum required actions haven't fired:
|
73 |
+
if ( is_admin() ) {
|
74 |
+
if ( ! did_action( 'admin_init' ) ) {
|
75 |
+
return false;
|
76 |
+
}
|
77 |
+
} else {
|
78 |
+
if ( ! ( did_action( 'wp' ) || did_action( 'login_init' ) ) ) {
|
79 |
+
return false;
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
return true;
|
84 |
+
|
85 |
+
}
|
86 |
+
|
87 |
+
}
|
88 |
+
|
89 |
+
function register_qm_dispatcher_redirect( array $dispatchers, QM_Plugin $qm ) {
|
90 |
+
$dispatchers['redirect'] = new QM_Dispatcher_Redirect( $qm );
|
91 |
+
return $dispatchers;
|
92 |
+
}
|
93 |
+
|
94 |
+
add_filter( 'qm/dispatchers', 'register_qm_dispatcher_redirect', 10, 2 );
|
output/Headers.php
CHANGED
@@ -14,10 +14,20 @@ GNU General Public License for more details.
|
|
14 |
|
15 |
*/
|
16 |
|
17 |
-
abstract class QM_Output_Headers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
-
public function __construct( QM_Collector $collector ) {
|
20 |
-
$this->collector = $collector;
|
21 |
}
|
22 |
|
23 |
}
|
14 |
|
15 |
*/
|
16 |
|
17 |
+
abstract class QM_Output_Headers extends QM_Output {
|
18 |
+
|
19 |
+
public function output() {
|
20 |
+
|
21 |
+
$id = $this->collector->id;
|
22 |
+
|
23 |
+
foreach ( $this->get_output() as $key => $value ) {
|
24 |
+
if ( is_scalar( $value ) ) {
|
25 |
+
header( sprintf( 'X-QM-%s-%s: %s', $id, $key, $value ) );
|
26 |
+
} else {
|
27 |
+
header( sprintf( 'X-QM-%s-%s: %s', $id, $key, json_encode( $value ) ) );
|
28 |
+
}
|
29 |
+
}
|
30 |
|
|
|
|
|
31 |
}
|
32 |
|
33 |
}
|
output/Html.php
CHANGED
@@ -14,46 +14,50 @@ GNU General Public License for more details.
|
|
14 |
|
15 |
*/
|
16 |
|
17 |
-
abstract class QM_Output_Html
|
18 |
|
19 |
protected static $file_link_format = null;
|
20 |
|
21 |
-
public function __construct( QM_Collector $collector ) {
|
22 |
-
$this->collector = $collector;
|
23 |
-
}
|
24 |
-
|
25 |
public function admin_menu( array $menu ) {
|
26 |
|
27 |
$menu[] = $this->menu( array(
|
28 |
-
'title' => $this->collector->name(),
|
29 |
) );
|
30 |
return $menu;
|
31 |
|
32 |
}
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
public static function output_inner( $vars ) {
|
35 |
|
36 |
echo '<table cellspacing="0" class="qm-inner">';
|
37 |
|
38 |
foreach ( $vars as $key => $value ) {
|
39 |
echo '<tr>';
|
40 |
-
echo '<td
|
41 |
if ( is_array( $value ) ) {
|
42 |
-
echo '<td
|
43 |
self::output_inner( $value );
|
44 |
echo '</td>';
|
45 |
} else if ( is_object( $value ) ) {
|
46 |
-
echo '<td
|
47 |
self::output_inner( get_object_vars( $value ) );
|
48 |
echo '</td>';
|
49 |
} else if ( is_bool( $value ) ) {
|
50 |
if ( $value ) {
|
51 |
-
echo '<td
|
52 |
} else {
|
53 |
-
echo '<td
|
54 |
}
|
55 |
} else {
|
56 |
-
echo '<td
|
57 |
echo nl2br( esc_html( $value ) );
|
58 |
echo '</td>';
|
59 |
}
|
@@ -64,6 +68,14 @@ abstract class QM_Output_Html implements QM_Output {
|
|
64 |
|
65 |
}
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
protected function build_filter( $name, array $values, $highlight = '' ) {
|
68 |
|
69 |
if ( empty( $values ) ) {
|
@@ -73,7 +85,7 @@ abstract class QM_Output_Html implements QM_Output {
|
|
73 |
usort( $values, 'strcasecmp' );
|
74 |
|
75 |
$out = '<select id="qm-filter-' . esc_attr( $this->collector->id . '-' . $name ) . '" class="qm-filter" data-filter="' . esc_attr( $name ) . '" data-highlight="' . esc_attr( $highlight ) . '">';
|
76 |
-
$out .= '<option value="">' .
|
77 |
|
78 |
foreach ( $values as $value ) {
|
79 |
$out .= '<option value="' . esc_attr( $value ) . '">' . esc_html( $value ) . '</option>';
|
@@ -85,6 +97,11 @@ abstract class QM_Output_Html implements QM_Output {
|
|
85 |
|
86 |
}
|
87 |
|
|
|
|
|
|
|
|
|
|
|
88 |
protected function build_sorter() {
|
89 |
$out = '<span class="qm-sort-controls">';
|
90 |
$out .= '<a href="#" class="qm-sort qm-sort-asc">▲</a>';
|
@@ -96,12 +113,18 @@ abstract class QM_Output_Html implements QM_Output {
|
|
96 |
protected function menu( array $args ) {
|
97 |
|
98 |
return array_merge( array(
|
99 |
-
'id' => "query-monitor-{$this->collector->id}",
|
100 |
-
'href' => '#' . $this->collector->id()
|
101 |
), $args );
|
102 |
|
103 |
}
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
public static function format_sql( $sql ) {
|
106 |
|
107 |
$sql = str_replace( array( "\r\n", "\r", "\n", "\t" ), ' ', $sql );
|
@@ -113,6 +136,7 @@ abstract class QM_Output_Html implements QM_Output {
|
|
113 |
'HAVING', 'INNER', 'INSERT', 'LEFT', 'LIMIT', 'ON', 'OR', 'ORDER', 'OUTER', 'REPLACE', 'RIGHT', 'ROLLBACK', 'SELECT', 'SET',
|
114 |
'SHOW', 'START', 'THEN', 'TRUNCATE', 'UPDATE', 'VALUES', 'WHEN', 'WHERE'
|
115 |
) as $cmd ) {
|
|
|
116 |
$sql = trim( str_replace( " $cmd ", "<br>$cmd ", $sql ) );
|
117 |
}
|
118 |
|
@@ -123,27 +147,41 @@ abstract class QM_Output_Html implements QM_Output {
|
|
123 |
|
124 |
}
|
125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
public static function format_url( $url ) {
|
127 |
-
|
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 |
}
|
139 |
|
140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
|
142 |
# Further reading:
|
143 |
# http://simonwheatley.co.uk/2012/07/clickable-stack-traces/
|
144 |
# https://github.com/grych/subl-handler
|
145 |
|
146 |
-
|
|
|
|
|
147 |
$format = ini_get( 'xdebug.file_link_format' );
|
148 |
$format = apply_filters( 'qm/output/file_link_format', $format );
|
149 |
if ( empty( $format ) ) {
|
@@ -154,11 +192,19 @@ abstract class QM_Output_Html implements QM_Output {
|
|
154 |
}
|
155 |
|
156 |
if ( false === self::$file_link_format ) {
|
157 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
}
|
159 |
|
160 |
-
$link = sprintf( self::$file_link_format, urlencode( $file ), $
|
161 |
-
return sprintf( '<a href="%s">%s</a>', $link, $text );
|
162 |
|
163 |
}
|
164 |
|
14 |
|
15 |
*/
|
16 |
|
17 |
+
abstract class QM_Output_Html extends QM_Output {
|
18 |
|
19 |
protected static $file_link_format = null;
|
20 |
|
|
|
|
|
|
|
|
|
21 |
public function admin_menu( array $menu ) {
|
22 |
|
23 |
$menu[] = $this->menu( array(
|
24 |
+
'title' => esc_html( $this->collector->name() ),
|
25 |
) );
|
26 |
return $menu;
|
27 |
|
28 |
}
|
29 |
|
30 |
+
public function get_output() {
|
31 |
+
ob_start();
|
32 |
+
// compat until I convert all the existing outputters to use `get_output()`
|
33 |
+
$this->output();
|
34 |
+
$out = ob_get_clean();
|
35 |
+
return $out;
|
36 |
+
}
|
37 |
+
|
38 |
public static function output_inner( $vars ) {
|
39 |
|
40 |
echo '<table cellspacing="0" class="qm-inner">';
|
41 |
|
42 |
foreach ( $vars as $key => $value ) {
|
43 |
echo '<tr>';
|
44 |
+
echo '<td>' . esc_html( $key ) . '</td>';
|
45 |
if ( is_array( $value ) ) {
|
46 |
+
echo '<td class="qm-has-inner">';
|
47 |
self::output_inner( $value );
|
48 |
echo '</td>';
|
49 |
} else if ( is_object( $value ) ) {
|
50 |
+
echo '<td class="qm-has-inner">';
|
51 |
self::output_inner( get_object_vars( $value ) );
|
52 |
echo '</td>';
|
53 |
} else if ( is_bool( $value ) ) {
|
54 |
if ( $value ) {
|
55 |
+
echo '<td class="qm-true">true</td>';
|
56 |
} else {
|
57 |
+
echo '<td class="qm-false">false</td>';
|
58 |
}
|
59 |
} else {
|
60 |
+
echo '<td>';
|
61 |
echo nl2br( esc_html( $value ) );
|
62 |
echo '</td>';
|
63 |
}
|
68 |
|
69 |
}
|
70 |
|
71 |
+
/**
|
72 |
+
* Returns the table filter controls. Safe for output.
|
73 |
+
*
|
74 |
+
* @param string $name The name for the `data-` attributes that get filtered by this control.
|
75 |
+
* @param array $values Possible values for this control.
|
76 |
+
* @param string $highlight Optional. The name for the `data-` attributes that get highlighted by this control.
|
77 |
+
* @return string Markup for the table filter controls.
|
78 |
+
*/
|
79 |
protected function build_filter( $name, array $values, $highlight = '' ) {
|
80 |
|
81 |
if ( empty( $values ) ) {
|
85 |
usort( $values, 'strcasecmp' );
|
86 |
|
87 |
$out = '<select id="qm-filter-' . esc_attr( $this->collector->id . '-' . $name ) . '" class="qm-filter" data-filter="' . esc_attr( $name ) . '" data-highlight="' . esc_attr( $highlight ) . '">';
|
88 |
+
$out .= '<option value="">' . esc_html_x( 'All', '"All" option for filters', 'query-monitor' ) . '</option>';
|
89 |
|
90 |
foreach ( $values as $value ) {
|
91 |
$out .= '<option value="' . esc_attr( $value ) . '">' . esc_html( $value ) . '</option>';
|
97 |
|
98 |
}
|
99 |
|
100 |
+
/**
|
101 |
+
* Returns the column sorter controls. Safe for output.
|
102 |
+
*
|
103 |
+
* @return string Markup for the column sorter controls.
|
104 |
+
*/
|
105 |
protected function build_sorter() {
|
106 |
$out = '<span class="qm-sort-controls">';
|
107 |
$out .= '<a href="#" class="qm-sort qm-sort-asc">▲</a>';
|
113 |
protected function menu( array $args ) {
|
114 |
|
115 |
return array_merge( array(
|
116 |
+
'id' => esc_attr( "query-monitor-{$this->collector->id}" ),
|
117 |
+
'href' => esc_attr( '#' . $this->collector->id() )
|
118 |
), $args );
|
119 |
|
120 |
}
|
121 |
|
122 |
+
/**
|
123 |
+
* Returns the given SQL string in a nicely presented format. Safe for output.
|
124 |
+
*
|
125 |
+
* @param string $sql An SQL query string.
|
126 |
+
* @return string The SQL formatted with markup.
|
127 |
+
*/
|
128 |
public static function format_sql( $sql ) {
|
129 |
|
130 |
$sql = str_replace( array( "\r\n", "\r", "\n", "\t" ), ' ', $sql );
|
136 |
'HAVING', 'INNER', 'INSERT', 'LEFT', 'LIMIT', 'ON', 'OR', 'ORDER', 'OUTER', 'REPLACE', 'RIGHT', 'ROLLBACK', 'SELECT', 'SET',
|
137 |
'SHOW', 'START', 'THEN', 'TRUNCATE', 'UPDATE', 'VALUES', 'WHEN', 'WHERE'
|
138 |
) as $cmd ) {
|
139 |
+
// Why does this trim() every time?
|
140 |
$sql = trim( str_replace( " $cmd ", "<br>$cmd ", $sql ) );
|
141 |
}
|
142 |
|
147 |
|
148 |
}
|
149 |
|
150 |
+
/**
|
151 |
+
* Returns the given URL in a nicely presented format. Safe for output.
|
152 |
+
*
|
153 |
+
* @param string $url A URL.
|
154 |
+
* @return string The URL formatted with markup.
|
155 |
+
*/
|
156 |
public static function format_url( $url ) {
|
157 |
+
return str_replace( '&', '<br>&', esc_html( $url ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
}
|
159 |
|
160 |
+
/**
|
161 |
+
* Returns a file path, name, and line number. Safe for output.
|
162 |
+
*
|
163 |
+
* If clickable file links are enabled, a link such as this is returned:
|
164 |
+
*
|
165 |
+
* <a href="subl://open/?line={line}&url={file}">{text}</a>
|
166 |
+
*
|
167 |
+
* Otherwise, the display text and file details such as this is returned:
|
168 |
+
*
|
169 |
+
* {text}<br>{file}:{line}
|
170 |
+
*
|
171 |
+
* @param string $text The display text, such as a function name or file name.
|
172 |
+
* @param string $file The full file path and name.
|
173 |
+
* @param int $line Optional. A line number, if appropriate.
|
174 |
+
* @return string The fully formatted file link or file name, safe for output.
|
175 |
+
*/
|
176 |
+
public static function output_filename( $text, $file, $line = 0 ) {
|
177 |
|
178 |
# Further reading:
|
179 |
# http://simonwheatley.co.uk/2012/07/clickable-stack-traces/
|
180 |
# https://github.com/grych/subl-handler
|
181 |
|
182 |
+
$link_line = ( $line ) ? $line : 1;
|
183 |
+
|
184 |
+
if ( ! isset( self::$file_link_format ) ) {
|
185 |
$format = ini_get( 'xdebug.file_link_format' );
|
186 |
$format = apply_filters( 'qm/output/file_link_format', $format );
|
187 |
if ( empty( $format ) ) {
|
192 |
}
|
193 |
|
194 |
if ( false === self::$file_link_format ) {
|
195 |
+
$fallback = QM_Util::standard_dir( $file, '' );
|
196 |
+
if ( $line ) {
|
197 |
+
$fallback .= ':' . $line;
|
198 |
+
}
|
199 |
+
$return = esc_html( $text );
|
200 |
+
if ( $fallback != $text ) {
|
201 |
+
$return .= '<br><span class="qm-info"> ' . esc_html( $fallback ) . '</span>';
|
202 |
+
}
|
203 |
+
return $return;
|
204 |
}
|
205 |
|
206 |
+
$link = sprintf( self::$file_link_format, urlencode( $file ), intval( $link_line ) );
|
207 |
+
return sprintf( '<a href="%s">%s</a>', esc_attr( $link ), esc_html( $text ) );
|
208 |
|
209 |
}
|
210 |
|
output/headers/overview.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Copyright 2009-2015 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_Headers_Overview extends QM_Output_Headers {
|
18 |
+
|
19 |
+
public function get_output() {
|
20 |
+
|
21 |
+
$data = $this->collector->get_data();
|
22 |
+
$headers = array();
|
23 |
+
|
24 |
+
$headers['time'] = number_format_i18n( $data['time'], 4 );
|
25 |
+
$headers['time_usage'] = sprintf(
|
26 |
+
__( '%1$s%% of %2$ss limit', 'query-monitor' ),
|
27 |
+
number_format_i18n( $data['time_usage'], 1 ),
|
28 |
+
number_format_i18n( $data['time_limit'] )
|
29 |
+
);
|
30 |
+
|
31 |
+
if ( ! empty( $data['memory'] ) ) {
|
32 |
+
$headers['memory'] = sprintf(
|
33 |
+
__( '%s kB', 'query-monitor' ),
|
34 |
+
number_format_i18n( $data['memory'] / 1024 )
|
35 |
+
);
|
36 |
+
$headers['memory_usage'] = sprintf(
|
37 |
+
__( '%1$s%% of %2$s kB limit', 'query-monitor' ),
|
38 |
+
number_format_i18n( $data['memory_usage'], 1 ),
|
39 |
+
number_format_i18n( $data['memory_limit'] / 1024 )
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
return $headers;
|
44 |
+
|
45 |
+
}
|
46 |
+
|
47 |
+
}
|
48 |
+
|
49 |
+
function register_qm_output_headers_overview( array $output, QM_Collectors $collectors ) {
|
50 |
+
if ( $collector = QM_Collectors::get( 'overview' ) ) {
|
51 |
+
$output['overview'] = new QM_Output_Headers_Overview( $collector );
|
52 |
+
}
|
53 |
+
return $output;
|
54 |
+
}
|
55 |
+
|
56 |
+
add_filter( 'qm/outputter/headers', 'register_qm_output_headers_overview', 10, 2 );
|
output/headers/php_errors.php
CHANGED
@@ -16,16 +16,13 @@ GNU General Public License for more details.
|
|
16 |
|
17 |
class QM_Output_Headers_PHP_Errors extends QM_Output_Headers {
|
18 |
|
19 |
-
public function
|
20 |
-
|
21 |
-
if ( ! QM_Util::is_ajax() ) {
|
22 |
-
return;
|
23 |
-
}
|
24 |
|
25 |
$data = $this->collector->get_data();
|
|
|
26 |
|
27 |
if ( empty( $data['errors'] ) ) {
|
28 |
-
return;
|
29 |
}
|
30 |
|
31 |
$count = 0;
|
@@ -48,18 +45,16 @@ class QM_Output_Headers_PHP_Errors extends QM_Output_Headers {
|
|
48 |
'component' => $component->name,
|
49 |
);
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
json_encode( $output_error )
|
54 |
-
) );
|
55 |
|
56 |
}
|
57 |
|
58 |
}
|
59 |
|
60 |
-
|
61 |
-
$count
|
62 |
-
) );
|
63 |
|
64 |
}
|
65 |
|
16 |
|
17 |
class QM_Output_Headers_PHP_Errors extends QM_Output_Headers {
|
18 |
|
19 |
+
public function get_output() {
|
|
|
|
|
|
|
|
|
20 |
|
21 |
$data = $this->collector->get_data();
|
22 |
+
$headers = array();
|
23 |
|
24 |
if ( empty( $data['errors'] ) ) {
|
25 |
+
return array();
|
26 |
}
|
27 |
|
28 |
$count = 0;
|
45 |
'component' => $component->name,
|
46 |
);
|
47 |
|
48 |
+
$key = sprintf( 'error-%d', $count );
|
49 |
+
$headers[ $key ] = json_encode( $output_error );
|
|
|
|
|
50 |
|
51 |
}
|
52 |
|
53 |
}
|
54 |
|
55 |
+
return array_merge( array(
|
56 |
+
'error-count' => $count,
|
57 |
+
), $headers );
|
58 |
|
59 |
}
|
60 |
|
output/headers/redirects.php
CHANGED
@@ -16,17 +16,17 @@ GNU General Public License for more details.
|
|
16 |
|
17 |
class QM_Output_Headers_Redirects extends QM_Output_Headers {
|
18 |
|
19 |
-
public function
|
20 |
|
21 |
$data = $this->collector->get_data();
|
|
|
22 |
|
23 |
if ( empty( $data['trace'] ) ) {
|
24 |
-
return;
|
25 |
}
|
26 |
|
27 |
-
|
28 |
-
|
29 |
-
) );
|
30 |
|
31 |
}
|
32 |
|
16 |
|
17 |
class QM_Output_Headers_Redirects extends QM_Output_Headers {
|
18 |
|
19 |
+
public function get_output() {
|
20 |
|
21 |
$data = $this->collector->get_data();
|
22 |
+
$headers = array();
|
23 |
|
24 |
if ( empty( $data['trace'] ) ) {
|
25 |
+
return array();
|
26 |
}
|
27 |
|
28 |
+
$headers['Redirect-Trace'] = implode( ', ', $data['trace']->get_stack() );
|
29 |
+
return $headers;
|
|
|
30 |
|
31 |
}
|
32 |
|
output/html/admin.php
CHANGED
@@ -58,7 +58,7 @@ class QM_Output_Html_Admin extends QM_Output_Html {
|
|
58 |
|
59 |
echo '<tr>';
|
60 |
echo '<td class="qm-ltr">$pagenow</td>';
|
61 |
-
echo
|
62 |
echo '</tr>';
|
63 |
|
64 |
$screens = array(
|
@@ -75,6 +75,7 @@ class QM_Output_Html_Admin extends QM_Output_Html {
|
|
75 |
'users-network' => true,
|
76 |
);
|
77 |
|
|
|
78 |
if ( !empty( $data['current_screen'] ) and isset( $screens[$data['current_screen']->base] ) ) {
|
79 |
|
80 |
# And now, WordPress' legendary inconsistency comes into play:
|
@@ -102,16 +103,16 @@ class QM_Output_Html_Admin extends QM_Output_Html {
|
|
102 |
}
|
103 |
|
104 |
echo '<tr>';
|
105 |
-
echo '<td rowspan="2">' .
|
106 |
-
echo
|
107 |
echo '</tr>';
|
108 |
echo '<tr>';
|
109 |
-
echo
|
110 |
echo '</tr>';
|
111 |
|
112 |
echo '<tr>';
|
113 |
-
echo '<td rowspan="1">' .
|
114 |
-
echo
|
115 |
echo '</tr>';
|
116 |
|
117 |
}
|
58 |
|
59 |
echo '<tr>';
|
60 |
echo '<td class="qm-ltr">$pagenow</td>';
|
61 |
+
echo '<td>' . esc_html( $data['pagenow'] ) . '</td>';
|
62 |
echo '</tr>';
|
63 |
|
64 |
$screens = array(
|
75 |
'users-network' => true,
|
76 |
);
|
77 |
|
78 |
+
// @TODO a lot of this logic can move to the collector
|
79 |
if ( !empty( $data['current_screen'] ) and isset( $screens[$data['current_screen']->base] ) ) {
|
80 |
|
81 |
# And now, WordPress' legendary inconsistency comes into play:
|
103 |
}
|
104 |
|
105 |
echo '<tr>';
|
106 |
+
echo '<td rowspan="2">' . esc_html__( 'Column Filters', 'query-monitor' ) . '</td>';
|
107 |
+
echo '<td colspan="2">manage_<span class="qm-current">' . esc_html( $cols ) . '</span>_columns</td>';
|
108 |
echo '</tr>';
|
109 |
echo '<tr>';
|
110 |
+
echo '<td colspan="2">manage_<span class="qm-current">' . esc_html( $data['current_screen']->id ) . '</span>_sortable_columns</td>';
|
111 |
echo '</tr>';
|
112 |
|
113 |
echo '<tr>';
|
114 |
+
echo '<td rowspan="1">' . esc_html__( 'Column Action', 'query-monitor' ) . '</td>';
|
115 |
+
echo '<td colspan="2">manage_<span class="qm-current">' . esc_html( $col ) . '</span>_custom_column</td>';
|
116 |
echo '</tr>';
|
117 |
|
118 |
}
|
output/html/assets.php
CHANGED
@@ -40,17 +40,17 @@ class QM_Output_Html_Assets extends QM_Output_Html {
|
|
40 |
|
41 |
echo '<thead>';
|
42 |
|
43 |
-
if ( 'scripts'
|
44 |
echo '<tr class="qm-totally-legit-spacer">';
|
45 |
echo '<td colspan="6"></td>';
|
46 |
echo '</tr>';
|
47 |
}
|
48 |
|
49 |
echo '<tr>';
|
50 |
-
echo '<th colspan="2">' . $type_label . '</th>';
|
51 |
-
echo '<th>' .
|
52 |
-
echo '<th>' .
|
53 |
-
echo '<th>' .
|
54 |
echo '</tr>';
|
55 |
echo '</thead>';
|
56 |
echo '<tbody>';
|
@@ -83,8 +83,8 @@ class QM_Output_Html_Assets extends QM_Output_Html {
|
|
83 |
|
84 |
if ( empty( $handles ) ) {
|
85 |
echo '<tr>';
|
86 |
-
echo '<td
|
87 |
-
echo '<td
|
88 |
echo '</tr>';
|
89 |
return;
|
90 |
}
|
@@ -92,14 +92,14 @@ class QM_Output_Html_Assets extends QM_Output_Html {
|
|
92 |
foreach ( $handles as $handle ) {
|
93 |
|
94 |
if ( in_array( $handle, $dependencies->done ) ) {
|
95 |
-
echo '<tr data-qm-subject="' . $handle . '">';
|
96 |
} else {
|
97 |
-
echo '<tr data-qm-subject="' . $handle . '" class="qm-warn">';
|
98 |
}
|
99 |
|
100 |
if ( $first ) {
|
101 |
$rowspan = count( $handles );
|
102 |
-
echo
|
103 |
}
|
104 |
|
105 |
$this->dependency_row( $dependencies->query( $handle ), $dependencies );
|
@@ -113,13 +113,13 @@ class QM_Output_Html_Assets extends QM_Output_Html {
|
|
113 |
protected function dependency_row( _WP_Dependency $script, WP_Dependencies $dependencies ) {
|
114 |
|
115 |
if ( empty( $script->ver ) ) {
|
116 |
-
$ver = '
|
117 |
} else {
|
118 |
-
$ver =
|
119 |
}
|
120 |
|
121 |
if ( empty( $script->src ) ) {
|
122 |
-
$src = '
|
123 |
} else {
|
124 |
$src = $script->src;
|
125 |
}
|
@@ -134,10 +134,10 @@ class QM_Output_Html_Assets extends QM_Output_Html {
|
|
134 |
}
|
135 |
}
|
136 |
|
137 |
-
echo '<td
|
138 |
-
echo '<td
|
139 |
-
echo '<td
|
140 |
-
echo '<td
|
141 |
|
142 |
}
|
143 |
|
@@ -177,7 +177,7 @@ class QM_Output_Html_Assets extends QM_Output_Html {
|
|
177 |
|
178 |
$data = $this->collector->get_data();
|
179 |
$args = array(
|
180 |
-
'title' => $this->collector->name()
|
181 |
);
|
182 |
|
183 |
if ( !empty( $data['broken'] ) or !empty( $data['missing'] ) ) {
|
40 |
|
41 |
echo '<thead>';
|
42 |
|
43 |
+
if ( 'scripts' !== $type ) {
|
44 |
echo '<tr class="qm-totally-legit-spacer">';
|
45 |
echo '<td colspan="6"></td>';
|
46 |
echo '</tr>';
|
47 |
}
|
48 |
|
49 |
echo '<tr>';
|
50 |
+
echo '<th colspan="2">' . esc_html( $type_label ) . '</th>';
|
51 |
+
echo '<th>' . esc_html__( 'Dependencies', 'query-monitor' ) . '</th>';
|
52 |
+
echo '<th>' . esc_html__( 'Dependents', 'query-monitor' ) . '</th>';
|
53 |
+
echo '<th>' . esc_html__( 'Version', 'query-monitor' ) . '</th>';
|
54 |
echo '</tr>';
|
55 |
echo '</thead>';
|
56 |
echo '<tbody>';
|
83 |
|
84 |
if ( empty( $handles ) ) {
|
85 |
echo '<tr>';
|
86 |
+
echo '<td class="qm-nowrap">' . esc_html( $label ) . '</td>';
|
87 |
+
echo '<td colspan="5"><em>' . esc_html__( 'none', 'query-monitor' ) . '</em></td>';
|
88 |
echo '</tr>';
|
89 |
return;
|
90 |
}
|
92 |
foreach ( $handles as $handle ) {
|
93 |
|
94 |
if ( in_array( $handle, $dependencies->done ) ) {
|
95 |
+
echo '<tr data-qm-subject="' . esc_attr( $handle ) . '">';
|
96 |
} else {
|
97 |
+
echo '<tr data-qm-subject="' . esc_attr( $handle ) . '" class="qm-warn">';
|
98 |
}
|
99 |
|
100 |
if ( $first ) {
|
101 |
$rowspan = count( $handles );
|
102 |
+
echo '<th rowspan="' . esc_attr( $rowspan ) . '" class="qm-nowrap">' . esc_html( $label ) . '</th>';
|
103 |
}
|
104 |
|
105 |
$this->dependency_row( $dependencies->query( $handle ), $dependencies );
|
113 |
protected function dependency_row( _WP_Dependency $script, WP_Dependencies $dependencies ) {
|
114 |
|
115 |
if ( empty( $script->ver ) ) {
|
116 |
+
$ver = '';
|
117 |
} else {
|
118 |
+
$ver = $script->ver;
|
119 |
}
|
120 |
|
121 |
if ( empty( $script->src ) ) {
|
122 |
+
$src = '';
|
123 |
} else {
|
124 |
$src = $script->src;
|
125 |
}
|
134 |
}
|
135 |
}
|
136 |
|
137 |
+
echo '<td class="qm-wrap">' . esc_html( $script->handle ) . '<br><span class="qm-info"> ' . esc_html( $src ) . '</span></td>';
|
138 |
+
echo '<td class="qm-nowrap qm-highlighter" data-qm-highlight="' . esc_attr( implode( ' ', $deps ) ) . '">' . implode( '<br>', array_map( 'esc_html', $deps ) ) . '</td>';
|
139 |
+
echo '<td class="qm-nowrap qm-highlighter" data-qm-highlight="' . esc_attr( implode( ' ', $dependents ) ) . '">' . implode( '<br>', array_map( 'esc_html', $dependents ) ) . '</td>';
|
140 |
+
echo '<td>' . esc_html( $ver ) . '</td>';
|
141 |
|
142 |
}
|
143 |
|
177 |
|
178 |
$data = $this->collector->get_data();
|
179 |
$args = array(
|
180 |
+
'title' => esc_html( $this->collector->name() ),
|
181 |
);
|
182 |
|
183 |
if ( !empty( $data['broken'] ) or !empty( $data['missing'] ) ) {
|
output/html/conditionals.php
CHANGED
@@ -33,7 +33,7 @@ class QM_Output_Html_Conditionals extends QM_Output_Html {
|
|
33 |
echo '<table cellspacing="0">';
|
34 |
echo '<thead>';
|
35 |
echo '<tr>';
|
36 |
-
echo '<th colspan="' . $cols . '">' . esc_html( $this->collector->name() ) . '</th>';
|
37 |
echo '</tr>';
|
38 |
echo '</thead>';
|
39 |
echo '<tbody>';
|
@@ -43,7 +43,7 @@ class QM_Output_Html_Conditionals extends QM_Output_Html {
|
|
43 |
if ( 1 === $i%$cols ) {
|
44 |
echo '<tr>';
|
45 |
}
|
46 |
-
echo '<td class="qm-ltr qm-true" width="' . $w . '%">' . $cond . '()</td>';
|
47 |
if ( 0 === $i%$cols ) {
|
48 |
echo '</tr>';
|
49 |
}
|
@@ -54,7 +54,7 @@ class QM_Output_Html_Conditionals extends QM_Output_Html {
|
|
54 |
if ( 1 === $i%$cols ) {
|
55 |
echo '<tr>';
|
56 |
}
|
57 |
-
echo '<td class="qm-ltr qm-false" width="' . $w . '%">' . $cond . '()</td>';
|
58 |
if ( 0 === $i%$cols ) {
|
59 |
echo '</tr>';
|
60 |
}
|
@@ -62,7 +62,7 @@ class QM_Output_Html_Conditionals extends QM_Output_Html {
|
|
62 |
|
63 |
$fill = ( $cols - ( $i % $cols ) );
|
64 |
if ( $fill and ( $fill != $cols ) ) {
|
65 |
-
echo '<td colspan="' . $fill . '"> </td>';
|
66 |
echo '</tr>';
|
67 |
}
|
68 |
|
@@ -78,8 +78,8 @@ class QM_Output_Html_Conditionals extends QM_Output_Html {
|
|
78 |
|
79 |
foreach ( $data['conds']['true'] as $cond ) {
|
80 |
$menu[] = $this->menu( array(
|
81 |
-
'title' => $cond . '()',
|
82 |
-
'id' => 'query-monitor-' . $cond,
|
83 |
'meta' => array( 'classname' => 'qm-true qm-ltr' )
|
84 |
) );
|
85 |
}
|
33 |
echo '<table cellspacing="0">';
|
34 |
echo '<thead>';
|
35 |
echo '<tr>';
|
36 |
+
echo '<th colspan="' . absint( $cols ) . '">' . esc_html( $this->collector->name() ) . '</th>';
|
37 |
echo '</tr>';
|
38 |
echo '</thead>';
|
39 |
echo '<tbody>';
|
43 |
if ( 1 === $i%$cols ) {
|
44 |
echo '<tr>';
|
45 |
}
|
46 |
+
echo '<td class="qm-ltr qm-true" width="' . absint( $w ) . '%">' . esc_html( $cond ) . '()</td>';
|
47 |
if ( 0 === $i%$cols ) {
|
48 |
echo '</tr>';
|
49 |
}
|
54 |
if ( 1 === $i%$cols ) {
|
55 |
echo '<tr>';
|
56 |
}
|
57 |
+
echo '<td class="qm-ltr qm-false" width="' . absint( $w ) . '%">' . esc_html( $cond ) . '()</td>';
|
58 |
if ( 0 === $i%$cols ) {
|
59 |
echo '</tr>';
|
60 |
}
|
62 |
|
63 |
$fill = ( $cols - ( $i % $cols ) );
|
64 |
if ( $fill and ( $fill != $cols ) ) {
|
65 |
+
echo '<td colspan="' . absint( $fill ) . '"> </td>';
|
66 |
echo '</tr>';
|
67 |
}
|
68 |
|
78 |
|
79 |
foreach ( $data['conds']['true'] as $cond ) {
|
80 |
$menu[] = $this->menu( array(
|
81 |
+
'title' => esc_html( $cond . '()' ),
|
82 |
+
'id' => 'query-monitor-conditionals-' . esc_attr( $cond ),
|
83 |
'meta' => array( 'classname' => 'qm-true qm-ltr' )
|
84 |
) );
|
85 |
}
|
output/html/db_callers.php
CHANGED
@@ -36,16 +36,22 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
|
|
36 |
echo '<table cellspacing="0" class="qm-sortable">';
|
37 |
echo '<thead>';
|
38 |
echo '<tr>';
|
39 |
-
echo '<th colspan="' . $span . '">' . esc_html( $this->collector->name() ) . '</th>';
|
40 |
echo '</tr>';
|
41 |
echo '<tr>';
|
42 |
-
echo '<th>' .
|
43 |
|
44 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
45 |
-
echo '<th class="qm-num">'
|
|
|
|
|
|
|
46 |
}
|
47 |
|
48 |
-
echo '<th class="qm-num qm-sorted-desc">'
|
|
|
|
|
|
|
49 |
echo '</tr>';
|
50 |
echo '</thead>';
|
51 |
|
@@ -58,17 +64,17 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
|
|
58 |
$stime = number_format_i18n( $row['ltime'], 4 );
|
59 |
|
60 |
echo '<tr>';
|
61 |
-
echo
|
62 |
|
63 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
64 |
if ( isset( $row['types'][$type_name] ) ) {
|
65 |
-
echo "<td
|
66 |
} else {
|
67 |
-
echo "<td
|
68 |
}
|
69 |
}
|
70 |
|
71 |
-
echo
|
72 |
echo '</tr>';
|
73 |
|
74 |
}
|
@@ -82,10 +88,10 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
|
|
82 |
echo '<td> </td>';
|
83 |
|
84 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
85 |
-
echo '<td class="qm-num">' . number_format_i18n( $type_count ) . '</td>';
|
86 |
}
|
87 |
|
88 |
-
echo
|
89 |
echo '</tr>';
|
90 |
|
91 |
echo '</tfoot>';
|
@@ -94,7 +100,7 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
|
|
94 |
|
95 |
echo '<tbody>';
|
96 |
echo '<tr>';
|
97 |
-
echo '<td colspan="3" style="text-align:center !important"><em>' .
|
98 |
echo '</tr>';
|
99 |
echo '</tbody>';
|
100 |
|
@@ -111,7 +117,7 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
|
|
111 |
$dbq_data = $dbq->get_data();
|
112 |
if ( isset( $dbq_data['times'] ) ) {
|
113 |
$menu[] = $this->menu( array(
|
114 |
-
'title' =>
|
115 |
) );
|
116 |
}
|
117 |
}
|
36 |
echo '<table cellspacing="0" class="qm-sortable">';
|
37 |
echo '<thead>';
|
38 |
echo '<tr>';
|
39 |
+
echo '<th colspan="' . absint( $span ) . '">' . esc_html( $this->collector->name() ) . '</th>';
|
40 |
echo '</tr>';
|
41 |
echo '<tr>';
|
42 |
+
echo '<th>' . esc_html_x( 'Caller', 'Query caller', 'query-monitor' ) . '</th>';
|
43 |
|
44 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
45 |
+
echo '<th class="qm-num">';
|
46 |
+
echo esc_html( $type_name );
|
47 |
+
echo $this->build_sorter(); // WPCS: XSS ok;
|
48 |
+
echo '</th>';
|
49 |
}
|
50 |
|
51 |
+
echo '<th class="qm-num qm-sorted-desc">';
|
52 |
+
esc_html_e( 'Time', 'query-monitor' );
|
53 |
+
echo $this->build_sorter(); // WPCS: XSS ok;
|
54 |
+
echo '</th>';
|
55 |
echo '</tr>';
|
56 |
echo '</thead>';
|
57 |
|
64 |
$stime = number_format_i18n( $row['ltime'], 4 );
|
65 |
|
66 |
echo '<tr>';
|
67 |
+
echo '<td class="qm-ltr">' . esc_html( $row['caller'] ) . '</td>';
|
68 |
|
69 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
70 |
if ( isset( $row['types'][$type_name] ) ) {
|
71 |
+
echo "<td class='qm-num'>" . esc_html( number_format_i18n( $row['types'][$type_name] ) ) . '</td>';
|
72 |
} else {
|
73 |
+
echo "<td class='qm-num'> </td>";
|
74 |
}
|
75 |
}
|
76 |
|
77 |
+
echo '<td class="qm-num">' . esc_html( $stime ) . '</td>';
|
78 |
echo '</tr>';
|
79 |
|
80 |
}
|
88 |
echo '<td> </td>';
|
89 |
|
90 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
91 |
+
echo '<td class="qm-num">' . esc_html( number_format_i18n( $type_count ) ) . '</td>';
|
92 |
}
|
93 |
|
94 |
+
echo '<td class="qm-num">' . esc_html( $total_stime ) . '</td>';
|
95 |
echo '</tr>';
|
96 |
|
97 |
echo '</tfoot>';
|
100 |
|
101 |
echo '<tbody>';
|
102 |
echo '<tr>';
|
103 |
+
echo '<td colspan="3" style="text-align:center !important"><em>' . esc_html__( 'none', 'query-monitor' ) . '</em></td>';
|
104 |
echo '</tr>';
|
105 |
echo '</tbody>';
|
106 |
|
117 |
$dbq_data = $dbq->get_data();
|
118 |
if ( isset( $dbq_data['times'] ) ) {
|
119 |
$menu[] = $this->menu( array(
|
120 |
+
'title' => esc_html__( 'Queries by Caller', 'query-monitor' )
|
121 |
) );
|
122 |
}
|
123 |
}
|
output/html/db_components.php
CHANGED
@@ -37,16 +37,22 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
|
|
37 |
echo '<table cellspacing="0" class="qm-sortable">';
|
38 |
echo '<thead>';
|
39 |
echo '<tr>';
|
40 |
-
echo '<th colspan="' . $span . '">' . esc_html( $this->collector->name() ) . '</th>';
|
41 |
echo '</tr>';
|
42 |
echo '<tr>';
|
43 |
-
echo '<th>' .
|
44 |
|
45 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
46 |
-
echo '<th class="qm-num">'
|
|
|
|
|
|
|
47 |
}
|
48 |
|
49 |
-
echo '<th class="qm-num qm-sorted-desc">'
|
|
|
|
|
|
|
50 |
echo '</tr>';
|
51 |
echo '</thead>';
|
52 |
|
@@ -57,20 +63,19 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
|
|
57 |
foreach ( $data['times'] as $row ) {
|
58 |
$total_time += $row['ltime'];
|
59 |
$total_calls += $row['calls'];
|
60 |
-
$stime = number_format_i18n( $row['ltime'], 4 );
|
61 |
|
62 |
echo '<tr>';
|
63 |
-
echo
|
64 |
|
65 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
66 |
if ( isset( $row['types'][$type_name] ) ) {
|
67 |
-
echo
|
68 |
} else {
|
69 |
-
echo
|
70 |
}
|
71 |
}
|
72 |
|
73 |
-
echo
|
74 |
echo '</tr>';
|
75 |
|
76 |
}
|
@@ -84,10 +89,10 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
|
|
84 |
echo '<td> </td>';
|
85 |
|
86 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
87 |
-
echo '<td class="qm-num">' . number_format_i18n( $type_count ) . '</td>';
|
88 |
}
|
89 |
|
90 |
-
echo
|
91 |
echo '</tr>';
|
92 |
echo '</tfoot>';
|
93 |
|
@@ -95,7 +100,7 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
|
|
95 |
|
96 |
echo '<tbody>';
|
97 |
echo '<tr>';
|
98 |
-
echo '<td colspan="' . $span . '" style="text-align:center !important"><em>' .
|
99 |
echo '</tr>';
|
100 |
echo '</tbody>';
|
101 |
|
@@ -112,7 +117,7 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
|
|
112 |
$dbq_data = $dbq->get_data();
|
113 |
if ( isset( $dbq_data['component_times'] ) ) {
|
114 |
$menu[] = $this->menu( array(
|
115 |
-
'title' =>
|
116 |
) );
|
117 |
}
|
118 |
}
|
37 |
echo '<table cellspacing="0" class="qm-sortable">';
|
38 |
echo '<thead>';
|
39 |
echo '<tr>';
|
40 |
+
echo '<th colspan="' . esc_attr( $span ) . '">' . esc_html( $this->collector->name() ) . '</th>';
|
41 |
echo '</tr>';
|
42 |
echo '<tr>';
|
43 |
+
echo '<th>' . esc_html_x( 'Component', 'Query component', 'query-monitor' ) . '</th>';
|
44 |
|
45 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
46 |
+
echo '<th class="qm-num">';
|
47 |
+
echo esc_html( $type_name );
|
48 |
+
echo $this->build_sorter(); // WPCS: XSS ok;
|
49 |
+
echo '</th>';
|
50 |
}
|
51 |
|
52 |
+
echo '<th class="qm-num qm-sorted-desc">';
|
53 |
+
esc_html_e( 'Time', 'query-monitor' );
|
54 |
+
echo $this->build_sorter(); // WPCS: XSS ok;
|
55 |
+
echo '</th>';
|
56 |
echo '</tr>';
|
57 |
echo '</thead>';
|
58 |
|
63 |
foreach ( $data['times'] as $row ) {
|
64 |
$total_time += $row['ltime'];
|
65 |
$total_calls += $row['calls'];
|
|
|
66 |
|
67 |
echo '<tr>';
|
68 |
+
echo '<td>' . esc_html( $row['component'] ) . '</td>';
|
69 |
|
70 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
71 |
if ( isset( $row['types'][$type_name] ) ) {
|
72 |
+
echo '<td class="qm-num">' . esc_html( number_format_i18n( $row['types'][ $type_name ] ) ) . '</td>';
|
73 |
} else {
|
74 |
+
echo '<td class="qm-num"> </td>';
|
75 |
}
|
76 |
}
|
77 |
|
78 |
+
echo '<td class="qm-num">' . esc_html( number_format_i18n( $row['ltime'], 4 ) ) . '</td>';
|
79 |
echo '</tr>';
|
80 |
|
81 |
}
|
89 |
echo '<td> </td>';
|
90 |
|
91 |
foreach ( $data['types'] as $type_name => $type_count ) {
|
92 |
+
echo '<td class="qm-num">' . esc_html( number_format_i18n( $type_count ) ) . '</td>';
|
93 |
}
|
94 |
|
95 |
+
echo '<td class="qm-num">' . esc_html( $total_stime ) . '</td>';
|
96 |
echo '</tr>';
|
97 |
echo '</tfoot>';
|
98 |
|
100 |
|
101 |
echo '<tbody>';
|
102 |
echo '<tr>';
|
103 |
+
echo '<td colspan="' . esc_attr( $span ) . '" style="text-align:center !important"><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></td>';
|
104 |
echo '</tr>';
|
105 |
echo '</tbody>';
|
106 |
|
117 |
$dbq_data = $dbq->get_data();
|
118 |
if ( isset( $dbq_data['component_times'] ) ) {
|
119 |
$menu[] = $this->menu( array(
|
120 |
+
'title' => esc_html__( 'Queries by Component', 'query-monitor' )
|
121 |
) );
|
122 |
}
|
123 |
}
|
output/html/db_queries.php
CHANGED
@@ -54,13 +54,16 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
54 |
echo '<table cellspacing="0">';
|
55 |
echo '<thead>';
|
56 |
echo '<tr>';
|
57 |
-
echo '<th>' .
|
58 |
echo '</tr>';
|
59 |
echo '</thead>';
|
60 |
echo '<tbody>';
|
61 |
echo '<tr>';
|
62 |
echo '<td class="qm-warn">';
|
63 |
-
|
|
|
|
|
|
|
64 |
echo '</td>';
|
65 |
echo '</tr>';
|
66 |
echo '</tbody>';
|
@@ -75,13 +78,13 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
75 |
echo '<table cellspacing="0">';
|
76 |
echo '<thead>';
|
77 |
echo '<tr>';
|
78 |
-
echo '<th colspan="4">' .
|
79 |
echo '</tr>';
|
80 |
echo '<tr>';
|
81 |
-
echo '<th>' .
|
82 |
-
echo '<th>' .
|
83 |
-
echo '<th>' .
|
84 |
-
echo '<th>' .
|
85 |
echo '</tr>';
|
86 |
echo '</thead>';
|
87 |
echo '<tbody>';
|
@@ -104,21 +107,25 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
104 |
echo '<table cellspacing="0">';
|
105 |
echo '<thead>';
|
106 |
echo '<tr>';
|
107 |
-
echo '<th colspan="5" class="qm-expensive">'
|
|
|
|
|
|
|
|
|
108 |
echo '</tr>';
|
109 |
echo '<tr>';
|
110 |
-
echo '<th scope="col">' .
|
111 |
-
echo '<th scope="col">' .
|
112 |
|
113 |
if ( isset( $expensive[0]['component'] ) ) {
|
114 |
-
echo '<th scope="col">' .
|
115 |
}
|
116 |
|
117 |
if ( isset( $expensive[0]['result'] ) ) {
|
118 |
-
echo '<th scope="col" class="qm-num">' .
|
119 |
}
|
120 |
|
121 |
-
echo '<th class="qm-num">' .
|
122 |
echo '</tr>';
|
123 |
echo '</thead>';
|
124 |
echo '<tbody>';
|
@@ -144,30 +151,50 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
144 |
$span++;
|
145 |
}
|
146 |
|
147 |
-
echo '<div class="qm qm-queries" id="' . esc_attr( $this->collector->id()
|
148 |
echo '<table cellspacing="0" class="qm-sortable">';
|
149 |
echo '<thead>';
|
150 |
echo '<tr>';
|
151 |
-
echo '<th colspan="' . $span . '">' . sprintf( __( '%s Queries', 'query-monitor' ), $name ) . '</th>';
|
152 |
echo '</tr>';
|
153 |
|
154 |
if ( !empty( $db->rows ) ) {
|
155 |
|
156 |
-
if ( ! $db->has_trace ) {
|
157 |
echo '<tr>';
|
158 |
-
echo '<td colspan="' . $span . '" class="qm-warn">'
|
|
|
|
|
|
|
159 |
'https://github.com/johnbillion/query-monitor/wiki/db.php-Symlink'
|
160 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
echo '</tr>';
|
162 |
}
|
163 |
|
164 |
echo '<tr>';
|
165 |
-
echo '<th scope="col" class="qm-sorted-asc"> '
|
166 |
-
echo
|
167 |
-
echo '
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
if ( $db->has_trace ) {
|
170 |
-
echo '<th scope="col">'
|
|
|
|
|
|
|
171 |
}
|
172 |
|
173 |
if ( $db->has_result ) {
|
@@ -176,10 +203,16 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
176 |
} else {
|
177 |
$class = '';
|
178 |
}
|
179 |
-
echo '<th scope="col" class="' . $class
|
|
|
|
|
|
|
180 |
}
|
181 |
|
182 |
-
echo '<th scope="col" class="qm-num">'
|
|
|
|
|
|
|
183 |
echo '</tr>';
|
184 |
|
185 |
}
|
@@ -200,13 +233,23 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
200 |
$total_stime = number_format_i18n( $db->total_time, 4 );
|
201 |
|
202 |
echo '<tr class="qm-items-shown qm-hide">';
|
203 |
-
echo '<td
|
204 |
-
|
|
|
|
|
|
|
|
|
|
|
205 |
echo '</tr>';
|
206 |
|
207 |
echo '<tr>';
|
208 |
-
echo '<td
|
209 |
-
echo
|
|
|
|
|
|
|
|
|
|
|
210 |
echo '</tr>';
|
211 |
echo '</tfoot>';
|
212 |
|
@@ -214,7 +257,7 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
214 |
|
215 |
echo '<tbody>';
|
216 |
echo '<tr>';
|
217 |
-
echo '<td colspan="' . $span . '" style="text-align:center !important"><em>' .
|
218 |
echo '</tr>';
|
219 |
echo '</tbody>';
|
220 |
|
@@ -239,7 +282,6 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
239 |
unset( $cols['stack'] );
|
240 |
}
|
241 |
|
242 |
-
$row_attr = array();
|
243 |
$stime = number_format_i18n( $row['ltime'], 4 );
|
244 |
$td = $this->collector->is_expensive( $row ) ? ' qm-expensive' : '';
|
245 |
|
@@ -249,14 +291,6 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
249 |
$sql = "<span class='qm-nonselectsql'>{$sql}</span>";
|
250 |
}
|
251 |
|
252 |
-
if ( is_wp_error( $row['result'] ) ) {
|
253 |
-
$error = $row['result']->get_error_message();
|
254 |
-
$result = "<td valign='top' class='qm-row-result qm-row-error'>{$error}</td>\n";
|
255 |
-
$row_attr['class'] = 'qm-warn';
|
256 |
-
} else {
|
257 |
-
$result = "<td valign='top' class='qm-row-result qm-num'>{$row['result']}</td>\n";
|
258 |
-
}
|
259 |
-
|
260 |
if ( isset( $row['trace'] ) ) {
|
261 |
|
262 |
$caller = $row['trace']->get_caller();
|
@@ -271,13 +305,19 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
271 |
|
272 |
} else {
|
273 |
|
274 |
-
$caller_name = $row['caller'];
|
275 |
$stack = explode( ', ', $row['stack'] );
|
276 |
$stack = array_reverse( $stack );
|
277 |
array_shift( $stack );
|
|
|
278 |
|
279 |
}
|
280 |
|
|
|
|
|
|
|
|
|
|
|
281 |
if ( isset( $cols['sql'] ) ) {
|
282 |
$row_attr['data-qm-type'] = $row['type'];
|
283 |
}
|
@@ -297,43 +337,52 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
297 |
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
298 |
}
|
299 |
|
300 |
-
echo "<tr{$attr}>";
|
301 |
|
302 |
if ( isset( $cols['row'] ) ) {
|
303 |
-
echo
|
304 |
}
|
305 |
|
306 |
if ( isset( $cols['sql'] ) ) {
|
307 |
-
|
|
|
|
|
308 |
}
|
309 |
|
310 |
if ( isset( $cols['caller'] ) ) {
|
311 |
-
echo "<td
|
312 |
|
313 |
-
echo $caller_name;
|
314 |
|
315 |
-
if ( !empty( $stack ) ) {
|
316 |
echo '<a href="#" class="qm-toggle" data-on="+" data-off="-">+</a>';
|
317 |
-
echo '<div class="qm-toggled">' . implode( '<br>', $stack ) . '</div>';
|
318 |
}
|
319 |
|
320 |
-
echo
|
321 |
}
|
322 |
|
323 |
if ( isset( $cols['stack'] ) ) {
|
324 |
-
echo '<td
|
|
|
|
|
325 |
}
|
326 |
|
327 |
if ( isset( $cols['component'] ) ) {
|
328 |
-
echo "<td
|
329 |
}
|
330 |
|
331 |
if ( isset( $cols['result'] ) ) {
|
332 |
-
|
|
|
|
|
|
|
|
|
|
|
333 |
}
|
334 |
|
335 |
if ( isset( $cols['time'] ) ) {
|
336 |
-
echo
|
337 |
}
|
338 |
|
339 |
echo '</tr>';
|
@@ -379,28 +428,38 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
|
379 |
$menu[] = $this->menu( array(
|
380 |
'id' => 'query-monitor-errors',
|
381 |
'href' => '#qm-query-errors',
|
382 |
-
'title' =>
|
|
|
|
|
|
|
383 |
) );
|
384 |
}
|
385 |
if ( $expensive = $this->collector->get_expensive() ) {
|
386 |
$menu[] = $this->menu( array(
|
387 |
'id' => 'query-monitor-expensive',
|
388 |
'href' => '#qm-query-expensive',
|
389 |
-
'title' =>
|
|
|
|
|
|
|
390 |
) );
|
391 |
}
|
392 |
|
393 |
if ( isset( $data['dbs'] ) and count( $data['dbs'] ) > 1 ) {
|
394 |
foreach ( $data['dbs'] as $name => $db ) {
|
395 |
$menu[] = $this->menu( array(
|
396 |
-
'
|
397 |
-
'
|
|
|
|
|
|
|
|
|
398 |
) );
|
399 |
}
|
400 |
} else {
|
401 |
$menu[] = $this->menu( array(
|
402 |
-
'title' =>
|
403 |
-
'href' => sprintf( '#%s-wpdb', $this->collector->id() ),
|
404 |
) );
|
405 |
}
|
406 |
|
54 |
echo '<table cellspacing="0">';
|
55 |
echo '<thead>';
|
56 |
echo '<tr>';
|
57 |
+
echo '<th>' . esc_html__( 'Database Queries', 'query-monitor' ) . '</th>';
|
58 |
echo '</tr>';
|
59 |
echo '</thead>';
|
60 |
echo '<tbody>';
|
61 |
echo '<tr>';
|
62 |
echo '<td class="qm-warn">';
|
63 |
+
printf( esc_html__( 'No database queries were logged because the %s constant is set to %s', 'query-monitor' ),
|
64 |
+
'<code>SAVEQUERIES</code>',
|
65 |
+
'<code>false</code>'
|
66 |
+
);
|
67 |
echo '</td>';
|
68 |
echo '</tr>';
|
69 |
echo '</tbody>';
|
78 |
echo '<table cellspacing="0">';
|
79 |
echo '<thead>';
|
80 |
echo '<tr>';
|
81 |
+
echo '<th colspan="4">' . esc_html__( 'Database Errors', 'query-monitor' ) . '</th>';
|
82 |
echo '</tr>';
|
83 |
echo '<tr>';
|
84 |
+
echo '<th>' . esc_html__( 'Query', 'query-monitor' ) . '</th>';
|
85 |
+
echo '<th>' . esc_html__( 'Call Stack', 'query-monitor' ) . '</th>';
|
86 |
+
echo '<th>' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
87 |
+
echo '<th>' . esc_html__( 'Error', 'query-monitor' ) . '</th>';
|
88 |
echo '</tr>';
|
89 |
echo '</thead>';
|
90 |
echo '<tbody>';
|
107 |
echo '<table cellspacing="0">';
|
108 |
echo '<thead>';
|
109 |
echo '<tr>';
|
110 |
+
echo '<th colspan="5" class="qm-expensive">';
|
111 |
+
printf( esc_html__( 'Slow Database Queries (above %ss)', 'query-monitor' ),
|
112 |
+
'<span class="qm-expensive">' . esc_html( number_format_i18n( QM_DB_EXPENSIVE, $dp ) ) . '</span>'
|
113 |
+
);
|
114 |
+
echo '</th>';
|
115 |
echo '</tr>';
|
116 |
echo '<tr>';
|
117 |
+
echo '<th scope="col">' . esc_html__( 'Query', 'query-monitor' ) . '</th>';
|
118 |
+
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
119 |
|
120 |
if ( isset( $expensive[0]['component'] ) ) {
|
121 |
+
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
122 |
}
|
123 |
|
124 |
if ( isset( $expensive[0]['result'] ) ) {
|
125 |
+
echo '<th scope="col" class="qm-num">' . esc_html__( 'Affected Rows', 'query-monitor' ) . '</th>';
|
126 |
}
|
127 |
|
128 |
+
echo '<th class="qm-num">' . esc_html__( 'Time', 'query-monitor' ) . '</th>';
|
129 |
echo '</tr>';
|
130 |
echo '</thead>';
|
131 |
echo '<tbody>';
|
151 |
$span++;
|
152 |
}
|
153 |
|
154 |
+
echo '<div class="qm qm-queries" id="' . esc_attr( $this->collector->id() . '-' . sanitize_title_with_dashes( $name ) ) . '">';
|
155 |
echo '<table cellspacing="0" class="qm-sortable">';
|
156 |
echo '<thead>';
|
157 |
echo '<tr>';
|
158 |
+
echo '<th colspan="' . absint( $span ) . '">' . esc_html( sprintf( __( '%s Queries', 'query-monitor' ), $name ) ) . '</th>';
|
159 |
echo '</tr>';
|
160 |
|
161 |
if ( !empty( $db->rows ) ) {
|
162 |
|
163 |
+
if ( ! $db->has_trace && ( '$wpdb' === $name ) ) {
|
164 |
echo '<tr>';
|
165 |
+
echo '<td colspan="' . absint( $span ) . '" class="qm-warn">';
|
166 |
+
echo wp_kses( sprintf(
|
167 |
+
__( 'Extended query information such as the component and affected rows is not available. Query Monitor was unable to symlink its %1$s file into place. <a href="%2$s" target="_blank">See this wiki page for more information.</a>', 'query-monitor' ),
|
168 |
+
'<code>db.php</code>',
|
169 |
'https://github.com/johnbillion/query-monitor/wiki/db.php-Symlink'
|
170 |
+
), array(
|
171 |
+
'a' => array(
|
172 |
+
'href' => array(),
|
173 |
+
'target' => array(),
|
174 |
+
),
|
175 |
+
) );
|
176 |
+
echo '</td>';
|
177 |
echo '</tr>';
|
178 |
}
|
179 |
|
180 |
echo '<tr>';
|
181 |
+
echo '<th scope="col" class="qm-sorted-asc"> ';
|
182 |
+
echo $this->build_sorter(); // WPCS: XSS ok;
|
183 |
+
echo '</th>';
|
184 |
+
echo '<th scope="col">';
|
185 |
+
esc_html_e( 'Query', 'query-monitor' );
|
186 |
+
echo $this->build_filter( 'type', array_keys( $db->types ) ); // WPCS: XSS ok;
|
187 |
+
echo '</th>';
|
188 |
+
echo '<th scope="col">';
|
189 |
+
esc_html_e( 'Caller', 'query-monitor' );
|
190 |
+
echo $this->build_filter( 'caller', wp_list_pluck( $data['times'], 'caller' ) ); // WPCS: XSS ok;
|
191 |
+
echo '</th>';
|
192 |
|
193 |
if ( $db->has_trace ) {
|
194 |
+
echo '<th scope="col">';
|
195 |
+
esc_html_e( 'Component', 'query-monitor' );
|
196 |
+
echo $this->build_filter( 'component', wp_list_pluck( $data['component_times'], 'component' ) ); // WPCS: XSS ok.
|
197 |
+
echo '</th>';
|
198 |
}
|
199 |
|
200 |
if ( $db->has_result ) {
|
203 |
} else {
|
204 |
$class = '';
|
205 |
}
|
206 |
+
echo '<th scope="col" class="' . esc_attr( $class ) . '">';
|
207 |
+
esc_html_e( 'Rows', 'query-monitor' );
|
208 |
+
echo $this->build_sorter(); // WPCS: XSS ok.
|
209 |
+
echo '</th>';
|
210 |
}
|
211 |
|
212 |
+
echo '<th scope="col" class="qm-num">';
|
213 |
+
esc_html_e( 'Time', 'query-monitor' );
|
214 |
+
echo $this->build_sorter(); // WPCS: XSS ok.
|
215 |
+
echo '</th>';
|
216 |
echo '</tr>';
|
217 |
|
218 |
}
|
233 |
$total_stime = number_format_i18n( $db->total_time, 4 );
|
234 |
|
235 |
echo '<tr class="qm-items-shown qm-hide">';
|
236 |
+
echo '<td colspan="' . absint( $span - 1 ) . '">';
|
237 |
+
printf(
|
238 |
+
esc_html__( 'Queries in filter: %s', 'query-monitor' ),
|
239 |
+
'<span class="qm-items-number">' . esc_html( number_format_i18n( $db->total_qs ) ) . '</span>'
|
240 |
+
);
|
241 |
+
echo '</td>';
|
242 |
+
echo '<td class="qm-items-time qm-num">' . esc_html( $total_stime ) . '</td>';
|
243 |
echo '</tr>';
|
244 |
|
245 |
echo '<tr>';
|
246 |
+
echo '<td colspan="' . absint( $span - 1 ) . '">';
|
247 |
+
echo esc_html( sprintf(
|
248 |
+
__( 'Total Queries: %s', 'query-monitor' ),
|
249 |
+
number_format_i18n( $db->total_qs )
|
250 |
+
) );
|
251 |
+
echo '</td>';
|
252 |
+
echo '<td class="qm-num">' . esc_html( $total_stime ) . '</td>';
|
253 |
echo '</tr>';
|
254 |
echo '</tfoot>';
|
255 |
|
257 |
|
258 |
echo '<tbody>';
|
259 |
echo '<tr>';
|
260 |
+
echo '<td colspan="' . absint( $span ) . '" style="text-align:center !important"><em>' . esc_html__( 'none', 'query-monitor' ) . '</em></td>';
|
261 |
echo '</tr>';
|
262 |
echo '</tbody>';
|
263 |
|
282 |
unset( $cols['stack'] );
|
283 |
}
|
284 |
|
|
|
285 |
$stime = number_format_i18n( $row['ltime'], 4 );
|
286 |
$td = $this->collector->is_expensive( $row ) ? ' qm-expensive' : '';
|
287 |
|
291 |
$sql = "<span class='qm-nonselectsql'>{$sql}</span>";
|
292 |
}
|
293 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
if ( isset( $row['trace'] ) ) {
|
295 |
|
296 |
$caller = $row['trace']->get_caller();
|
305 |
|
306 |
} else {
|
307 |
|
308 |
+
$caller_name = esc_html( $row['caller'] );
|
309 |
$stack = explode( ', ', $row['stack'] );
|
310 |
$stack = array_reverse( $stack );
|
311 |
array_shift( $stack );
|
312 |
+
$stack = array_map( 'esc_html', $stack );
|
313 |
|
314 |
}
|
315 |
|
316 |
+
$row_attr = array();
|
317 |
+
|
318 |
+
if ( is_wp_error( $row['result'] ) ) {
|
319 |
+
$row_attr['class'] = 'qm-warn';
|
320 |
+
}
|
321 |
if ( isset( $cols['sql'] ) ) {
|
322 |
$row_attr['data-qm-type'] = $row['type'];
|
323 |
}
|
337 |
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
338 |
}
|
339 |
|
340 |
+
echo "<tr{$attr}>"; // WPCS: XSS ok.
|
341 |
|
342 |
if ( isset( $cols['row'] ) ) {
|
343 |
+
echo '<td class="qm-row-num qm-num">' . absint( ++$this->query_row ) . '</td>';
|
344 |
}
|
345 |
|
346 |
if ( isset( $cols['sql'] ) ) {
|
347 |
+
printf( '<td class="qm-row-sql qm-ltr qm-wrap">%s</td>',
|
348 |
+
$sql
|
349 |
+
); // WPCS: XSS ok.
|
350 |
}
|
351 |
|
352 |
if ( isset( $cols['caller'] ) ) {
|
353 |
+
echo "<td class='qm-row-caller qm-ltr qm-has-toggle qm-nowrap'>";
|
354 |
|
355 |
+
echo $caller_name; // WPCS: XSS ok.
|
356 |
|
357 |
+
if ( ! empty( $stack ) ) {
|
358 |
echo '<a href="#" class="qm-toggle" data-on="+" data-off="-">+</a>';
|
359 |
+
echo '<div class="qm-toggled">' . implode( '<br>', $stack ) . '</div>'; // WPCS: XSS ok.
|
360 |
}
|
361 |
|
362 |
+
echo '</td>';
|
363 |
}
|
364 |
|
365 |
if ( isset( $cols['stack'] ) ) {
|
366 |
+
echo '<td class="qm-row-caller qm-row-stack qm-nowrap qm-ltr">';
|
367 |
+
echo $caller_name; // WPCS: XSS ok.
|
368 |
+
echo '<br>' . implode( '<br>', $stack ) . '</td>'; // WPCS: XSS ok.
|
369 |
}
|
370 |
|
371 |
if ( isset( $cols['component'] ) ) {
|
372 |
+
echo "<td class='qm-row-component qm-nowrap'>" . esc_html( $row['component']->name ) . "</td>\n";
|
373 |
}
|
374 |
|
375 |
if ( isset( $cols['result'] ) ) {
|
376 |
+
if ( is_wp_error( $row['result'] ) ) {
|
377 |
+
echo "<td class='qm-row-result qm-row-error'>" . esc_html( $row['result']->get_error_message() ) . "</td>\n";
|
378 |
+
} else {
|
379 |
+
echo "<td class='qm-row-result qm-num'>" . esc_html( $row['result'] ) . "</td>\n";
|
380 |
+
}
|
381 |
+
|
382 |
}
|
383 |
|
384 |
if ( isset( $cols['time'] ) ) {
|
385 |
+
echo '<td class="qm-num qm-row-time"' . esc_attr( $td ) . '">'. esc_html( $stime ) . "</td>\n";
|
386 |
}
|
387 |
|
388 |
echo '</tr>';
|
428 |
$menu[] = $this->menu( array(
|
429 |
'id' => 'query-monitor-errors',
|
430 |
'href' => '#qm-query-errors',
|
431 |
+
'title' => esc_html( sprintf(
|
432 |
+
__( 'Database Errors (%s)', 'query-monitor' ),
|
433 |
+
number_format_i18n( count( $errors ) )
|
434 |
+
) ),
|
435 |
) );
|
436 |
}
|
437 |
if ( $expensive = $this->collector->get_expensive() ) {
|
438 |
$menu[] = $this->menu( array(
|
439 |
'id' => 'query-monitor-expensive',
|
440 |
'href' => '#qm-query-expensive',
|
441 |
+
'title' => esc_html( sprintf(
|
442 |
+
__( 'Slow Queries (%s)', 'query-monitor' ),
|
443 |
+
number_format_i18n( count( $expensive ) )
|
444 |
+
) ),
|
445 |
) );
|
446 |
}
|
447 |
|
448 |
if ( isset( $data['dbs'] ) and count( $data['dbs'] ) > 1 ) {
|
449 |
foreach ( $data['dbs'] as $name => $db ) {
|
450 |
$menu[] = $this->menu( array(
|
451 |
+
'id' => esc_attr( sprintf( 'query-monitor-%s-db-%s', $this->collector->id(), sanitize_title_with_dashes( $name ) ) ),
|
452 |
+
'title' => esc_html( sprintf(
|
453 |
+
__( 'Queries - %s', 'query-monitor' ),
|
454 |
+
$name
|
455 |
+
) ),
|
456 |
+
'href' => esc_attr( sprintf( '#%s-%s', $this->collector->id(), sanitize_title_with_dashes( $name ) ) ),
|
457 |
) );
|
458 |
}
|
459 |
} else {
|
460 |
$menu[] = $this->menu( array(
|
461 |
+
'title' => esc_html__( 'Queries', 'query-monitor' ),
|
462 |
+
'href' => esc_attr( sprintf( '#%s-wpdb', $this->collector->id() ) ),
|
463 |
) );
|
464 |
}
|
465 |
|
output/html/debug_bar.php
CHANGED
@@ -35,7 +35,7 @@ class QM_Output_Html_Debug_Bar extends QM_Output_Html {
|
|
35 |
echo '<tbody>';
|
36 |
|
37 |
echo '<tr>';
|
38 |
-
echo '<td
|
39 |
echo '<div id="debug-menu-target-' . esc_attr( $target ) . '" class="debug-menu-target qm-debug-bar-output">';
|
40 |
|
41 |
$this->collector->render();
|
35 |
echo '<tbody>';
|
36 |
|
37 |
echo '<tr>';
|
38 |
+
echo '<td>';
|
39 |
echo '<div id="debug-menu-target-' . esc_attr( $target ) . '" class="debug-menu-target qm-debug-bar-output">';
|
40 |
|
41 |
$this->collector->render();
|
output/html/environment.php
CHANGED
@@ -38,36 +38,58 @@ class QM_Output_Html_Environment extends QM_Output_Html {
|
|
38 |
|
39 |
echo '<tr>';
|
40 |
echo '<td>version</td>';
|
41 |
-
echo
|
42 |
echo '</tr>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
echo '<tr>';
|
44 |
echo '<td>user</td>';
|
45 |
if ( !empty( $data['php']['user'] ) ) {
|
46 |
echo '<td>' . esc_html( $data['php']['user'] ) . '</td>';
|
47 |
} else {
|
48 |
-
echo '<td><em>' .
|
49 |
}
|
50 |
echo '</tr>';
|
51 |
|
52 |
foreach ( $data['php']['variables'] as $key => $val ) {
|
53 |
|
54 |
-
|
|
|
|
|
|
|
55 |
|
56 |
if ( $val['after'] != $val['before'] ) {
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
}
|
59 |
|
60 |
-
echo '
|
61 |
-
echo "<td>{$key}</td>";
|
62 |
-
echo "<td>{$val['after']}{$append}</td>";
|
63 |
echo '</tr>';
|
64 |
}
|
65 |
|
66 |
-
$error_levels = implode( '<br
|
67 |
|
68 |
echo '<tr>';
|
69 |
echo '<td>error_reporting</td>';
|
70 |
-
echo
|
|
|
|
|
71 |
echo '</tr>';
|
72 |
|
73 |
echo '</tbody>';
|
@@ -79,9 +101,9 @@ class QM_Output_Html_Environment extends QM_Output_Html {
|
|
79 |
foreach ( $data['db'] as $id => $db ) {
|
80 |
|
81 |
if ( 1 == count( $data['db'] ) ) {
|
82 |
-
$name = 'Database';
|
83 |
} else {
|
84 |
-
$name = 'Database: '
|
85 |
}
|
86 |
|
87 |
echo '<div class="qm qm-half">';
|
@@ -93,42 +115,31 @@ class QM_Output_Html_Environment extends QM_Output_Html {
|
|
93 |
echo '</thead>';
|
94 |
echo '<tbody>';
|
95 |
|
96 |
-
|
97 |
-
echo '<td>driver</td>';
|
98 |
-
echo '<td>' . $db['driver'] . '</td>';
|
99 |
-
echo '</tr>';
|
100 |
|
101 |
-
|
102 |
-
|
103 |
-
echo '<td>' . $db['version'] . '</td>';
|
104 |
-
echo '</tr>';
|
105 |
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
|
|
110 |
|
111 |
-
|
112 |
-
echo '<td>host</td>';
|
113 |
-
echo '<td>' . $db['host'] . '</td>';
|
114 |
-
echo '</tr>';
|
115 |
|
116 |
-
|
117 |
-
echo '<td>database</td>';
|
118 |
-
echo '<td>' . $db['name'] . '</td>';
|
119 |
-
echo '</tr>';
|
120 |
|
121 |
echo '<tr>';
|
122 |
|
123 |
$first = true;
|
124 |
-
$warn = __( "This value may not be optimal. Check the recommended configuration for '%s'.", 'query-monitor' );
|
125 |
$search = __( 'https://www.google.com/search?q=mysql+performance+%s', 'query-monitor' );
|
126 |
|
127 |
foreach ( $db['variables'] as $setting ) {
|
128 |
|
129 |
$key = $setting->Variable_name;
|
130 |
$val = $setting->Value;
|
131 |
-
$
|
132 |
$show_warning = false;
|
133 |
|
134 |
if ( ( true === $db['vars'][$key] ) and empty( $val ) ) {
|
@@ -138,24 +149,31 @@ class QM_Output_Html_Environment extends QM_Output_Html {
|
|
138 |
}
|
139 |
|
140 |
if ( $show_warning ) {
|
141 |
-
$
|
|
|
|
|
|
|
|
|
142 |
}
|
143 |
|
144 |
if ( is_numeric( $val ) and ( $val >= ( 1024*1024 ) ) ) {
|
145 |
-
$
|
|
|
|
|
|
|
146 |
}
|
147 |
|
148 |
$class = ( $show_warning ) ? 'qm-warn' : '';
|
149 |
|
150 |
if ( !$first ) {
|
151 |
-
echo
|
152 |
}
|
153 |
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
echo
|
158 |
-
echo
|
159 |
|
160 |
echo '</tr>';
|
161 |
|
@@ -183,8 +201,8 @@ class QM_Output_Html_Environment extends QM_Output_Html {
|
|
183 |
foreach ( $data['wp'] as $key => $val ) {
|
184 |
|
185 |
echo '<tr>';
|
186 |
-
echo
|
187 |
-
echo
|
188 |
echo '</tr>';
|
189 |
|
190 |
}
|
@@ -197,37 +215,37 @@ class QM_Output_Html_Environment extends QM_Output_Html {
|
|
197 |
echo '<table cellspacing="0">';
|
198 |
echo '<thead>';
|
199 |
echo '<tr>';
|
200 |
-
echo '<th colspan="2">' .
|
201 |
echo '</tr>';
|
202 |
echo '</thead>';
|
203 |
echo '<tbody>';
|
204 |
|
205 |
echo '<tr>';
|
206 |
-
echo '<td>software</td>';
|
207 |
-
echo
|
208 |
echo '</tr>';
|
209 |
|
210 |
echo '<tr>';
|
211 |
-
echo '<td>version</td>';
|
212 |
if ( !empty( $data['server']['version'] ) ) {
|
213 |
echo '<td>' . esc_html( $data['server']['version'] ) . '</td>';
|
214 |
} else {
|
215 |
-
echo '<td><em>' .
|
216 |
}
|
217 |
echo '</tr>';
|
218 |
|
219 |
echo '<tr>';
|
220 |
-
echo '<td>address</td>';
|
221 |
if ( !empty( $data['server']['address'] ) ) {
|
222 |
echo '<td>' . esc_html( $data['server']['address'] ) . '</td>';
|
223 |
} else {
|
224 |
-
echo '<td><em>' .
|
225 |
}
|
226 |
echo '</tr>';
|
227 |
|
228 |
echo '<tr>';
|
229 |
-
echo '<td>host</td>';
|
230 |
-
echo
|
231 |
echo '</tr>';
|
232 |
|
233 |
echo '</tbody>';
|
38 |
|
39 |
echo '<tr>';
|
40 |
echo '<td>version</td>';
|
41 |
+
echo '<td>' . esc_html( $data['php']['version'] ) . '</td>';
|
42 |
echo '</tr>';
|
43 |
+
|
44 |
+
echo '<tr>';
|
45 |
+
echo '<td>sapi</td>';
|
46 |
+
echo '<td>' . esc_html( $data['php']['sapi'] ) . '</td>';
|
47 |
+
echo '</tr>';
|
48 |
+
|
49 |
+
if ( isset( $data['php']['hhvm'] ) ) {
|
50 |
+
echo '<tr>';
|
51 |
+
echo '<td>hhvm</td>';
|
52 |
+
echo '<td>' . esc_html( $data['php']['hhvm'] ) . '</td>';
|
53 |
+
echo '</tr>';
|
54 |
+
}
|
55 |
+
|
56 |
echo '<tr>';
|
57 |
echo '<td>user</td>';
|
58 |
if ( !empty( $data['php']['user'] ) ) {
|
59 |
echo '<td>' . esc_html( $data['php']['user'] ) . '</td>';
|
60 |
} else {
|
61 |
+
echo '<td><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></td>';
|
62 |
}
|
63 |
echo '</tr>';
|
64 |
|
65 |
foreach ( $data['php']['variables'] as $key => $val ) {
|
66 |
|
67 |
+
echo '<tr>';
|
68 |
+
echo '<td>' . esc_html( $key ) . '</td>';
|
69 |
+
echo '<td>';
|
70 |
+
echo esc_html( $val['after'] );
|
71 |
|
72 |
if ( $val['after'] != $val['before'] ) {
|
73 |
+
printf(
|
74 |
+
'<br><span class="qm-info"> %s</span>',
|
75 |
+
esc_html( sprintf(
|
76 |
+
__( 'Overridden at runtime from %s', 'query-monitor' ),
|
77 |
+
$val['before']
|
78 |
+
) )
|
79 |
+
);
|
80 |
}
|
81 |
|
82 |
+
echo '</td>';
|
|
|
|
|
83 |
echo '</tr>';
|
84 |
}
|
85 |
|
86 |
+
$error_levels = implode( '<br> ', array_map( 'esc_html', $this->collector->get_error_levels( $data['php']['error_reporting'] ) ) );
|
87 |
|
88 |
echo '<tr>';
|
89 |
echo '<td>error_reporting</td>';
|
90 |
+
echo '<td>' . esc_html( $data['php']['error_reporting'] ) . '<br><span class="qm-info"> ';
|
91 |
+
echo $error_levels; // WPCS: XSS ok.
|
92 |
+
echo '</span></td>';
|
93 |
echo '</tr>';
|
94 |
|
95 |
echo '</tbody>';
|
101 |
foreach ( $data['db'] as $id => $db ) {
|
102 |
|
103 |
if ( 1 == count( $data['db'] ) ) {
|
104 |
+
$name = __( 'Database', 'query-monitor' );
|
105 |
} else {
|
106 |
+
$name = sprintf( __( 'Database: %s', 'query-monitor' ), $id );
|
107 |
}
|
108 |
|
109 |
echo '<div class="qm qm-half">';
|
115 |
echo '</thead>';
|
116 |
echo '<tbody>';
|
117 |
|
118 |
+
foreach ( $db['info'] as $key => $value ) {
|
|
|
|
|
|
|
119 |
|
120 |
+
echo '<tr>';
|
121 |
+
echo '<td>' . esc_html( $key ) . '</td>';
|
|
|
|
|
122 |
|
123 |
+
if ( ! isset( $value ) ) {
|
124 |
+
echo '<td><span class="qm-warn">' . esc_html__( 'Unknown', 'query-monitor' ) . '</span></td>';
|
125 |
+
} else {
|
126 |
+
echo '<td>' . esc_html( $value ) . '</td>';
|
127 |
+
}
|
128 |
|
129 |
+
echo '</tr>';
|
|
|
|
|
|
|
130 |
|
131 |
+
}
|
|
|
|
|
|
|
132 |
|
133 |
echo '<tr>';
|
134 |
|
135 |
$first = true;
|
|
|
136 |
$search = __( 'https://www.google.com/search?q=mysql+performance+%s', 'query-monitor' );
|
137 |
|
138 |
foreach ( $db['variables'] as $setting ) {
|
139 |
|
140 |
$key = $setting->Variable_name;
|
141 |
$val = $setting->Value;
|
142 |
+
$append = '';
|
143 |
$show_warning = false;
|
144 |
|
145 |
if ( ( true === $db['vars'][$key] ) and empty( $val ) ) {
|
149 |
}
|
150 |
|
151 |
if ( $show_warning ) {
|
152 |
+
$append .= sprintf(
|
153 |
+
' <span class="qm-info">(<a href="%s" target="_blank">%s</a>)</span>',
|
154 |
+
esc_url( sprintf( $search, $key ) ),
|
155 |
+
esc_html__( 'Help', 'query-monitor' )
|
156 |
+
);
|
157 |
}
|
158 |
|
159 |
if ( is_numeric( $val ) and ( $val >= ( 1024*1024 ) ) ) {
|
160 |
+
$append .= sprintf(
|
161 |
+
'<br><span class="qm-info"> ~%s</span>',
|
162 |
+
esc_html( size_format( $val ) )
|
163 |
+
);
|
164 |
}
|
165 |
|
166 |
$class = ( $show_warning ) ? 'qm-warn' : '';
|
167 |
|
168 |
if ( !$first ) {
|
169 |
+
echo '<tr class="' . esc_attr( $class ) . '"">';
|
170 |
}
|
171 |
|
172 |
+
echo '<td>' . esc_html( $key ) . '</td>';
|
173 |
+
echo '<td>';
|
174 |
+
echo esc_html( $val );
|
175 |
+
echo $append; // WPCS: XSS ok.
|
176 |
+
echo '</td>';
|
177 |
|
178 |
echo '</tr>';
|
179 |
|
201 |
foreach ( $data['wp'] as $key => $val ) {
|
202 |
|
203 |
echo '<tr>';
|
204 |
+
echo '<td>' . esc_html( $key ) . '</td>';
|
205 |
+
echo '<td>' . esc_html( $val ) . '</td>';
|
206 |
echo '</tr>';
|
207 |
|
208 |
}
|
215 |
echo '<table cellspacing="0">';
|
216 |
echo '<thead>';
|
217 |
echo '<tr>';
|
218 |
+
echo '<th colspan="2">' . esc_html__( 'Server', 'query-monitor' ) . '</th>';
|
219 |
echo '</tr>';
|
220 |
echo '</thead>';
|
221 |
echo '<tbody>';
|
222 |
|
223 |
echo '<tr>';
|
224 |
+
echo '<td>' . esc_html__( 'software', 'query-monitor' ) . '</td>';
|
225 |
+
echo '<td>' . esc_html( $data['server']['name'] ) . '</td>';
|
226 |
echo '</tr>';
|
227 |
|
228 |
echo '<tr>';
|
229 |
+
echo '<td>' . esc_html__( 'version', 'query-monitor' ) . '</td>';
|
230 |
if ( !empty( $data['server']['version'] ) ) {
|
231 |
echo '<td>' . esc_html( $data['server']['version'] ) . '</td>';
|
232 |
} else {
|
233 |
+
echo '<td><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></td>';
|
234 |
}
|
235 |
echo '</tr>';
|
236 |
|
237 |
echo '<tr>';
|
238 |
+
echo '<td>' . esc_html__( 'address', 'query-monitor' ) . '</td>';
|
239 |
if ( !empty( $data['server']['address'] ) ) {
|
240 |
echo '<td>' . esc_html( $data['server']['address'] ) . '</td>';
|
241 |
} else {
|
242 |
+
echo '<td><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></td>';
|
243 |
}
|
244 |
echo '</tr>';
|
245 |
|
246 |
echo '<tr>';
|
247 |
+
echo '<td>' . esc_html__( 'host', 'query-monitor' ) . '</td>';
|
248 |
+
echo '<td>' . esc_html( $data['server']['host'] ) . '</td>';
|
249 |
echo '</tr>';
|
250 |
|
251 |
echo '</tbody>';
|
output/html/hooks.php
CHANGED
@@ -21,7 +21,6 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
|
|
21 |
public function __construct( QM_Collector $collector ) {
|
22 |
parent::__construct( $collector );
|
23 |
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 80 );
|
24 |
-
add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
|
25 |
}
|
26 |
|
27 |
public function output() {
|
@@ -32,8 +31,6 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
|
|
32 |
return;
|
33 |
}
|
34 |
|
35 |
-
$row_attr = array();
|
36 |
-
|
37 |
if ( is_multisite() and is_network_admin() ) {
|
38 |
$screen = preg_replace( '|-network$|', '', $data['screen'] );
|
39 |
} else {
|
@@ -44,8 +41,14 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
|
|
44 |
echo '<table cellspacing="0">';
|
45 |
echo '<thead>';
|
46 |
echo '<tr>';
|
47 |
-
echo '<th>'
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
echo '</tr>';
|
50 |
echo '</thead>';
|
51 |
echo '<tbody>';
|
@@ -55,13 +58,16 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
|
|
55 |
if ( !empty( $screen ) ) {
|
56 |
|
57 |
if ( false !== strpos( $hook['name'], $screen . '.php' ) ) {
|
58 |
-
$
|
59 |
} else {
|
60 |
-
$
|
61 |
}
|
62 |
|
|
|
|
|
63 |
}
|
64 |
|
|
|
65 |
$row_attr['data-qm-name'] = implode( ' ', $hook['parts'] );
|
66 |
$row_attr['data-qm-component'] = implode( ' ', $hook['components'] );
|
67 |
|
@@ -89,42 +95,48 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
|
|
89 |
$component = '';
|
90 |
}
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
|
|
|
|
95 |
|
96 |
if ( $first ) {
|
97 |
|
98 |
-
echo "<th
|
99 |
-
echo $
|
100 |
if ( 'all' === $hook['name'] ) {
|
101 |
echo '<br><span class="qm-warn">';
|
102 |
-
|
|
|
|
|
|
|
103 |
echo '<span>';
|
104 |
}
|
105 |
echo '</th>';
|
106 |
|
107 |
}
|
108 |
|
109 |
-
echo '<td
|
110 |
-
echo '<td
|
111 |
|
112 |
if ( isset( $action['callback']['file'] ) ) {
|
113 |
-
echo self::output_filename(
|
114 |
} else {
|
115 |
echo esc_html( $action['callback']['name'] );
|
116 |
}
|
117 |
|
118 |
if ( isset( $action['callback']['error'] ) ) {
|
119 |
echo '<br><span class="qm-warn">';
|
120 |
-
|
121 |
-
|
122 |
-
|
|
|
123 |
echo '<span>';
|
124 |
}
|
125 |
|
126 |
echo '</td>';
|
127 |
-
echo '<td
|
128 |
echo esc_html( $component );
|
129 |
echo '</td>';
|
130 |
echo '</tr>';
|
@@ -132,9 +144,9 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
|
|
132 |
}
|
133 |
|
134 |
} else {
|
135 |
-
echo "<tr{$attr}>";
|
136 |
-
echo "<th
|
137 |
-
echo $
|
138 |
echo '</th>';
|
139 |
echo '<td colspan="3"> </td>';
|
140 |
echo '</tr>';
|
@@ -148,35 +160,6 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
|
|
148 |
|
149 |
}
|
150 |
|
151 |
-
public function admin_class( array $class ) {
|
152 |
-
|
153 |
-
$data = $this->collector->get_data();
|
154 |
-
|
155 |
-
if ( isset( $data['warnings'] ) ) {
|
156 |
-
$class[] = 'qm-warning';
|
157 |
-
}
|
158 |
-
|
159 |
-
return $class;
|
160 |
-
|
161 |
-
}
|
162 |
-
|
163 |
-
public function admin_menu( array $menu ) {
|
164 |
-
|
165 |
-
$data = $this->collector->get_data();
|
166 |
-
$args = array(
|
167 |
-
'title' => $this->collector->name(),
|
168 |
-
);
|
169 |
-
|
170 |
-
if ( isset( $data['warnings'] ) ) {
|
171 |
-
$args['meta']['classname'] = 'qm-warning';
|
172 |
-
}
|
173 |
-
|
174 |
-
$menu[] = $this->menu( $args );
|
175 |
-
|
176 |
-
return $menu;
|
177 |
-
|
178 |
-
}
|
179 |
-
|
180 |
}
|
181 |
|
182 |
function register_qm_output_html_hooks( array $output, QM_Collectors $collectors ) {
|
21 |
public function __construct( QM_Collector $collector ) {
|
22 |
parent::__construct( $collector );
|
23 |
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 80 );
|
|
|
24 |
}
|
25 |
|
26 |
public function output() {
|
31 |
return;
|
32 |
}
|
33 |
|
|
|
|
|
34 |
if ( is_multisite() and is_network_admin() ) {
|
35 |
$screen = preg_replace( '|-network$|', '', $data['screen'] );
|
36 |
} else {
|
41 |
echo '<table cellspacing="0">';
|
42 |
echo '<thead>';
|
43 |
echo '<tr>';
|
44 |
+
echo '<th>';
|
45 |
+
esc_html_e( 'Hook', 'query-monitor' );
|
46 |
+
echo $this->build_filter( 'name', $data['parts'] ); // WPCS: XSS ok.
|
47 |
+
echo '</th>';
|
48 |
+
echo '<th colspan="3">';
|
49 |
+
esc_html_e( 'Actions', 'query-monitor' );
|
50 |
+
echo $this->build_filter( 'component', $data['components'], 'subject' ); // WPCS: XSS ok.
|
51 |
+
echo '</th>';
|
52 |
echo '</tr>';
|
53 |
echo '</thead>';
|
54 |
echo '<tbody>';
|
58 |
if ( !empty( $screen ) ) {
|
59 |
|
60 |
if ( false !== strpos( $hook['name'], $screen . '.php' ) ) {
|
61 |
+
$hook_name = str_replace( '-' . $screen . '.php', '-<span class="qm-current">' . $screen . '.php</span>', esc_html( $hook['name'] ) );
|
62 |
} else {
|
63 |
+
$hook_name = str_replace( '-' . $screen, '-<span class="qm-current">' . $screen . '</span>', esc_html( $hook['name'] ) );
|
64 |
}
|
65 |
|
66 |
+
} else {
|
67 |
+
$hook_name = esc_html( $hook['name'] );
|
68 |
}
|
69 |
|
70 |
+
$row_attr = array();
|
71 |
$row_attr['data-qm-name'] = implode( ' ', $hook['parts'] );
|
72 |
$row_attr['data-qm-component'] = implode( ' ', $hook['components'] );
|
73 |
|
95 |
$component = '';
|
96 |
}
|
97 |
|
98 |
+
printf(
|
99 |
+
'<tr data-qm-subject="%s" %s>',
|
100 |
+
esc_attr( $component ),
|
101 |
+
$attr
|
102 |
+
); // WPCS: XSS ok.
|
103 |
|
104 |
if ( $first ) {
|
105 |
|
106 |
+
echo "<th rowspan='" . absint( $rowspan ) . "'>";
|
107 |
+
echo $hook_name; // WPCS: XSS ok.
|
108 |
if ( 'all' === $hook['name'] ) {
|
109 |
echo '<br><span class="qm-warn">';
|
110 |
+
printf(
|
111 |
+
esc_html__( 'Warning: The %s action is extremely resource intensive. Try to avoid using it.', 'query-monitor' ),
|
112 |
+
'<code>all</code>'
|
113 |
+
);
|
114 |
echo '<span>';
|
115 |
}
|
116 |
echo '</th>';
|
117 |
|
118 |
}
|
119 |
|
120 |
+
echo '<td class="qm-num">' . intval( $action['priority'] ) . '</td>';
|
121 |
+
echo '<td class="qm-ltr qm-nowrap">';
|
122 |
|
123 |
if ( isset( $action['callback']['file'] ) ) {
|
124 |
+
echo self::output_filename( $action['callback']['name'], $action['callback']['file'], $action['callback']['line'] ); // WPCS: XSS ok.
|
125 |
} else {
|
126 |
echo esc_html( $action['callback']['name'] );
|
127 |
}
|
128 |
|
129 |
if ( isset( $action['callback']['error'] ) ) {
|
130 |
echo '<br><span class="qm-warn">';
|
131 |
+
echo esc_html( sprintf(
|
132 |
+
__( 'Error: %s', 'query-monitor' ),
|
133 |
+
$action['callback']['error']->get_error_message()
|
134 |
+
) );
|
135 |
echo '<span>';
|
136 |
}
|
137 |
|
138 |
echo '</td>';
|
139 |
+
echo '<td class="qm-nowrap">';
|
140 |
echo esc_html( $component );
|
141 |
echo '</td>';
|
142 |
echo '</tr>';
|
144 |
}
|
145 |
|
146 |
} else {
|
147 |
+
echo "<tr{$attr}>"; // WPCS: XSS ok.
|
148 |
+
echo "<th>";
|
149 |
+
echo $hook_name; // WPCS: XSS ok.
|
150 |
echo '</th>';
|
151 |
echo '<td colspan="3"> </td>';
|
152 |
echo '</tr>';
|
160 |
|
161 |
}
|
162 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
}
|
164 |
|
165 |
function register_qm_output_html_hooks( array $output, QM_Collectors $collectors ) {
|
output/html/http.php
CHANGED
@@ -32,25 +32,33 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
32 |
echo '<table cellspacing="0" class="qm-sortable">';
|
33 |
echo '<thead>';
|
34 |
echo '<tr>';
|
35 |
-
echo '<th class="qm-sorted-asc"> '
|
36 |
-
echo
|
37 |
-
echo '
|
38 |
-
echo '<th scope="col">' .
|
39 |
-
echo '<th scope="col">' .
|
40 |
-
echo
|
41 |
-
echo '
|
42 |
-
echo '<th scope="col"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
echo '</tr>';
|
44 |
echo '</thead>';
|
45 |
|
46 |
-
$vars =
|
47 |
|
48 |
if ( !empty( $data['vars'] ) ) {
|
49 |
-
$vars = array();
|
50 |
foreach ( $data['vars'] as $key => $value ) {
|
51 |
-
$vars[] = $key . ': ' .
|
52 |
}
|
53 |
-
$vars = implode( '<br>', $vars );
|
54 |
}
|
55 |
|
56 |
if ( !empty( $data['http'] ) ) {
|
@@ -64,14 +72,8 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
64 |
|
65 |
$row_attr = array();
|
66 |
|
67 |
-
if ( empty( $ltime ) ) {
|
68 |
-
$stime = '';
|
69 |
-
} else {
|
70 |
-
$stime = number_format_i18n( $ltime, 4 );
|
71 |
-
}
|
72 |
-
|
73 |
if ( is_wp_error( $row['response'] ) ) {
|
74 |
-
$response =
|
75 |
$css = 'qm-warn';
|
76 |
} else {
|
77 |
$response = wp_remote_retrieve_response_code( $row['response'] );
|
@@ -81,7 +83,7 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
81 |
if ( empty( $response ) ) {
|
82 |
$response = __( 'n/a', 'query-monitor' );
|
83 |
} else {
|
84 |
-
$response =
|
85 |
}
|
86 |
|
87 |
if ( intval( $response ) >= 400 ) {
|
@@ -102,9 +104,16 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
102 |
$transport = '';
|
103 |
}
|
104 |
|
105 |
-
$stack = $row['trace']->get_stack();
|
106 |
$component = $row['component'];
|
107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
$row_attr['data-qm-component'] = $component->name;
|
109 |
$row_attr['data-qm-type'] = $row['type'];
|
110 |
|
@@ -113,19 +122,52 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
113 |
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
114 |
}
|
115 |
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
}
|
130 |
|
131 |
echo '</tbody>';
|
@@ -134,8 +176,11 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
134 |
$total_stime = number_format_i18n( $data['ltime'], 4 );
|
135 |
|
136 |
echo '<tr>';
|
137 |
-
|
138 |
-
|
|
|
|
|
|
|
139 |
echo '</tr>';
|
140 |
echo '</tfoot>';
|
141 |
|
@@ -143,11 +188,14 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
143 |
|
144 |
echo '<tbody>';
|
145 |
echo '<tr>';
|
146 |
-
echo '<td colspan="8" style="text-align:center !important"><em>' .
|
147 |
echo '</tr>';
|
148 |
if ( !empty( $vars ) ) {
|
149 |
echo '<tr>';
|
150 |
-
|
|
|
|
|
|
|
151 |
echo '</tr>';
|
152 |
}
|
153 |
echo '</tbody>';
|
@@ -184,7 +232,10 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
|
|
184 |
: __( 'HTTP Requests (%s)', 'query-monitor' );
|
185 |
|
186 |
$args = array(
|
187 |
-
'title' =>
|
|
|
|
|
|
|
188 |
);
|
189 |
|
190 |
if ( isset( $data['errors']['error'] ) ) {
|
32 |
echo '<table cellspacing="0" class="qm-sortable">';
|
33 |
echo '<thead>';
|
34 |
echo '<tr>';
|
35 |
+
echo '<th class="qm-sorted-asc"> ';
|
36 |
+
echo $this->build_sorter(); // WPCS: XSS ok.
|
37 |
+
echo '</th>';
|
38 |
+
echo '<th scope="col">' . esc_html__( 'HTTP Request', 'query-monitor' ) . '</th>';
|
39 |
+
echo '<th scope="col">' . esc_html__( 'Response', 'query-monitor' );
|
40 |
+
echo $this->build_filter( 'type', array_keys( $data['types'] ) ); // WPCS: XSS ok.
|
41 |
+
echo '</th>';
|
42 |
+
echo '<th scope="col">' . esc_html__( 'Transport', 'query-monitor' ) . '</th>';
|
43 |
+
echo '<th scope="col">' . esc_html__( 'Call Stack', 'query-monitor' ) . '</th>';
|
44 |
+
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' );
|
45 |
+
echo $this->build_filter( 'component', wp_list_pluck( $data['component_times'], 'component' ) ); // WPCS: XSS ok.
|
46 |
+
echo '</th>';
|
47 |
+
echo '<th scope="col" class="qm-num">' . esc_html__( 'Timeout', 'query-monitor' );
|
48 |
+
echo $this->build_sorter(); // WPCS: XSS ok.
|
49 |
+
echo '</th>';
|
50 |
+
echo '<th scope="col" class="qm-num">' . esc_html__( 'Time', 'query-monitor' );
|
51 |
+
echo $this->build_sorter(); // WPCS: XSS ok.
|
52 |
+
echo '</th>';
|
53 |
echo '</tr>';
|
54 |
echo '</thead>';
|
55 |
|
56 |
+
$vars = array();
|
57 |
|
58 |
if ( !empty( $data['vars'] ) ) {
|
|
|
59 |
foreach ( $data['vars'] as $key => $value ) {
|
60 |
+
$vars[] = $key . ': ' . $value;
|
61 |
}
|
|
|
62 |
}
|
63 |
|
64 |
if ( !empty( $data['http'] ) ) {
|
72 |
|
73 |
$row_attr = array();
|
74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
if ( is_wp_error( $row['response'] ) ) {
|
76 |
+
$response = $row['response']->get_error_message();
|
77 |
$css = 'qm-warn';
|
78 |
} else {
|
79 |
$response = wp_remote_retrieve_response_code( $row['response'] );
|
83 |
if ( empty( $response ) ) {
|
84 |
$response = __( 'n/a', 'query-monitor' );
|
85 |
} else {
|
86 |
+
$response = $response . ' ' . $msg;
|
87 |
}
|
88 |
|
89 |
if ( intval( $response ) >= 400 ) {
|
104 |
$transport = '';
|
105 |
}
|
106 |
|
|
|
107 |
$component = $row['component'];
|
108 |
|
109 |
+
$stack = array();
|
110 |
+
$filtered_trace = $row['trace']->get_filtered_trace();
|
111 |
+
array_shift( $filtered_trace );
|
112 |
+
|
113 |
+
foreach ( $filtered_trace as $item ) {
|
114 |
+
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
115 |
+
}
|
116 |
+
|
117 |
$row_attr['data-qm-component'] = $component->name;
|
118 |
$row_attr['data-qm-type'] = $row['type'];
|
119 |
|
122 |
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
123 |
}
|
124 |
|
125 |
+
printf(
|
126 |
+
'<tr %s class="%s">',
|
127 |
+
$attr,
|
128 |
+
esc_attr( $css )
|
129 |
+
); // WPCS:: XSS ok.
|
130 |
+
printf(
|
131 |
+
'<td class="qm-num">%s</td>',
|
132 |
+
intval( $i )
|
133 |
+
);
|
134 |
+
printf(
|
135 |
+
'<td class="qm-url qm-ltr qm-wrap">%s<br>%s</td>',
|
136 |
+
esc_html( $method ),
|
137 |
+
$url
|
138 |
+
); // WPCS:: XSS ok.
|
139 |
+
printf(
|
140 |
+
'<td>%s</td>',
|
141 |
+
esc_html( $response )
|
142 |
+
);
|
143 |
+
printf(
|
144 |
+
'<td>%s</td>',
|
145 |
+
esc_html( $transport )
|
146 |
+
);
|
147 |
+
printf(
|
148 |
+
'<td class="qm-nowrap qm-ltr">%s</td>',
|
149 |
+
implode( '<br>', $stack ) // WPCS: XSS ok.
|
150 |
+
);
|
151 |
+
printf(
|
152 |
+
'<td class="qm-nowrap">%s</td>',
|
153 |
+
esc_html( $component->name )
|
154 |
+
);
|
155 |
+
printf(
|
156 |
+
'<td class="qm-num">%s</td>',
|
157 |
+
esc_html( $row['args']['timeout'] )
|
158 |
+
);
|
159 |
+
|
160 |
+
if ( empty( $ltime ) ) {
|
161 |
+
$stime = '';
|
162 |
+
} else {
|
163 |
+
$stime = number_format_i18n( $ltime, 4 );
|
164 |
+
}
|
165 |
+
|
166 |
+
printf(
|
167 |
+
'<td class="qm-num">%s</td>',
|
168 |
+
esc_html( $stime )
|
169 |
+
);
|
170 |
+
echo '</tr>';
|
171 |
}
|
172 |
|
173 |
echo '</tbody>';
|
176 |
$total_stime = number_format_i18n( $data['ltime'], 4 );
|
177 |
|
178 |
echo '<tr>';
|
179 |
+
printf(
|
180 |
+
'<td colspan="7">%s</td>',
|
181 |
+
implode( '<br>', array_map( 'esc_html', $vars ) )
|
182 |
+
);
|
183 |
+
echo '<td class="qm-num">' . esc_html( $total_stime ) . '</td>';
|
184 |
echo '</tr>';
|
185 |
echo '</tfoot>';
|
186 |
|
188 |
|
189 |
echo '<tbody>';
|
190 |
echo '<tr>';
|
191 |
+
echo '<td colspan="8" style="text-align:center !important"><em>' . esc_html__( 'none', 'query-monitor' ) . '</em></td>';
|
192 |
echo '</tr>';
|
193 |
if ( !empty( $vars ) ) {
|
194 |
echo '<tr>';
|
195 |
+
printf(
|
196 |
+
'<td colspan="8">%s</td>',
|
197 |
+
implode( '<br>', array_map( 'esc_html', $vars ) )
|
198 |
+
);
|
199 |
echo '</tr>';
|
200 |
}
|
201 |
echo '</tbody>';
|
232 |
: __( 'HTTP Requests (%s)', 'query-monitor' );
|
233 |
|
234 |
$args = array(
|
235 |
+
'title' => esc_html( sprintf(
|
236 |
+
$title,
|
237 |
+
number_format_i18n( $count )
|
238 |
+
) ),
|
239 |
);
|
240 |
|
241 |
if ( isset( $data['errors']['error'] ) ) {
|
output/html/languages.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Copyright 2009-2015 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_Languages extends QM_Output_Html {
|
18 |
+
|
19 |
+
public $id = 'languages';
|
20 |
+
|
21 |
+
public function __construct( QM_Collector $collector ) {
|
22 |
+
parent::__construct( $collector );
|
23 |
+
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 80 );
|
24 |
+
}
|
25 |
+
|
26 |
+
public function output() {
|
27 |
+
|
28 |
+
$data = $this->collector->get_data();
|
29 |
+
|
30 |
+
if ( empty( $data['languages'] ) ) {
|
31 |
+
return;
|
32 |
+
}
|
33 |
+
|
34 |
+
echo '<div class="qm" id="' . esc_attr( $this->collector->id() ) . '">';
|
35 |
+
echo '<table cellspacing="0">';
|
36 |
+
echo '<thead>';
|
37 |
+
echo '<tr>';
|
38 |
+
echo '<th>' . esc_html__( 'Languages', 'query-monitor' ) . '</th>';
|
39 |
+
echo '<th colspan="3">' . esc_html__( 'Language Setting:', 'query-monitor' ) . ' ' . esc_html( get_locale() ) . '</th>';
|
40 |
+
echo '</tr>';
|
41 |
+
echo '<tr>';
|
42 |
+
echo '<td>' . esc_html__( 'Text Domain', 'query-monitor' ) . '</td>';
|
43 |
+
echo '<td>' . esc_html__( 'Caller', 'query-monitor' ) . '</td>';
|
44 |
+
echo '<td>' . esc_html__( 'MO File', 'query-monitor' ) . '</td>';
|
45 |
+
echo '<td>' . esc_html__( 'Loaded', 'query-monitor' ) . '</td>';
|
46 |
+
echo '</tr>';
|
47 |
+
echo '</thead>';
|
48 |
+
echo '<tbody>';
|
49 |
+
|
50 |
+
foreach ( $data['languages'] as $mofile ) {
|
51 |
+
|
52 |
+
echo '<tr>';
|
53 |
+
|
54 |
+
echo '<td>' . esc_html( $mofile['domain'] ) . '</td>';
|
55 |
+
echo '<td class="qm-nowrap">';
|
56 |
+
echo self::output_filename( $mofile['caller']['display'], $mofile['caller']['file'], $mofile['caller']['line'] ); // WPCS: XSS ok.
|
57 |
+
echo '</td>';
|
58 |
+
echo '<td>';
|
59 |
+
echo esc_html( QM_Util::standard_dir( $mofile['mofile'], '' ) );
|
60 |
+
echo '</td>';
|
61 |
+
|
62 |
+
if ( $mofile['found'] ) {
|
63 |
+
echo '<td class="qm-nowrap">';
|
64 |
+
echo esc_html__( 'Found', 'query-monitor' ) . '<br />';
|
65 |
+
echo esc_html( size_format( $mofile['found'] ) );
|
66 |
+
echo '</td>';
|
67 |
+
} else {
|
68 |
+
echo '<td class="qm-warn">';
|
69 |
+
echo esc_html__( 'Not Found', 'query-monitor' );
|
70 |
+
echo '</td>';
|
71 |
+
}
|
72 |
+
|
73 |
+
echo '</tr>';
|
74 |
+
|
75 |
+
}
|
76 |
+
|
77 |
+
echo '</tbody>';
|
78 |
+
echo '</table>';
|
79 |
+
echo '</div>';
|
80 |
+
|
81 |
+
}
|
82 |
+
|
83 |
+
public function admin_menu( array $menu ) {
|
84 |
+
|
85 |
+
$data = $this->collector->get_data();
|
86 |
+
$args = array(
|
87 |
+
'title' => esc_html( $this->collector->name() ),
|
88 |
+
);
|
89 |
+
|
90 |
+
$menu[] = $this->menu( $args );
|
91 |
+
|
92 |
+
return $menu;
|
93 |
+
|
94 |
+
}
|
95 |
+
|
96 |
+
}
|
97 |
+
|
98 |
+
function register_qm_output_html_languages( array $output, QM_Collectors $collectors ) {
|
99 |
+
if ( $collector = QM_Collectors::get( 'languages' ) ) {
|
100 |
+
$output['languages'] = new QM_Output_Html_Languages( $collector );
|
101 |
+
}
|
102 |
+
return $output;
|
103 |
+
}
|
104 |
+
|
105 |
+
add_filter( 'qm/outputter/html', 'register_qm_output_html_languages', 81, 2 );
|
output/html/overview.php
CHANGED
@@ -34,49 +34,65 @@ class QM_Output_Html_Overview extends QM_Output_Html {
|
|
34 |
$db_queries_data = $db_queries->get_data();
|
35 |
if ( isset( $db_queries_data['types'] ) ) {
|
36 |
$db_query_num = $db_queries_data['types'];
|
37 |
-
$db_stime = number_format_i18n( $db_queries_data['total_time'], 4 );
|
38 |
}
|
39 |
}
|
40 |
|
41 |
-
$total_stime = number_format_i18n( $data['time'], 4 );
|
42 |
-
|
43 |
echo '<div class="qm" id="' . esc_attr( $this->collector->id() ) . '">';
|
44 |
echo '<table cellspacing="0">';
|
45 |
|
46 |
-
$memory_usage = '<br><span class="qm-info">' . sprintf( __( '%1$s%% of %2$s kB limit', 'query-monitor' ), number_format_i18n( $data['memory_usage'], 1 ), number_format_i18n( $data['memory_limit'] / 1024 ) ) . '</span>';
|
47 |
-
|
48 |
-
$time_usage = '<br><span class="qm-info">' . sprintf( __( '%1$s%% of %2$ss limit', 'query-monitor' ), number_format_i18n( $data['time_usage'], 1 ), number_format_i18n( $data['time_limit'] ) ) . '</span>';
|
49 |
-
|
50 |
echo '<thead>';
|
51 |
echo '<tr>';
|
52 |
-
echo '<th scope="col">' .
|
53 |
-
echo '<th scope="col">' .
|
54 |
if ( isset( $db_query_num ) ) {
|
55 |
-
echo '<th scope="col">' .
|
56 |
-
echo '<th scope="col">' .
|
57 |
}
|
58 |
echo '</tr>';
|
59 |
echo '</thead>';
|
60 |
|
61 |
echo '<tbody>';
|
62 |
echo '<tr>';
|
63 |
-
echo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
if ( empty( $data['memory'] ) ) {
|
66 |
-
echo '<td><em>' .
|
67 |
} else {
|
68 |
-
echo '<td>'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
}
|
70 |
|
71 |
if ( isset( $db_query_num ) ) {
|
72 |
-
echo
|
|
|
|
|
73 |
echo '<td>';
|
74 |
|
75 |
foreach ( $db_query_num as $type_name => $type_count ) {
|
76 |
$db_query_types[] = sprintf( '%1$s: %2$s', $type_name, number_format_i18n( $type_count ) );
|
77 |
}
|
78 |
|
79 |
-
echo implode( '<br>', $db_query_types );
|
80 |
|
81 |
echo '</td>';
|
82 |
}
|
34 |
$db_queries_data = $db_queries->get_data();
|
35 |
if ( isset( $db_queries_data['types'] ) ) {
|
36 |
$db_query_num = $db_queries_data['types'];
|
|
|
37 |
}
|
38 |
}
|
39 |
|
|
|
|
|
40 |
echo '<div class="qm" id="' . esc_attr( $this->collector->id() ) . '">';
|
41 |
echo '<table cellspacing="0">';
|
42 |
|
|
|
|
|
|
|
|
|
43 |
echo '<thead>';
|
44 |
echo '<tr>';
|
45 |
+
echo '<th scope="col">' . esc_html__( 'Page generation time', 'query-monitor' ) . '</th>';
|
46 |
+
echo '<th scope="col">' . esc_html__( 'Peak memory usage', 'query-monitor' ) . '</th>';
|
47 |
if ( isset( $db_query_num ) ) {
|
48 |
+
echo '<th scope="col">' . esc_html__( 'Database query time', 'query-monitor' ) . '</th>';
|
49 |
+
echo '<th scope="col">' . esc_html__( 'Database queries', 'query-monitor' ) . '</th>';
|
50 |
}
|
51 |
echo '</tr>';
|
52 |
echo '</thead>';
|
53 |
|
54 |
echo '<tbody>';
|
55 |
echo '<tr>';
|
56 |
+
echo '<td>';
|
57 |
+
echo esc_html( number_format_i18n( $data['time'], 4 ) );
|
58 |
+
echo '<br><span class="qm-info">';
|
59 |
+
echo esc_html( sprintf(
|
60 |
+
__( '%1$s%% of %2$ss limit', 'query-monitor' ),
|
61 |
+
number_format_i18n( $data['time_usage'], 1 ),
|
62 |
+
number_format_i18n( $data['time_limit'] )
|
63 |
+
) );
|
64 |
+
echo '</span>';
|
65 |
+
echo '</td>';
|
66 |
|
67 |
if ( empty( $data['memory'] ) ) {
|
68 |
+
echo '<td><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></td>';
|
69 |
} else {
|
70 |
+
echo '<td>';
|
71 |
+
echo esc_html( sprintf(
|
72 |
+
__( '%s kB', 'query-monitor' ),
|
73 |
+
number_format_i18n( $data['memory'] / 1024 )
|
74 |
+
) );
|
75 |
+
echo '<br><span class="qm-info">';
|
76 |
+
echo esc_html( sprintf(
|
77 |
+
__( '%1$s%% of %2$s kB limit', 'query-monitor' ),
|
78 |
+
number_format_i18n( $data['memory_usage'], 1 ),
|
79 |
+
number_format_i18n( $data['memory_limit'] / 1024 )
|
80 |
+
) );
|
81 |
+
echo '</span>';
|
82 |
+
echo '</td>';
|
83 |
}
|
84 |
|
85 |
if ( isset( $db_query_num ) ) {
|
86 |
+
echo '<td>';
|
87 |
+
echo esc_html( number_format_i18n( $db_queries_data['total_time'], 4 ) );
|
88 |
+
echo '</td>';
|
89 |
echo '<td>';
|
90 |
|
91 |
foreach ( $db_query_num as $type_name => $type_count ) {
|
92 |
$db_query_types[] = sprintf( '%1$s: %2$s', $type_name, number_format_i18n( $type_count ) );
|
93 |
}
|
94 |
|
95 |
+
echo implode( '<br>', array_map( 'esc_html', $db_query_types ) );
|
96 |
|
97 |
echo '</td>';
|
98 |
}
|
output/html/php_errors.php
CHANGED
@@ -34,11 +34,11 @@ class QM_Output_Html_PHP_Errors extends QM_Output_Html {
|
|
34 |
echo '<table cellspacing="0">';
|
35 |
echo '<thead>';
|
36 |
echo '<tr>';
|
37 |
-
echo '<th colspan="2">' .
|
38 |
-
echo '<th class="qm-num">' .
|
39 |
-
echo '<th>' .
|
40 |
-
echo '<th>' .
|
41 |
-
echo '<th>' .
|
42 |
echo '</tr>';
|
43 |
echo '</thead>';
|
44 |
echo '<tbody>';
|
@@ -55,7 +55,7 @@ class QM_Output_Html_PHP_Errors extends QM_Output_Html {
|
|
55 |
if ( isset( $data['errors'][$type] ) ) {
|
56 |
|
57 |
echo '<tr>';
|
58 |
-
echo '<td rowspan="' . count( $data['errors'][$type] ) . '">' . $title . '</td>';
|
59 |
$first = true;
|
60 |
|
61 |
foreach ( $data['errors'][$type] as $error ) {
|
@@ -64,25 +64,25 @@ class QM_Output_Html_PHP_Errors extends QM_Output_Html {
|
|
64 |
echo '<tr>';
|
65 |
}
|
66 |
|
67 |
-
$stack = $error->trace->get_stack();
|
68 |
$component = $error->trace->get_component();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
if ( $component ) {
|
70 |
-
|
71 |
} else {
|
72 |
-
|
73 |
}
|
74 |
-
$stack = implode( '<br>', $stack );
|
75 |
-
$message = str_replace( "href='function.", "target='_blank' href='http://php.net/function.", $error->message );
|
76 |
|
77 |
-
$output = esc_html( $error->filename ) . ':' . $error->line;
|
78 |
-
|
79 |
-
echo '<td>' . $message . '</td>';
|
80 |
-
echo '<td>' . number_format_i18n( $error->calls ) . '</td>';
|
81 |
-
echo '<td>';
|
82 |
-
echo self::output_filename( $output, $error->file, $error->line );
|
83 |
-
echo '</td>';
|
84 |
-
echo '<td class="qm-nowrap qm-ltr">' . $stack . '</td>';
|
85 |
-
echo '<td class="qm-nowrap">' . $name . '</td>';
|
86 |
echo '</tr>';
|
87 |
|
88 |
$first = false;
|
@@ -124,25 +124,37 @@ class QM_Output_Html_PHP_Errors extends QM_Output_Html {
|
|
124 |
if ( isset( $data['errors']['warning'] ) ) {
|
125 |
$menu[] = $this->menu( array(
|
126 |
'id' => 'query-monitor-warnings',
|
127 |
-
'title' =>
|
|
|
|
|
|
|
128 |
) );
|
129 |
}
|
130 |
if ( isset( $data['errors']['notice'] ) ) {
|
131 |
$menu[] = $this->menu( array(
|
132 |
'id' => 'query-monitor-notices',
|
133 |
-
'title' =>
|
|
|
|
|
|
|
134 |
) );
|
135 |
}
|
136 |
if ( isset( $data['errors']['strict'] ) ) {
|
137 |
$menu[] = $this->menu( array(
|
138 |
'id' => 'query-monitor-stricts',
|
139 |
-
'title' =>
|
|
|
|
|
|
|
140 |
) );
|
141 |
}
|
142 |
if ( isset( $data['errors']['deprecated'] ) ) {
|
143 |
$menu[] = $this->menu( array(
|
144 |
'id' => 'query-monitor-deprecated',
|
145 |
-
'title' =>
|
|
|
|
|
|
|
146 |
) );
|
147 |
}
|
148 |
return $menu;
|
34 |
echo '<table cellspacing="0">';
|
35 |
echo '<thead>';
|
36 |
echo '<tr>';
|
37 |
+
echo '<th colspan="2">' . esc_html__( 'PHP Error', 'query-monitor' ) . '</th>';
|
38 |
+
echo '<th class="qm-num">' . esc_html__( 'Count', 'query-monitor' ) . '</th>';
|
39 |
+
echo '<th>' . esc_html__( 'Location', 'query-monitor' ) . '</th>';
|
40 |
+
echo '<th>' . esc_html__( 'Call Stack', 'query-monitor' ) . '</th>';
|
41 |
+
echo '<th>' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
42 |
echo '</tr>';
|
43 |
echo '</thead>';
|
44 |
echo '<tbody>';
|
55 |
if ( isset( $data['errors'][$type] ) ) {
|
56 |
|
57 |
echo '<tr>';
|
58 |
+
echo '<td rowspan="' . count( $data['errors'][$type] ) . '">' . esc_html( $title ) . '</td>';
|
59 |
$first = true;
|
60 |
|
61 |
foreach ( $data['errors'][$type] as $error ) {
|
64 |
echo '<tr>';
|
65 |
}
|
66 |
|
|
|
67 |
$component = $error->trace->get_component();
|
68 |
+
$message = wp_strip_all_tags( $error->message );
|
69 |
+
|
70 |
+
echo '<td>' . esc_html( $message ) . '</td>';
|
71 |
+
echo '<td>' . esc_html( number_format_i18n( $error->calls ) ) . '</td>';
|
72 |
+
echo '<td>';
|
73 |
+
echo self::output_filename( $error->filename . ':' . $error->line, $error->file, $error->line ); // WPCS: XSS ok.
|
74 |
+
echo '</td>';
|
75 |
+
printf(
|
76 |
+
'<td class="qm-nowrap qm-ltr">%s</td>',
|
77 |
+
implode( '<br>', array_map( 'esc_html', $error->trace->get_stack() ) )
|
78 |
+
);
|
79 |
+
|
80 |
if ( $component ) {
|
81 |
+
echo '<td class="qm-nowrap">' . esc_html( $component->name ) . '</td>';
|
82 |
} else {
|
83 |
+
echo '<td><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></td>';
|
84 |
}
|
|
|
|
|
85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
echo '</tr>';
|
87 |
|
88 |
$first = false;
|
124 |
if ( isset( $data['errors']['warning'] ) ) {
|
125 |
$menu[] = $this->menu( array(
|
126 |
'id' => 'query-monitor-warnings',
|
127 |
+
'title' => esc_html( sprintf(
|
128 |
+
__( 'PHP Warnings (%s)', 'query-monitor' ),
|
129 |
+
number_format_i18n( count( $data['errors']['warning'] ) )
|
130 |
+
) )
|
131 |
) );
|
132 |
}
|
133 |
if ( isset( $data['errors']['notice'] ) ) {
|
134 |
$menu[] = $this->menu( array(
|
135 |
'id' => 'query-monitor-notices',
|
136 |
+
'title' => esc_html( sprintf(
|
137 |
+
__( 'PHP Notices (%s)', 'query-monitor' ),
|
138 |
+
number_format_i18n( count( $data['errors']['notice'] ) )
|
139 |
+
) )
|
140 |
) );
|
141 |
}
|
142 |
if ( isset( $data['errors']['strict'] ) ) {
|
143 |
$menu[] = $this->menu( array(
|
144 |
'id' => 'query-monitor-stricts',
|
145 |
+
'title' => esc_html( sprintf(
|
146 |
+
__( 'PHP Stricts (%s)', 'query-monitor' ),
|
147 |
+
number_format_i18n( count( $data['errors']['strict'] ) )
|
148 |
+
) )
|
149 |
) );
|
150 |
}
|
151 |
if ( isset( $data['errors']['deprecated'] ) ) {
|
152 |
$menu[] = $this->menu( array(
|
153 |
'id' => 'query-monitor-deprecated',
|
154 |
+
'title' => esc_html( sprintf(
|
155 |
+
__( 'PHP Deprecated (%s)', 'query-monitor' ),
|
156 |
+
number_format_i18n( count( $data['errors']['deprecated'] ) )
|
157 |
+
) )
|
158 |
) );
|
159 |
}
|
160 |
return $menu;
|
output/html/request.php
CHANGED
@@ -41,25 +41,25 @@ class QM_Output_Html_Request extends QM_Output_Html {
|
|
41 |
}
|
42 |
|
43 |
if ( ! empty( $data['request'][$item] ) ) {
|
44 |
-
if ( in_array( $item, array( 'request', 'matched_query', 'query_string' ) ) ) {
|
45 |
$value = self::format_url( $data['request'][$item] );
|
46 |
} else {
|
47 |
$value = esc_html( $data['request'][$item] );
|
48 |
}
|
49 |
} else {
|
50 |
-
$value = '<em>' .
|
51 |
}
|
52 |
|
53 |
echo '<tr>';
|
54 |
-
echo '<td
|
55 |
-
echo '<td
|
56 |
echo '</tr>';
|
57 |
}
|
58 |
|
59 |
$rowspan = isset( $data['qvars'] ) ? count( $data['qvars'] ) : 1;
|
60 |
|
61 |
echo '<tr>';
|
62 |
-
echo '<td rowspan="' . $rowspan . '">' .
|
63 |
|
64 |
if ( !empty( $data['qvars'] ) ) {
|
65 |
|
@@ -72,18 +72,17 @@ class QM_Output_Html_Request extends QM_Output_Html {
|
|
72 |
}
|
73 |
|
74 |
if ( isset( $data['plugin_qvars'][$var] ) ) {
|
75 |
-
echo "<td
|
76 |
} else {
|
77 |
-
echo "<td
|
78 |
}
|
79 |
|
80 |
if ( is_array( $value ) or is_object( $value ) ) {
|
81 |
-
echo '<td
|
82 |
-
print_r( $value );
|
83 |
echo '</pre></td>';
|
84 |
} else {
|
85 |
-
|
86 |
-
echo "<td valign='top'>{$value}</td>";
|
87 |
}
|
88 |
|
89 |
echo '</tr>';
|
@@ -94,7 +93,28 @@ class QM_Output_Html_Request extends QM_Output_Html {
|
|
94 |
|
95 |
} else {
|
96 |
|
97 |
-
echo '<td colspan="2"><em>' .
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
echo '</tr>';
|
99 |
|
100 |
}
|
@@ -104,7 +124,7 @@ class QM_Output_Html_Request extends QM_Output_Html {
|
|
104 |
$rowspan = count( $data['multisite'] );
|
105 |
|
106 |
echo '<tr>';
|
107 |
-
echo '<td rowspan="' . $rowspan . '">' .
|
108 |
|
109 |
$first = true;
|
110 |
|
@@ -114,37 +134,24 @@ class QM_Output_Html_Request extends QM_Output_Html {
|
|
114 |
echo '<tr>';
|
115 |
}
|
116 |
|
117 |
-
echo
|
118 |
|
119 |
-
|
120 |
-
|
121 |
-
|
|
|
122 |
|
123 |
-
echo '
|
|
|
|
|
|
|
|
|
124 |
|
125 |
$first = false;
|
126 |
|
127 |
}
|
128 |
}
|
129 |
|
130 |
-
if ( !empty( $data['queried_object'] ) ) {
|
131 |
-
|
132 |
-
$vars = get_object_vars( $data['queried_object'] );
|
133 |
-
|
134 |
-
echo '<tr>';
|
135 |
-
echo '<td valign="top">' . __( 'Queried Object', 'query-monitor' ) . '</td>';
|
136 |
-
echo '<td valign="top" colspan="2" class="qm-has-inner">';
|
137 |
-
echo '<div class="qm-inner-toggle">' . $data['queried_object_title'] . ' (' . get_class( $data['queried_object'] ) . ' object) (<a href="#" class="qm-toggle" data-on="' . esc_attr__( 'Show', 'query-monitor' ) . '" data-off="' . esc_attr__( 'Hide', 'query-monitor' ) . '">' . __( 'Show', 'query-monitor' ) . '</a>)</div>';
|
138 |
-
|
139 |
-
echo '<div class="qm-toggled">';
|
140 |
-
self::output_inner( $vars );
|
141 |
-
echo '</div>';
|
142 |
-
|
143 |
-
echo '</td>';
|
144 |
-
echo '</tr>';
|
145 |
-
|
146 |
-
}
|
147 |
-
|
148 |
echo '</tbody>';
|
149 |
echo '</table>';
|
150 |
echo '</div>';
|
@@ -161,7 +168,10 @@ class QM_Output_Html_Request extends QM_Output_Html {
|
|
161 |
: __( 'Request (+%s)', 'query-monitor' );
|
162 |
|
163 |
$menu[] = $this->menu( array(
|
164 |
-
'title' =>
|
|
|
|
|
|
|
165 |
) );
|
166 |
return $menu;
|
167 |
|
41 |
}
|
42 |
|
43 |
if ( ! empty( $data['request'][$item] ) ) {
|
44 |
+
if ( in_array( $item, array( 'request', 'matched_query', 'query_string' ), true ) ) {
|
45 |
$value = self::format_url( $data['request'][$item] );
|
46 |
} else {
|
47 |
$value = esc_html( $data['request'][$item] );
|
48 |
}
|
49 |
} else {
|
50 |
+
$value = '<em>' . esc_html__( 'none', 'query-monitor' ) . '</em>';
|
51 |
}
|
52 |
|
53 |
echo '<tr>';
|
54 |
+
echo '<td>' . esc_html( $name ) . '</td>';
|
55 |
+
echo '<td colspan="2">' . $value . '</td>'; // WPCS: XSS ok.
|
56 |
echo '</tr>';
|
57 |
}
|
58 |
|
59 |
$rowspan = isset( $data['qvars'] ) ? count( $data['qvars'] ) : 1;
|
60 |
|
61 |
echo '<tr>';
|
62 |
+
echo '<td rowspan="' . absint( $rowspan ) . '">' . esc_html__( 'Query Vars', 'query-monitor' ) . '</td>';
|
63 |
|
64 |
if ( !empty( $data['qvars'] ) ) {
|
65 |
|
72 |
}
|
73 |
|
74 |
if ( isset( $data['plugin_qvars'][$var] ) ) {
|
75 |
+
echo "<td><span class='qm-current'>" . esc_html( $var ) . "</span></td>";
|
76 |
} else {
|
77 |
+
echo "<td>" . esc_html( $var ) . "</td>";
|
78 |
}
|
79 |
|
80 |
if ( is_array( $value ) or is_object( $value ) ) {
|
81 |
+
echo '<td><pre>';
|
82 |
+
echo esc_html( print_r( $value, true ) );
|
83 |
echo '</pre></td>';
|
84 |
} else {
|
85 |
+
echo "<td>" . esc_html( $value ) . "</td>";
|
|
|
86 |
}
|
87 |
|
88 |
echo '</tr>';
|
93 |
|
94 |
} else {
|
95 |
|
96 |
+
echo '<td colspan="2"><em>' . esc_html__( 'none', 'query-monitor' ) . '</em></td>';
|
97 |
+
echo '</tr>';
|
98 |
+
|
99 |
+
}
|
100 |
+
|
101 |
+
if ( ! empty( $data['queried_object'] ) ) {
|
102 |
+
|
103 |
+
echo '<tr>';
|
104 |
+
echo '<td>' . esc_html__( 'Queried Object', 'query-monitor' ) . '</td>';
|
105 |
+
echo '<td colspan="2" class="qm-has-inner">';
|
106 |
+
|
107 |
+
printf(
|
108 |
+
'<div class="qm-inner-toggle">%1$s (%2$s) <a href="#" class="qm-toggle" data-on="+" data-off="-">+</a></div>',
|
109 |
+
esc_html( $data['queried_object']['title'] ),
|
110 |
+
esc_html( get_class( $data['queried_object']['data'] ) )
|
111 |
+
);
|
112 |
+
|
113 |
+
echo '<div class="qm-toggled">';
|
114 |
+
self::output_inner( $data['queried_object']['data'] );
|
115 |
+
echo '</div>';
|
116 |
+
|
117 |
+
echo '</td>';
|
118 |
echo '</tr>';
|
119 |
|
120 |
}
|
124 |
$rowspan = count( $data['multisite'] );
|
125 |
|
126 |
echo '<tr>';
|
127 |
+
echo '<td rowspan="' . absint( $rowspan ) . '">' . esc_html__( 'Multisite', 'query-monitor' ) . '</td>';
|
128 |
|
129 |
$first = true;
|
130 |
|
134 |
echo '<tr>';
|
135 |
}
|
136 |
|
137 |
+
echo '<td colspan="2" class="qm-has-inner">';
|
138 |
|
139 |
+
printf(
|
140 |
+
'<div class="qm-inner-toggle">%1$s <a href="#" class="qm-toggle" data-on="+" data-off="-">+</a></div>',
|
141 |
+
esc_html( $value['title'] )
|
142 |
+
);
|
143 |
|
144 |
+
echo '<div class="qm-toggled">';
|
145 |
+
self::output_inner( $value['data'] );
|
146 |
+
echo '</div>';
|
147 |
+
|
148 |
+
echo '</td>';
|
149 |
|
150 |
$first = false;
|
151 |
|
152 |
}
|
153 |
}
|
154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
echo '</tbody>';
|
156 |
echo '</table>';
|
157 |
echo '</div>';
|
168 |
: __( 'Request (+%s)', 'query-monitor' );
|
169 |
|
170 |
$menu[] = $this->menu( array(
|
171 |
+
'title' => esc_html( sprintf(
|
172 |
+
$title,
|
173 |
+
number_format_i18n( $count )
|
174 |
+
) ),
|
175 |
) );
|
176 |
return $menu;
|
177 |
|
output/html/theme.php
CHANGED
@@ -35,27 +35,31 @@ class QM_Output_Html_Theme extends QM_Output_Html {
|
|
35 |
echo '<table cellspacing="0">';
|
36 |
echo '<tbody>';
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
echo '<td>' .
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
44 |
}
|
45 |
-
echo '</tr>';
|
46 |
|
47 |
echo '<tr>';
|
48 |
if ( $child_theme ) {
|
49 |
-
echo '<td>' .
|
50 |
} else {
|
51 |
-
echo '<td>' .
|
52 |
}
|
53 |
echo '<td>' . esc_html( $data['stylesheet'] ) . '</td>';
|
54 |
echo '</tr>';
|
55 |
|
56 |
if ( $child_theme ) {
|
57 |
echo '<tr>';
|
58 |
-
echo '<td>' .
|
59 |
echo '<td>' . esc_html( $data['template'] ) . '</td>';
|
60 |
echo '</tr>';
|
61 |
}
|
@@ -63,7 +67,7 @@ class QM_Output_Html_Theme extends QM_Output_Html {
|
|
63 |
if ( !empty( $data['body_class'] ) ) {
|
64 |
|
65 |
echo '<tr>';
|
66 |
-
echo '<td rowspan="' . count( $data['body_class'] ) . '">' .
|
67 |
$first = true;
|
68 |
|
69 |
foreach ( $data['body_class'] as $class ) {
|
@@ -93,7 +97,10 @@ class QM_Output_Html_Theme extends QM_Output_Html {
|
|
93 |
|
94 |
if ( isset( $data['template_file'] ) ) {
|
95 |
$menu[] = $this->menu( array(
|
96 |
-
'title' =>
|
|
|
|
|
|
|
97 |
) );
|
98 |
}
|
99 |
return $menu;
|
35 |
echo '<table cellspacing="0">';
|
36 |
echo '<tbody>';
|
37 |
|
38 |
+
if ( ! empty( $data['template_path'] ) ) {
|
39 |
+
|
40 |
+
echo '<tr>';
|
41 |
+
echo '<td>' . esc_html__( 'Template File', 'query-monitor' ) . '</td>';
|
42 |
+
if ( $child_theme ) {
|
43 |
+
echo '<td>' . self::output_filename( $data['theme_template'], $data['template_path'] ) . '</td>'; // WPCS: XSS ok.
|
44 |
+
} else {
|
45 |
+
echo '<td>' . self::output_filename( $data['template_file'], $data['template_path'] ) . '</td>'; // WPCS: XSS ok.
|
46 |
+
}
|
47 |
+
echo '</tr>';
|
48 |
+
|
49 |
}
|
|
|
50 |
|
51 |
echo '<tr>';
|
52 |
if ( $child_theme ) {
|
53 |
+
echo '<td>' . esc_html__( 'Child Theme', 'query-monitor' ) . '</td>';
|
54 |
} else {
|
55 |
+
echo '<td>' . esc_html__( 'Theme', 'query-monitor' ) . '</td>';
|
56 |
}
|
57 |
echo '<td>' . esc_html( $data['stylesheet'] ) . '</td>';
|
58 |
echo '</tr>';
|
59 |
|
60 |
if ( $child_theme ) {
|
61 |
echo '<tr>';
|
62 |
+
echo '<td>' . esc_html__( 'Parent Theme', 'query-monitor' ) . '</td>';
|
63 |
echo '<td>' . esc_html( $data['template'] ) . '</td>';
|
64 |
echo '</tr>';
|
65 |
}
|
67 |
if ( !empty( $data['body_class'] ) ) {
|
68 |
|
69 |
echo '<tr>';
|
70 |
+
echo '<td rowspan="' . count( $data['body_class'] ) . '">' . esc_html__( 'Body Classes', 'query-monitor' ) . '</td>';
|
71 |
$first = true;
|
72 |
|
73 |
foreach ( $data['body_class'] as $class ) {
|
97 |
|
98 |
if ( isset( $data['template_file'] ) ) {
|
99 |
$menu[] = $this->menu( array(
|
100 |
+
'title' => esc_html( sprintf(
|
101 |
+
__( 'Template: %s', 'query-monitor' ),
|
102 |
+
$data['template_file']
|
103 |
+
) ),
|
104 |
) );
|
105 |
}
|
106 |
return $menu;
|
output/html/transients.php
CHANGED
@@ -29,15 +29,15 @@ class QM_Output_Html_Transients extends QM_Output_Html {
|
|
29 |
echo '<table cellspacing="0">';
|
30 |
echo '<thead>';
|
31 |
echo '<tr>';
|
32 |
-
echo '<th>' .
|
33 |
if ( is_multisite() ) {
|
34 |
-
echo '<th>' .
|
35 |
}
|
36 |
if ( !empty( $data['trans'] ) and isset( $data['trans'][0]['expiration'] ) ) {
|
37 |
-
echo '<th>' .
|
38 |
}
|
39 |
-
echo '<th>' .
|
40 |
-
echo '<th>' .
|
41 |
echo '</tr>';
|
42 |
echo '</thead>';
|
43 |
|
@@ -46,29 +46,58 @@ class QM_Output_Html_Transients extends QM_Output_Html {
|
|
46 |
echo '<tbody>';
|
47 |
|
48 |
foreach ( $data['trans'] as $row ) {
|
49 |
-
$stack = $row['trace']->get_stack();
|
50 |
$transient = str_replace( array(
|
51 |
'_site_transient_',
|
52 |
'_transient_'
|
53 |
), '', $row['transient'] );
|
54 |
-
$type = ( is_multisite() ) ? "<td valign='top'>{$row['type']}</td>\n" : '';
|
55 |
-
if ( 0 === $row['expiration'] ) {
|
56 |
-
$row['expiration'] = '<em>' . __( 'none', 'query-monitor' ) . '</em>';
|
57 |
-
}
|
58 |
-
$expiration = ( isset( $row['expiration'] ) ) ? "<td valign='top'>{$row['expiration']}</td>\n" : '';
|
59 |
|
60 |
$component = $row['trace']->get_component();
|
61 |
|
62 |
-
|
63 |
-
|
64 |
-
<
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
<td
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
73 |
|
74 |
echo '</tbody>';
|
@@ -77,7 +106,7 @@ class QM_Output_Html_Transients extends QM_Output_Html {
|
|
77 |
|
78 |
echo '<tbody>';
|
79 |
echo '<tr>';
|
80 |
-
echo '<td colspan="4" style="text-align:center !important"><em>' .
|
81 |
echo '</tr>';
|
82 |
echo '</tbody>';
|
83 |
|
@@ -98,7 +127,10 @@ class QM_Output_Html_Transients extends QM_Output_Html {
|
|
98 |
: __( 'Transients Set (%s)', 'query-monitor' );
|
99 |
|
100 |
$menu[] = $this->menu( array(
|
101 |
-
'title' =>
|
|
|
|
|
|
|
102 |
) );
|
103 |
return $menu;
|
104 |
|
29 |
echo '<table cellspacing="0">';
|
30 |
echo '<thead>';
|
31 |
echo '<tr>';
|
32 |
+
echo '<th>' . esc_html__( 'Transient Set', 'query-monitor' ) . '</th>';
|
33 |
if ( is_multisite() ) {
|
34 |
+
echo '<th>' . esc_html__( 'Type', 'query-monitor' ) . '</th>';
|
35 |
}
|
36 |
if ( !empty( $data['trans'] ) and isset( $data['trans'][0]['expiration'] ) ) {
|
37 |
+
echo '<th>' . esc_html__( 'Expiration', 'query-monitor' ) . '</th>';
|
38 |
}
|
39 |
+
echo '<th>' . esc_html__( 'Call Stack', 'query-monitor' ) . '</th>';
|
40 |
+
echo '<th>' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
41 |
echo '</tr>';
|
42 |
echo '</thead>';
|
43 |
|
46 |
echo '<tbody>';
|
47 |
|
48 |
foreach ( $data['trans'] as $row ) {
|
|
|
49 |
$transient = str_replace( array(
|
50 |
'_site_transient_',
|
51 |
'_transient_'
|
52 |
), '', $row['transient'] );
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
$component = $row['trace']->get_component();
|
55 |
|
56 |
+
echo '<tr>';
|
57 |
+
printf(
|
58 |
+
'<td>%s</td>',
|
59 |
+
esc_html( $transient )
|
60 |
+
);
|
61 |
+
if ( is_multisite() ) {
|
62 |
+
printf(
|
63 |
+
'<td>%s</td>',
|
64 |
+
esc_html( $row['type'] )
|
65 |
+
);
|
66 |
+
}
|
67 |
+
|
68 |
+
if ( isset( $row['expiration'] ) ) {
|
69 |
+
if ( 0 === $row['expiration'] ) {
|
70 |
+
printf(
|
71 |
+
'<td><em>%s</em></td>',
|
72 |
+
esc_html__( 'none', 'query-monitor' )
|
73 |
+
);
|
74 |
+
} else {
|
75 |
+
printf(
|
76 |
+
'<td>%s</td>',
|
77 |
+
esc_html( $row['expiration'] )
|
78 |
+
);
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
$stack = array();
|
83 |
+
$filtered_trace = $row['trace']->get_filtered_trace();
|
84 |
+
array_shift( $filtered_trace );
|
85 |
+
|
86 |
+
foreach ( $filtered_trace as $item ) {
|
87 |
+
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
88 |
+
}
|
89 |
+
|
90 |
+
printf(
|
91 |
+
'<td class="qm-nowrap qm-ltr">%s</td>',
|
92 |
+
implode( '<br>', $stack ) // WPCS: XSS ok.
|
93 |
+
);
|
94 |
+
printf(
|
95 |
+
'<td class="qm-nowrap">%s</td>',
|
96 |
+
esc_html( $component->name )
|
97 |
+
);
|
98 |
+
|
99 |
+
echo '</tr>';
|
100 |
+
|
101 |
}
|
102 |
|
103 |
echo '</tbody>';
|
106 |
|
107 |
echo '<tbody>';
|
108 |
echo '<tr>';
|
109 |
+
echo '<td colspan="4" style="text-align:center !important"><em>' . esc_html__( 'none', 'query-monitor' ) . '</em></td>';
|
110 |
echo '</tr>';
|
111 |
echo '</tbody>';
|
112 |
|
127 |
: __( 'Transients Set (%s)', 'query-monitor' );
|
128 |
|
129 |
$menu[] = $this->menu( array(
|
130 |
+
'title' => esc_html( sprintf(
|
131 |
+
$title,
|
132 |
+
number_format_i18n( $count )
|
133 |
+
) ),
|
134 |
) );
|
135 |
return $menu;
|
136 |
|
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.
|
6 |
Plugin URI: https://querymonitor.com/
|
7 |
Author: John Blackbourn
|
8 |
Author URI: https://johnblackbourn.com/
|
@@ -30,9 +30,9 @@ if ( defined( 'QM_DISABLED' ) and QM_DISABLED ) {
|
|
30 |
return;
|
31 |
}
|
32 |
|
33 |
-
if ( defined( '
|
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 |
}
|
38 |
|
@@ -49,7 +49,6 @@ class QueryMonitor extends QM_Plugin {
|
|
49 |
# Actions
|
50 |
add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) );
|
51 |
add_action( 'init', array( $this, 'action_init' ) );
|
52 |
-
add_action( 'shutdown', array( $this, 'action_shutdown' ), 0 );
|
53 |
|
54 |
# Filters
|
55 |
add_filter( 'pre_update_option_active_plugins', array( $this, 'filter_active_plugins' ) );
|
@@ -63,7 +62,9 @@ class QueryMonitor extends QM_Plugin {
|
|
63 |
parent::__construct( $file );
|
64 |
|
65 |
# Load and register built-in collectors:
|
66 |
-
|
|
|
|
|
67 |
|
68 |
}
|
69 |
|
@@ -74,8 +75,10 @@ class QueryMonitor extends QM_Plugin {
|
|
74 |
QM_Collectors::add( $collector );
|
75 |
}
|
76 |
|
77 |
-
#
|
78 |
-
|
|
|
|
|
79 |
|
80 |
# Register built-in and additional dispatchers:
|
81 |
foreach ( apply_filters( 'qm/dispatchers', array(), $this ) as $dispatcher ) {
|
@@ -115,100 +118,10 @@ class QueryMonitor extends QM_Plugin {
|
|
115 |
|
116 |
}
|
117 |
|
118 |
-
public function should_process() {
|
119 |
-
|
120 |
-
# @TODO this decision should be moved to each dispatcher
|
121 |
-
|
122 |
-
# Don't process if the minimum required actions haven't fired:
|
123 |
-
|
124 |
-
if ( is_admin() ) {
|
125 |
-
|
126 |
-
if ( ! did_action( 'admin_init' ) ) {
|
127 |
-
return false;
|
128 |
-
}
|
129 |
-
|
130 |
-
} else {
|
131 |
-
|
132 |
-
if ( ! ( did_action( 'wp' ) or did_action( 'login_init' ) ) ) {
|
133 |
-
return false;
|
134 |
-
}
|
135 |
-
|
136 |
-
}
|
137 |
-
|
138 |
-
$e = error_get_last();
|
139 |
-
|
140 |
-
# Don't process if a fatal has occurred:
|
141 |
-
if ( ! empty( $e ) and ( $e['type'] & ( E_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR ) ) ) {
|
142 |
-
return false;
|
143 |
-
}
|
144 |
-
|
145 |
-
# Allow users to disable the processing and output
|
146 |
-
if ( ! apply_filters( 'qm/process', true, is_admin_bar_showing() ) ) {
|
147 |
-
return false;
|
148 |
-
}
|
149 |
-
|
150 |
-
$dispatchers = QM_Dispatchers::init();
|
151 |
-
|
152 |
-
foreach ( $dispatchers as $dispatcher ) {
|
153 |
-
|
154 |
-
# At least one dispatcher is active, so we need to process:
|
155 |
-
if ( $dispatcher->is_active() ) {
|
156 |
-
return true;
|
157 |
-
}
|
158 |
-
|
159 |
-
}
|
160 |
-
|
161 |
-
return false;
|
162 |
-
|
163 |
-
}
|
164 |
-
|
165 |
-
public function action_shutdown() {
|
166 |
-
|
167 |
-
# @TODO this should move to each dispatcher so it can decide when it wants to do its output
|
168 |
-
# eg. the JSON dispatcher needs to output inside the 'json_post_dispatch' filter, not on shutdown
|
169 |
-
|
170 |
-
if ( ! $this->should_process() ) {
|
171 |
-
return;
|
172 |
-
}
|
173 |
-
|
174 |
-
$collectors = QM_Collectors::init();
|
175 |
-
$dispatchers = QM_Dispatchers::init();
|
176 |
-
|
177 |
-
foreach ( $collectors as $collector ) {
|
178 |
-
$collector->tear_down();
|
179 |
-
$collector->process();
|
180 |
-
}
|
181 |
-
|
182 |
-
foreach ( $dispatchers as $dispatcher ) {
|
183 |
-
|
184 |
-
if ( ! $dispatcher->is_active() ) {
|
185 |
-
continue;
|
186 |
-
}
|
187 |
-
|
188 |
-
$dispatcher->before_output();
|
189 |
-
|
190 |
-
$outputters = apply_filters( "qm/outputter/{$dispatcher->id}", array(), $collectors );
|
191 |
-
|
192 |
-
foreach ( $outputters as $outputter ) {
|
193 |
-
$outputter->output();
|
194 |
-
}
|
195 |
-
|
196 |
-
$dispatcher->after_output();
|
197 |
-
|
198 |
-
}
|
199 |
-
|
200 |
-
}
|
201 |
-
|
202 |
public function action_init() {
|
203 |
|
204 |
load_plugin_textdomain( 'query-monitor', false, dirname( $this->plugin_base() ) . '/languages' );
|
205 |
|
206 |
-
$dispatchers = QM_Dispatchers::init();
|
207 |
-
|
208 |
-
foreach ( $dispatchers as $dispatcher ) {
|
209 |
-
$dispatcher->init();
|
210 |
-
}
|
211 |
-
|
212 |
}
|
213 |
|
214 |
public function filter_active_plugins( $plugins ) {
|
@@ -250,7 +163,10 @@ class QueryMonitor extends QM_Plugin {
|
|
250 |
|
251 |
public static function symlink_warning() {
|
252 |
$db = WP_CONTENT_DIR . '/db.php';
|
253 |
-
trigger_error( sprintf(
|
|
|
|
|
|
|
254 |
}
|
255 |
|
256 |
public static function init( $file = null ) {
|
2 |
/*
|
3 |
Plugin Name: Query Monitor
|
4 |
Description: Monitoring of database queries, hooks, conditionals and more.
|
5 |
+
Version: 2.8.0
|
6 |
Plugin URI: https://querymonitor.com/
|
7 |
Author: John Blackbourn
|
8 |
Author URI: https://johnblackbourn.com/
|
30 |
return;
|
31 |
}
|
32 |
|
33 |
+
if ( 'cli' === php_sapi_name() && ! defined( 'QM_TESTS' ) ) {
|
34 |
+
# For the time being, let's not load QM when using the CLI because we've no persistent storage and no means of
|
35 |
+
# outputting collected data on the CLI. This will hopefully change in a future version of QM.
|
36 |
return;
|
37 |
}
|
38 |
|
49 |
# Actions
|
50 |
add_action( 'plugins_loaded', array( $this, 'action_plugins_loaded' ) );
|
51 |
add_action( 'init', array( $this, 'action_init' ) );
|
|
|
52 |
|
53 |
# Filters
|
54 |
add_filter( 'pre_update_option_active_plugins', array( $this, 'filter_active_plugins' ) );
|
62 |
parent::__construct( $file );
|
63 |
|
64 |
# Load and register built-in collectors:
|
65 |
+
foreach ( glob( $this->plugin_path( 'collectors/*.php' ) ) as $file ) {
|
66 |
+
include $file;
|
67 |
+
}
|
68 |
|
69 |
}
|
70 |
|
75 |
QM_Collectors::add( $collector );
|
76 |
}
|
77 |
|
78 |
+
# Load dispatchers:
|
79 |
+
foreach ( glob( $this->plugin_path( 'dispatchers/*.php' ) ) as $file ) {
|
80 |
+
include $file;
|
81 |
+
}
|
82 |
|
83 |
# Register built-in and additional dispatchers:
|
84 |
foreach ( apply_filters( 'qm/dispatchers', array(), $this ) as $dispatcher ) {
|
118 |
|
119 |
}
|
120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
public function action_init() {
|
122 |
|
123 |
load_plugin_textdomain( 'query-monitor', false, dirname( $this->plugin_base() ) . '/languages' );
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
}
|
126 |
|
127 |
public function filter_active_plugins( $plugins ) {
|
163 |
|
164 |
public static function symlink_warning() {
|
165 |
$db = WP_CONTENT_DIR . '/db.php';
|
166 |
+
trigger_error( sprintf(
|
167 |
+
esc_html__( 'The symlink at %s is no longer pointing to the correct location. Please remove the symlink, then deactivate and reactivate Query Monitor.', 'query-monitor' ),
|
168 |
+
'<code>' . esc_html( $db ) . '</code>'
|
169 |
+
), E_USER_WARNING );
|
170 |
}
|
171 |
|
172 |
public static function init( $file = null ) {
|
readme.txt
CHANGED
@@ -1,16 +1,16 @@
|
|
1 |
=== Query Monitor ===
|
2 |
Contributors: johnbillion
|
3 |
-
Tags: debug, debug-bar, debugging, development, developer, performance, profiler, profiling, queries, query monitor
|
4 |
-
Requires at least: 3.
|
5 |
Tested up to: 4.3
|
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.
|
10 |
|
11 |
== Description ==
|
12 |
|
13 |
-
Query Monitor is a debugging plugin for anyone developing with WordPress. It has some advanced features not available in other debugging plugins, including automatic AJAX debugging and the ability to narrow down things by plugin or theme.
|
14 |
|
15 |
For complete information, please see [Query Monitor's GitHub repo](https://github.com/johnbillion/query-monitor).
|
16 |
|
@@ -25,7 +25,7 @@ Here's an overview of what's shown:
|
|
25 |
* Filter queries by **component** (WordPress core, Plugin X, Plugin Y, theme)
|
26 |
* Filter queries by **calling function**
|
27 |
* View **aggregate query information** grouped by component, calling function, and type
|
28 |
-
* Super advanced: Supports **multiple instances of wpdb** on one page
|
29 |
|
30 |
Filtering queries by component or calling function makes it easy to see which plugins, themes, or functions on your site are making the most (or the slowest) database queries.
|
31 |
|
@@ -39,7 +39,7 @@ Filtering queries by component or calling function makes it easy to see which pl
|
|
39 |
|
40 |
* Shows the **template filename** for the current page
|
41 |
* Shows the available **body classes** for the current page
|
42 |
-
* Shows the active
|
43 |
|
44 |
= PHP Errors =
|
45 |
|
@@ -50,7 +50,7 @@ Filtering queries by component or calling function makes it easy to see which pl
|
|
50 |
|
51 |
* Shows **matched rewrite rules** and associated query strings
|
52 |
* Shows **query vars** for the current request, and highlights **custom query vars**
|
53 |
-
* Shows the **queried object** details
|
54 |
* Shows details of the **current blog** (multisite only) and **current site** (multi-network only)
|
55 |
|
56 |
= Scripts & Styles =
|
@@ -58,25 +58,34 @@ Filtering queries by component or calling function makes it easy to see which pl
|
|
58 |
* Shows all **enqueued scripts and styles** on the current page, along with their URL and version
|
59 |
* Shows their **dependencies and dependents**, and alerts you to any **broken dependencies**
|
60 |
|
|
|
|
|
|
|
|
|
|
|
61 |
= HTTP Requests =
|
62 |
|
63 |
* Shows all HTTP requests performed on the current page (as long as they use WordPress' HTTP API)
|
64 |
-
* Shows the response code, call stack, transport, timeout, and time taken
|
65 |
* Highlights **erroneous responses**, such as failed requests and anything without a `200` response code
|
66 |
|
67 |
= Redirects =
|
68 |
|
69 |
-
* 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 to easily trace where a redirect has come from
|
70 |
|
71 |
= AJAX =
|
72 |
|
73 |
-
The response from any jQuery AJAX request on the page will contain various debugging information in its
|
74 |
|
75 |
-
|
76 |
|
77 |
-
=
|
|
|
|
|
|
|
|
|
78 |
|
79 |
-
|
80 |
|
81 |
* Shows the correct names for **custom column filters and actions** on all admin screens that have a listing table
|
82 |
* Shows the state of `get_current_screen()` and a few variables
|
@@ -94,8 +103,7 @@ Hands up who can remember the correct names for the filters and actions for cust
|
|
94 |
|
95 |
* Shows any **transients that were set**, along with their timeout, component, and call stack
|
96 |
* Shows all **WordPress conditionals** on the current page, highlighted nicely
|
97 |
-
* Shows an overview including page generation time and memory limit as absolute values and as % of their respective limits
|
98 |
-
* Shows all *scripts and styles* which were enqueued on the current page, along with their URL, dependencies, dependents, and version number
|
99 |
|
100 |
= Authentication =
|
101 |
|
@@ -105,14 +113,9 @@ In addition to this, you can set an authentication cookie which allows you to vi
|
|
105 |
|
106 |
== Installation ==
|
107 |
|
108 |
-
|
109 |
-
|
110 |
-
1. Go to the *Plugins* menu and click *Add New*.
|
111 |
-
2. Search for *Query Monitor*.
|
112 |
-
3. Click *Install Now* next to the Query Monitor plugin.
|
113 |
-
4. Activate the plugin.
|
114 |
|
115 |
-
|
116 |
|
117 |
== Screenshots ==
|
118 |
|
@@ -150,12 +153,29 @@ In addition, Query Monitor transparently supports add-ons for the Debug Bar plug
|
|
150 |
|
151 |
Please use [the issue tracker on Query Monitor's GitHub repo](https://github.com/johnbillion/query-monitor/issues) as it's easier to keep track of issues there, rather than on the wordpress.org support forums.
|
152 |
|
|
|
|
|
|
|
|
|
153 |
= Do you accept donations? =
|
154 |
|
155 |
No, I do not accept donations. If you like the plugin, I'd love for you to [leave a review](https://wordpress.org/support/view/plugin-reviews/query-monitor). Tell all your friends about the plugin too!
|
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.
|
1 |
=== Query Monitor ===
|
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.3
|
6 |
+
Stable tag: 2.8.0
|
7 |
License: GPLv2 or later
|
8 |
|
9 |
View debugging and performance information on database queries, hooks, conditionals, HTTP requests, redirects and more.
|
10 |
|
11 |
== Description ==
|
12 |
|
13 |
+
Query Monitor is a debugging plugin for anyone developing with WordPress. It has some advanced features not available in other debugging plugins, including automatic AJAX debugging, REST API debugging, and the ability to narrow down things by plugin or theme.
|
14 |
|
15 |
For complete information, please see [Query Monitor's GitHub repo](https://github.com/johnbillion/query-monitor).
|
16 |
|
25 |
* Filter queries by **component** (WordPress core, Plugin X, Plugin Y, theme)
|
26 |
* Filter queries by **calling function**
|
27 |
* View **aggregate query information** grouped by component, calling function, and type
|
28 |
+
* Super advanced: Supports **multiple instances of wpdb** on one page (more info in the FAQ)
|
29 |
|
30 |
Filtering queries by component or calling function makes it easy to see which plugins, themes, or functions on your site are making the most (or the slowest) database queries.
|
31 |
|
39 |
|
40 |
* Shows the **template filename** for the current page
|
41 |
* Shows the available **body classes** for the current page
|
42 |
+
* Shows the active theme name
|
43 |
|
44 |
= PHP Errors =
|
45 |
|
50 |
|
51 |
* Shows **matched rewrite rules** and associated query strings
|
52 |
* Shows **query vars** for the current request, and highlights **custom query vars**
|
53 |
+
* Shows the **queried object** details
|
54 |
* Shows details of the **current blog** (multisite only) and **current site** (multi-network only)
|
55 |
|
56 |
= Scripts & Styles =
|
58 |
* Shows all **enqueued scripts and styles** on the current page, along with their URL and version
|
59 |
* Shows their **dependencies and dependents**, and alerts you to any **broken dependencies**
|
60 |
|
61 |
+
= Languages =
|
62 |
+
|
63 |
+
* Shows you **language settings** and text domains
|
64 |
+
* Shows you the **MO files** for each text domain and which ones were loaded or not
|
65 |
+
|
66 |
= HTTP Requests =
|
67 |
|
68 |
* Shows all HTTP requests performed on the current page (as long as they use WordPress' HTTP API)
|
69 |
+
* Shows the response code, call stack, transport, component, timeout, and time taken
|
70 |
* Highlights **erroneous responses**, such as failed requests and anything without a `200` response code
|
71 |
|
72 |
= Redirects =
|
73 |
|
74 |
+
* 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
|
75 |
|
76 |
= AJAX =
|
77 |
|
78 |
+
The response from any jQuery AJAX request on the page will contain various debugging information in its headers. Any errors also get output to the developer console. **No hooking required**.
|
79 |
|
80 |
+
Currently this includes PHP errors and some overview information such as memory usage, but this will be built upon in future versions.
|
81 |
|
82 |
+
= REST API =
|
83 |
+
|
84 |
+
The response from an authenticated WordPress REST API (v2 or later) request will contain various debugging information in its headers, as long as the authenticated user has permission to view Query Monitor's output.
|
85 |
+
|
86 |
+
Currently this includes PHP errors and some overview information such as memory usage, but this will be built upon in future versions.
|
87 |
|
88 |
+
= Admin Screen =
|
89 |
|
90 |
* Shows the correct names for **custom column filters and actions** on all admin screens that have a listing table
|
91 |
* Shows the state of `get_current_screen()` and a few variables
|
103 |
|
104 |
* Shows any **transients that were set**, along with their timeout, component, and call stack
|
105 |
* Shows all **WordPress conditionals** on the current page, highlighted nicely
|
106 |
+
* Shows an overview at the top, including page generation time and memory limit as absolute values and as % of their respective limits
|
|
|
107 |
|
108 |
= Authentication =
|
109 |
|
113 |
|
114 |
== Installation ==
|
115 |
|
116 |
+
Install Query Monitor just like any other plugin.
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
+
If you don't know how to do that, then Query Monitor is not for you.
|
119 |
|
120 |
== Screenshots ==
|
121 |
|
153 |
|
154 |
Please use [the issue tracker on Query Monitor's GitHub repo](https://github.com/johnbillion/query-monitor/issues) as it's easier to keep track of issues there, rather than on the wordpress.org support forums.
|
155 |
|
156 |
+
= I'm using multiple instances of `wpdb`. How do I get my additional instances to show up in Query Monitor? =
|
157 |
+
|
158 |
+
You'll need to hook into the `qm/collect/db_objects` filter and add an item to the array with your connection name as the key and the `wpdb` instance as the value. Your `wpdb` instance will then show up as a separate panel, and the query time and query count will show up separately in the admin toolbar menu. Aggregate information (queries by caller and component) will not be separated.
|
159 |
+
|
160 |
= Do you accept donations? =
|
161 |
|
162 |
No, I do not accept donations. If you like the plugin, I'd love for you to [leave a review](https://wordpress.org/support/view/plugin-reviews/query-monitor). Tell all your friends about the plugin too!
|
163 |
|
164 |
== Changelog ==
|
165 |
|
166 |
+
= 2.8.0 =
|
167 |
+
* A new Languages component for debugging languages and text domains. Thanks, @MPolleke!
|
168 |
+
* REST API debugging in the form of HTTP headers when performing an authenticated REST API request. Shows PHP errors when relevant, along with an overview of memory usage, processing time, database query number, and database query time.
|
169 |
+
* Various visual improvements, including displaying the relevant file name below stack trace functions, and a more visible stack trace expansion toggle.
|
170 |
+
* Add `is_embed()`, `is_comment_feed()`, and `is_user_admin()` to the list of conditional functions.
|
171 |
+
* Add HHVM, SAPI, and MySQL client info to the Environment component.
|
172 |
+
* QM is now not loaded at all on the CLI.
|
173 |
+
* Avoid an issue with the CloudFlare Flexible SSL plugin.
|
174 |
+
* Improve the output of Multisite's `$current_blog` and `$current_site` in the Request component.
|
175 |
+
* Fully handle Windows paths when detecting a file component.
|
176 |
+
* Don't display the symlink warning when using a secondary instance of WPDB.
|
177 |
+
* Whole bunch of internal structure refactoring, escaping, and other misc tweaks.
|
178 |
+
|
179 |
= 2.7.4 =
|
180 |
* An unknown component now gets marked as such, not as Core.
|
181 |
* Support for invokable objects in action and filter callbacks.
|
wp-content/db.php
CHANGED
@@ -29,9 +29,9 @@ if ( defined( 'QM_DISABLED' ) and QM_DISABLED ) {
|
|
29 |
return;
|
30 |
}
|
31 |
|
32 |
-
if ( defined( '
|
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 |
}
|
37 |
|
29 |
return;
|
30 |
}
|
31 |
|
32 |
+
if ( 'cli' === php_sapi_name() && ! defined( 'QM_TESTS' ) ) {
|
33 |
+
# For the time being, let's not load QM when using the CLI because we've no persistent storage and no means of
|
34 |
+
# outputting collected data on the CLI. This will hopefully change in a future version of QM.
|
35 |
return;
|
36 |
}
|
37 |
|