Query Monitor - Version 2.12.0

Version Description

Download this release

Release Info

Developer johnbillion
Plugin Icon 128x128 Query Monitor
Version 2.12.0
Comparing to
See all releases

Code changes from version 2.11.4 to 2.12.0

assets/query-monitor.css CHANGED
@@ -26,14 +26,6 @@ GNU General Public License for more details.
26
  background-color: #f60;
27
  }
28
 
29
- #wp-admin-bar-query-monitor-notices {
30
- background-color: #740 !important;
31
- }
32
-
33
- #wpadminbar .qm-notice {
34
- background-color: #740;
35
- }
36
-
37
  #wp-admin-bar-query-monitor-deprecated,
38
  #wp-admin-bar-query-monitor-stricts {
39
  background-color: #555 !important;
@@ -44,6 +36,14 @@ GNU General Public License for more details.
44
  background-color: #3c3c3c;
45
  }
46
 
 
 
 
 
 
 
 
 
47
  #wp-admin-bar-query-monitor-expensive {
48
  background-color: #b60 !important;
49
  }
@@ -77,6 +77,7 @@ GNU General Public License for more details.
77
  color: #fff !important;
78
  }
79
 
 
80
  #wp-admin-bar-query-monitor-deprecated a,
81
  #wp-admin-bar-query-monitor-stricts a,
82
  #wp-admin-bar-query-monitor-notices a,
@@ -237,6 +238,12 @@ body.wp-admin.folded #qm {
237
  clear: none !important;
238
  }
239
 
 
 
 
 
 
 
240
  .qm:focus {
241
  outline: 0 !important;
242
  }
@@ -252,6 +259,7 @@ body.wp-admin.folded #qm {
252
 
253
  @media all and (max-width: 900px) {
254
  .qm-third,
 
255
  .qm-half {
256
  float: none !important;
257
  width: 100% !important;
@@ -457,19 +465,25 @@ body.wp-admin.folded #qm {
457
  text-decoration: underline !important;
458
  }
459
 
460
- .qm a.qm-toggle {
461
  color: #0073aa !important;
462
- padding: 4px 8px 3px !important;
 
 
463
  border-left: 1px solid #e8e8e8 !important;
464
  border-bottom: 1px solid #e8e8e8 !important;
 
 
 
465
  position: absolute !important;
466
  top: 0 !important;
467
  right: 0 !important;
468
  background: #fff !important;
 
469
  }
470
 
471
- .qm a.qm-toggle:focus,
472
- .qm a.qm-toggle:hover {
473
  text-decoration: none !important;
474
  border-color: #e8e8e8 !important;
475
  color: #0073aa !important;
@@ -497,6 +511,10 @@ body.wp-admin.folded #qm {
497
 
498
  /* Filters */
499
 
 
 
 
 
500
  select.qm-filter {
501
  display: block !important;
502
  font-family: Menlo, Monaco, Consolas, monospace !important;
@@ -533,20 +551,56 @@ select.qm-filter {
533
  text-align: center !important;
534
  }
535
 
 
 
 
 
 
 
 
 
 
 
 
 
536
  .qm .qm-sort {
537
- color: #ccc !important;
538
  display: block !important;
539
- font-size: 14px !important;
 
540
  line-height: 11px !important;
541
- text-decoration: none !important;
 
 
 
 
 
542
  }
543
 
544
- .qm .qm-sort:hover,
545
- .qm .qm-sort:focus,
546
- .qm .qm-sorted-asc .qm-sort-asc,
547
- .qm .qm-sorted-desc .qm-sort-desc {
548
- color: #444 !important;
549
- text-decoration: none !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
  }
551
 
552
  /* RTL */
@@ -589,9 +643,11 @@ html[dir="rtl"] .qm th {
589
  text-align: right !important;
590
  }
591
 
592
- html[dir="rtl"] .qm a.qm-toggle {
593
- border-left: none !important;
594
  border-right: 1px solid #e8e8e8 !important;
 
 
595
  right: auto !important;
596
  left: 1px !important;
597
  }
@@ -600,7 +656,7 @@ html[dir="rtl"] .qm a.qm-toggle {
600
 
601
  .qm-no-js #qm-authentication,
602
  .qm-no-js .qm-sort-controls,
603
- .qm-no-js a.qm-toggle,
604
  .qm-no-js select.qm-filter {
605
  display: none !important;
606
  }
26
  background-color: #f60;
27
  }
28
 
 
 
 
 
 
 
 
 
29
  #wp-admin-bar-query-monitor-deprecated,
30
  #wp-admin-bar-query-monitor-stricts {
31
  background-color: #555 !important;
36
  background-color: #3c3c3c;
37
  }
38
 
39
+ #wp-admin-bar-query-monitor-notices {
40
+ background-color: #740 !important;
41
+ }
42
+
43
+ #wpadminbar .qm-notice {
44
+ background-color: #740;
45
+ }
46
+
47
  #wp-admin-bar-query-monitor-expensive {
48
  background-color: #b60 !important;
49
  }
77
  color: #fff !important;
78
  }
79
 
80
+ body.admin-color-light #wp-admin-bar-query-monitor:not(.qm-all-clear):not(:hover):not(.hover) .ab-label,
81
  #wp-admin-bar-query-monitor-deprecated a,
82
  #wp-admin-bar-query-monitor-stricts a,
83
  #wp-admin-bar-query-monitor-notices a,
238
  clear: none !important;
239
  }
240
 
241
+ .qm-two-thirds {
242
+ float: left !important;
243
+ width: 66.66% !important;
244
+ clear: none !important;
245
+ }
246
+
247
  .qm:focus {
248
  outline: 0 !important;
249
  }
259
 
260
  @media all and (max-width: 900px) {
261
  .qm-third,
262
+ .qm-two-thirds,
263
  .qm-half {
264
  float: none !important;
265
  width: 100% !important;
465
  text-decoration: underline !important;
466
  }
467
 
468
+ .qm .qm-toggle {
469
  color: #0073aa !important;
470
+ padding: 5px 8px !important;
471
+ border-top: none !important;
472
+ border-right: none !important;
473
  border-left: 1px solid #e8e8e8 !important;
474
  border-bottom: 1px solid #e8e8e8 !important;
475
+ font-family: Menlo, Monaco, Consolas, monospace !important;
476
+ font-weight: normal !important;
477
+ font-size: 11px !important;
478
  position: absolute !important;
479
  top: 0 !important;
480
  right: 0 !important;
481
  background: #fff !important;
482
+ cursor: pointer !important;
483
  }
484
 
485
+ .qm .qm-toggle:focus,
486
+ .qm .qm-toggle:hover {
487
  text-decoration: none !important;
488
  border-color: #e8e8e8 !important;
489
  color: #0073aa !important;
511
 
512
  /* Filters */
513
 
514
+ .qm label {
515
+ cursor: pointer !important;
516
+ }
517
+
518
  select.qm-filter {
519
  display: block !important;
520
  font-family: Menlo, Monaco, Consolas, monospace !important;
551
  text-align: center !important;
552
  }
553
 
554
+ .qm button,
555
+ .qm a,
556
+ .qm select {
557
+ outline: none !important;
558
+ }
559
+
560
+ .qm button:focus,
561
+ .qm a:focus,
562
+ .qm select:focus {
563
+ box-shadow: 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, .8) !important;
564
+ }
565
+
566
  .qm .qm-sort {
567
+ color: #767676 !important;
568
  display: block !important;
569
+ font-size: 15px !important;
570
+ font-family: Menlo, Monaco, Consolas, monospace !important;
571
  line-height: 11px !important;
572
+ border: 0 !important;
573
+ padding: 0 !important;
574
+ width: 30px !important;
575
+ background-color: transparent !important;
576
+ cursor: pointer !important;
577
+ margin: 0 auto !important;
578
  }
579
 
580
+ .qm .qm-sort-asc {
581
+ margin-bottom: 1px !important;
582
+ }
583
+ .qm .qm-sort-asc:before {
584
+ content: "\25b3" !important;
585
+ }
586
+ .qm .qm-sort-asc:hover:before,
587
+ .qm .qm-sort-asc:focus:before,
588
+ .qm .qm-sorted-asc .qm-sort-asc:before {
589
+ color: #333 !important;
590
+ content: "\25b2" !important;
591
+ }
592
+
593
+ .qm .qm-sort-desc {
594
+ margin-top: 1px !important;
595
+ }
596
+ .qm .qm-sort-desc:before {
597
+ content: "\25bd" !important;
598
+ }
599
+ .qm .qm-sort-desc:hover:before,
600
+ .qm .qm-sort-desc:focus:before,
601
+ .qm .qm-sorted-desc .qm-sort-desc:before {
602
+ color: #333 !important;
603
+ content: "\25bc" !important;
604
  }
605
 
606
  /* RTL */
643
  text-align: right !important;
644
  }
645
 
646
+ html[dir="rtl"] .qm .qm-toggle {
647
+ border-top: none !important;
648
  border-right: 1px solid #e8e8e8 !important;
649
+ border-bottom: 1px solid #e8e8e8 !important;
650
+ border-left: none !important;
651
  right: auto !important;
652
  left: 1px !important;
653
  }
656
 
657
  .qm-no-js #qm-authentication,
658
  .qm-no-js .qm-sort-controls,
659
+ .qm-no-js .qm-toggle,
660
  .qm-no-js select.qm-filter {
661
  display: none !important;
662
  }
assets/query-monitor.js CHANGED
@@ -182,9 +182,6 @@ jQuery( function($) {
182
  var results = table.find('.qm-items-shown').removeClass('qm-hide');
183
  results.find('.qm-items-number').text( QM_i18n.number_format( matches.length, 0 ) );
184
  results.find('.qm-items-time').text(time);
185
-
186
- $(this).blur();
187
-
188
  });
189
 
190
  $('#qm').find('.qm-filter-trigger').on('click',function(e){
@@ -203,10 +200,13 @@ jQuery( function($) {
203
  $('#qm').find('.qm-toggle').on('click',function(e){
204
  var el = $(this);
205
  $(this).closest('td').find('.qm-toggled').slideToggle(100,function(){
206
- if ( el.attr('data-off') == el.text() )
 
207
  el.text(el.attr('data-on'));
208
- else
 
209
  el.text(el.attr('data-off'));
 
210
  });
211
  e.preventDefault();
212
  });
182
  var results = table.find('.qm-items-shown').removeClass('qm-hide');
183
  results.find('.qm-items-number').text( QM_i18n.number_format( matches.length, 0 ) );
184
  results.find('.qm-items-time').text(time);
 
 
 
185
  });
186
 
187
  $('#qm').find('.qm-filter-trigger').on('click',function(e){
200
  $('#qm').find('.qm-toggle').on('click',function(e){
201
  var el = $(this);
202
  $(this).closest('td').find('.qm-toggled').slideToggle(100,function(){
203
+ if ( el.attr('data-off') == el.text() ) {
204
+ el.closest('td').removeClass('qm-toggled-on');
205
  el.text(el.attr('data-on'));
206
+ } else {
207
+ el.closest('td').addClass('qm-toggled-on');
208
  el.text(el.attr('data-off'));
209
+ }
210
  });
211
  e.preventDefault();
212
  });
classes/Util.php CHANGED
@@ -222,6 +222,12 @@ class QM_Util {
222
 
223
  if ( ! empty( $callback['file'] ) ) {
224
  $callback['component'] = self::get_file_component( $callback['file'] );
 
 
 
 
 
 
225
  }
226
 
227
  } catch ( ReflectionException $e ) {
222
 
223
  if ( ! empty( $callback['file'] ) ) {
224
  $callback['component'] = self::get_file_component( $callback['file'] );
225
+ } else {
226
+ $callback['component'] = (object) array(
227
+ 'type' => 'php',
228
+ 'name' => 'PHP',
229
+ 'context' => '',
230
+ );
231
  }
232
 
233
  } catch ( ReflectionException $e ) {
collectors/db_queries.php CHANGED
@@ -193,7 +193,7 @@ class QM_Collector_DB_Queries extends QM_Collector {
193
  $row = array(
194
  'caller' => 'Unknown',
195
  'caller_name' => 'Unknown',
196
- 'stack' => array(),
197
  'sql' => $error['query'],
198
  'result' => new WP_Error( 'qmdb', $error['error_str'] ),
199
  'type' => '',
193
  $row = array(
194
  'caller' => 'Unknown',
195
  'caller_name' => 'Unknown',
196
+ 'stack' => '',
197
  'sql' => $error['query'],
198
  'result' => new WP_Error( 'qmdb', $error['error_str'] ),
199
  'type' => '',
collectors/hooks.php CHANGED
@@ -27,6 +27,7 @@ class QM_Collector_Hooks extends QM_Collector {
27
  global $wp_actions, $wp_filter;
28
 
29
  $this->hide_qm = ( defined( 'QM_HIDE_SELF' ) and QM_HIDE_SELF );
 
30
 
31
  if ( is_admin() and ( $admin = QM_Collectors::get( 'admin' ) ) ) {
32
  $this->data['screen'] = $admin->data['base'];
@@ -40,7 +41,15 @@ class QM_Collector_Hooks extends QM_Collector {
40
  $hooks['all'] = $this->process_action( 'all', $wp_filter );
41
  }
42
 
43
- foreach ( $wp_actions as $name => $count ) {
 
 
 
 
 
 
 
 
44
 
45
  $hooks[$name] = $this->process_action( $name, $wp_filter );
46
 
@@ -71,7 +80,10 @@ class QM_Collector_Hooks extends QM_Collector {
71
  $callback = QM_Util::populate_callback( $callback );
72
 
73
  if ( isset( $callback['component'] ) ) {
74
- if ( $this->hide_qm and ( 'query-monitor' === $callback['component']->context ) ) {
 
 
 
75
  continue;
76
  }
77
 
27
  global $wp_actions, $wp_filter;
28
 
29
  $this->hide_qm = ( defined( 'QM_HIDE_SELF' ) and QM_HIDE_SELF );
30
+ $this->hide_core = ( defined( 'QM_HIDE_CORE_HOOKS' ) and QM_HIDE_CORE_HOOKS );
31
 
32
  if ( is_admin() and ( $admin = QM_Collectors::get( 'admin' ) ) ) {
33
  $this->data['screen'] = $admin->data['base'];
41
  $hooks['all'] = $this->process_action( 'all', $wp_filter );
42
  }
43
 
44
+ if ( defined( 'QM_SHOW_ALL_HOOKS' ) && QM_SHOW_ALL_HOOKS ) {
45
+ // Show all hooks
46
+ $hook_names = array_keys( $wp_filter );
47
+ } else {
48
+ // Only show action hooks that have been called at least once
49
+ $hook_names = array_keys( $wp_actions );
50
+ }
51
+
52
+ foreach ( $hook_names as $name ) {
53
 
54
  $hooks[$name] = $this->process_action( $name, $wp_filter );
55
 
80
  $callback = QM_Util::populate_callback( $callback );
81
 
82
  if ( isset( $callback['component'] ) ) {
83
+ if (
84
+ ( $this->hide_qm and 'query-monitor' === $callback['component']->context )
85
+ or ( $this->hide_core and 'core' === $callback['component']->context )
86
+ ) {
87
  continue;
88
  }
89
 
collectors/request.php CHANGED
@@ -30,14 +30,22 @@ class QM_Collector_Request extends QM_Collector {
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
  }
30
 
31
  if ( is_multisite() ) {
32
  $this->data['multisite']['current_blog'] = array(
33
+ 'title' => sprintf(
34
+ /* translators: 1: Blog ID */
35
+ __( 'Current blog: #%d', 'query-monitor' ),
36
+ $current_blog->blog_id
37
+ ),
38
  'data' => $current_blog,
39
  );
40
  }
41
 
42
  if ( QM_Util::is_multi_network() ) {
43
  $this->data['multisite']['current_site'] = array(
44
+ 'title' => sprintf(
45
+ /* translators: 1: Site ID */
46
+ __( 'Current site: #%d', 'query-monitor' ),
47
+ $current_site->id
48
+ ),
49
  'data' => $current_site,
50
  );
51
  }
dispatchers/Html.php CHANGED
@@ -97,9 +97,6 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
97
  'id' => 'query-monitor',
98
  'title' => esc_html( $title ),
99
  'href' => '#qm',
100
- 'meta' => array(
101
- 'classname' => 'hide-if-js',
102
- ),
103
  ) );
104
 
105
  $wp_admin_bar->add_menu( array(
@@ -298,6 +295,11 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
298
  public function js_admin_bar_menu() {
299
 
300
  $class = implode( ' ', apply_filters( 'qm/output/menu_class', array() ) );
 
 
 
 
 
301
  $title = implode( '   ', apply_filters( 'qm/output/title', array() ) );
302
 
303
  if ( empty( $title ) ) {
@@ -330,7 +332,8 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
330
  return false;
331
  }
332
 
333
- if ( QM_Util::is_async() && ! is_customize_preview() ) {
 
334
  return false;
335
  }
336
 
97
  'id' => 'query-monitor',
98
  'title' => esc_html( $title ),
99
  'href' => '#qm',
 
 
 
100
  ) );
101
 
102
  $wp_admin_bar->add_menu( array(
295
  public function js_admin_bar_menu() {
296
 
297
  $class = implode( ' ', apply_filters( 'qm/output/menu_class', array() ) );
298
+
299
+ if ( false === strpos( $class, 'qm-' ) ) {
300
+ $class .= ' qm-all-clear';
301
+ }
302
+
303
  $title = implode( '   ', apply_filters( 'qm/output/title', array() ) );
304
 
305
  if ( empty( $title ) ) {
332
  return false;
333
  }
334
 
335
+ // If this is an async request and not a customizer preview:
336
+ if ( QM_Util::is_async() && ( ! function_exists( 'is_customize_preview' ) || ! is_customize_preview() ) ) {
337
  return false;
338
  }
339
 
output/Html.php CHANGED
@@ -73,18 +73,22 @@ abstract class QM_Output_Html extends QM_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 ) ) {
82
- return '';
83
  }
84
 
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 ) {
@@ -104,8 +108,10 @@ abstract class QM_Output_Html extends QM_Output {
104
  */
105
  protected function build_sorter() {
106
  $out = '<span class="qm-sort-controls">';
107
- $out .= '<a href="#" class="qm-sort qm-sort-asc">&#9650;</a>';
108
- $out .= '<a href="#" class="qm-sort qm-sort-desc">&#9660;</a>';
 
 
109
  $out .= '</span>';
110
  return $out;
111
  }
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 $label Label text for the filter control.
77
  * @param string $highlight Optional. The name for the `data-` attributes that get highlighted by this control.
78
  * @return string Markup for the table filter controls.
79
  */
80
+ protected function build_filter( $name, array $values, $label, $highlight = '' ) {
81
 
82
  if ( empty( $values ) ) {
83
+ return esc_html( $label ); // Return label text, without being marked up as a label element.
84
  }
85
 
86
  usort( $values, 'strcasecmp' );
87
 
88
+ $filter_id = 'qm-filter-' . $this->collector->id . '-' . $name;
89
+
90
+ $out = '<label for="' . esc_attr( $filter_id ) .'">' . esc_html( $label ) . '</label>';
91
+ $out .= '<select id="' . esc_attr( $filter_id ) . '" class="qm-filter" data-filter="' . esc_attr( $name ) . '" data-highlight="' . esc_attr( $highlight ) . '">';
92
  $out .= '<option value="">' . esc_html_x( 'All', '"All" option for filters', 'query-monitor' ) . '</option>';
93
 
94
  foreach ( $values as $value ) {
108
  */
109
  protected function build_sorter() {
110
  $out = '<span class="qm-sort-controls">';
111
+ /* translators: Button for sorting table columns in ascending order */
112
+ $out .= '<button class="qm-sort qm-sort-asc"><span class="screen-reader-text">' . esc_html__( 'Ascending', 'query-monitor' ) . '</span></button>';
113
+ /* translators: Button for sorting table columns in descending order */
114
+ $out .= '<button class="qm-sort qm-sort-desc"><span class="screen-reader-text">' . esc_html__( 'Descending', 'query-monitor' ) . '</span></button>';
115
  $out .= '</span>';
116
  return $out;
117
  }
output/html/admin.php CHANGED
@@ -46,7 +46,7 @@ class QM_Output_Html_Admin extends QM_Output_Html {
46
  echo '<tbody>';
47
  foreach ( $data['current_screen'] as $key => $value ) {
48
  echo '<tr>';
49
- echo '<td>' . esc_html( $key ) . '</td>';
50
  echo '<td>' . esc_html( $value ) . '</td>';
51
  echo '</tr>';
52
  }
46
  echo '<tbody>';
47
  foreach ( $data['current_screen'] as $key => $value ) {
48
  echo '<tr>';
49
+ echo '<th>' . esc_html( $key ) . '</th>';
50
  echo '<td>' . esc_html( $value ) . '</td>';
51
  echo '</tr>';
52
  }
output/html/assets.php CHANGED
@@ -133,13 +133,17 @@ class QM_Output_Html_Assets extends QM_Output_Html {
133
  $ver = $dependency->ver;
134
  }
135
 
 
 
136
  /**
137
- * Filter the script loader source.
 
 
138
  *
139
- * @param string $src Script loader source path.
140
- * @param string $handle Script handle.
141
  */
142
- $source = apply_filters( 'script_loader_src', $dependency->src, $dependency->handle );
143
 
144
  if ( is_wp_error( $source ) ) {
145
  $src = $source->get_error_message();
133
  $ver = $dependency->ver;
134
  }
135
 
136
+ $loader = rtrim( $type, 's' );
137
+
138
  /**
139
+ * Filter the asset loader source.
140
+ *
141
+ * The variable {$loader} can be either 'script' or 'style'.
142
  *
143
+ * @param string $src Script or style loader source path.
144
+ * @param string $handle Script or style handle.
145
  */
146
+ $source = apply_filters( "{$loader}_loader_src", $dependency->src, $dependency->handle );
147
 
148
  if ( is_wp_error( $source ) ) {
149
  $src = $source->get_error_message();
output/html/db_callers.php CHANGED
@@ -74,7 +74,7 @@ class QM_Output_Html_DB_Callers extends QM_Output_Html {
74
  }
75
  }
76
 
77
- echo '<td class="qm-num">' . esc_html( $stime ) . '</td>';
78
  echo '</tr>';
79
 
80
  }
74
  }
75
  }
76
 
77
+ echo '<td class="qm-num" data-qm-sort-weight="' . esc_attr( $row['ltime'] ) . '">' . esc_html( $stime ) . '</td>';
78
  echo '</tr>';
79
 
80
  }
output/html/db_components.php CHANGED
@@ -39,21 +39,25 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
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__( '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
 
59
  if ( !empty( $data['times'] ) ) {
@@ -75,7 +79,7 @@ class QM_Output_Html_DB_Components extends QM_Output_Html {
75
  }
76
  }
77
 
78
- echo '<td class="qm-num">' . esc_html( number_format_i18n( $row['ltime'], 4 ) ) . '</td>';
79
  echo '</tr>';
80
 
81
  }
39
  echo '<tr>';
40
  echo '<th colspan="' . esc_attr( $span ) . '">' . esc_html( $this->collector->name() ) . '</th>';
41
  echo '</tr>';
 
 
42
 
43
+ if ( !empty( $data['times'] ) ) {
44
+ echo '<tr>';
45
+ echo '<th>' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
46
+
47
+ foreach ( $data['types'] as $type_name => $type_count ) {
48
+ echo '<th class="qm-num">';
49
+ echo esc_html( $type_name );
50
+ echo $this->build_sorter(); // WPCS: XSS ok;
51
+ echo '</th>';
52
+ }
53
+
54
+ echo '<th class="qm-num qm-sorted-desc">';
55
+ esc_html_e( 'Time', 'query-monitor' );
56
  echo $this->build_sorter(); // WPCS: XSS ok;
57
  echo '</th>';
58
+ echo '</tr>';
59
  }
60
 
 
 
 
 
 
61
  echo '</thead>';
62
 
63
  if ( !empty( $data['times'] ) ) {
79
  }
80
  }
81
 
82
+ echo '<td class="qm-num" data-qm-sort-weight="' . esc_attr( $row['ltime'] ) . '">' . esc_html( number_format_i18n( $row['ltime'], 4 ) ) . '</td>';
83
  echo '</tr>';
84
 
85
  }
output/html/db_queries.php CHANGED
@@ -194,18 +194,15 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
194
  echo $this->build_sorter(); // WPCS: XSS ok;
195
  echo '</th>';
196
  echo '<th scope="col">';
197
- esc_html_e( 'Query', 'query-monitor' );
198
- echo $this->build_filter( 'type', array_keys( $db->types ) ); // WPCS: XSS ok;
199
  echo '</th>';
200
  echo '<th scope="col">';
201
- esc_html_e( 'Caller', 'query-monitor' );
202
- echo $this->build_filter( 'caller', wp_list_pluck( $data['times'], 'caller' ) ); // WPCS: XSS ok;
203
  echo '</th>';
204
 
205
  if ( $db->has_trace ) {
206
  echo '<th scope="col">';
207
- esc_html_e( 'Component', 'query-monitor' );
208
- echo $this->build_filter( 'component', wp_list_pluck( $data['component_times'], 'component' ) ); // WPCS: XSS ok.
209
  echo '</th>';
210
  }
211
 
@@ -370,7 +367,7 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
370
  echo $caller_name; // WPCS: XSS ok.
371
 
372
  if ( ! empty( $stack ) ) {
373
- echo '<a href="#" class="qm-toggle" data-on="+" data-off="-">+</a>';
374
  echo '<div class="qm-toggled">' . implode( '<br>', $stack ) . '</div>'; // WPCS: XSS ok.
375
  }
376
 
@@ -401,7 +398,7 @@ class QM_Output_Html_DB_Queries extends QM_Output_Html {
401
  }
402
 
403
  if ( isset( $cols['time'] ) ) {
404
- echo '<td class="qm-num qm-row-time' . esc_attr( $td ) . '">'. esc_html( $stime ) . "</td>\n";
405
  }
406
 
407
  echo '</tr>';
194
  echo $this->build_sorter(); // WPCS: XSS ok;
195
  echo '</th>';
196
  echo '<th scope="col">';
197
+ echo $this->build_filter( 'type', array_keys( $db->types ), __( 'Query', 'query-monitor' ) ); // WPCS: XSS ok;
 
198
  echo '</th>';
199
  echo '<th scope="col">';
200
+ echo $this->build_filter( 'caller', wp_list_pluck( $data['times'], 'caller' ), __( 'Caller', 'query-monitor' ) ); // WPCS: XSS ok;
 
201
  echo '</th>';
202
 
203
  if ( $db->has_trace ) {
204
  echo '<th scope="col">';
205
+ echo $this->build_filter( 'component', wp_list_pluck( $data['component_times'], 'component' ), __( 'Component', 'query-monitor' ) ); // WPCS: XSS ok.
 
206
  echo '</th>';
207
  }
208
 
367
  echo $caller_name; // WPCS: XSS ok.
368
 
369
  if ( ! empty( $stack ) ) {
370
+ echo '<button class="qm-toggle" data-on="+" data-off="-">+</button>';
371
  echo '<div class="qm-toggled">' . implode( '<br>', $stack ) . '</div>'; // WPCS: XSS ok.
372
  }
373
 
398
  }
399
 
400
  if ( isset( $cols['time'] ) ) {
401
+ echo '<td class="qm-num qm-row-time' . esc_attr( $td ) . '" data-qm-sort-weight="' . esc_attr( $row['ltime'] ) . '">' . esc_html( $stime ) . "</td>\n";
402
  }
403
 
404
  echo '</tr>';
output/html/hooks.php CHANGED
@@ -42,12 +42,10 @@ class QM_Output_Html_Hooks extends QM_Output_Html {
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>';
42
  echo '<thead>';
43
  echo '<tr>';
44
  echo '<th>';
45
+ echo $this->build_filter( 'name', $data['parts'], __( 'Hook', 'query-monitor' ) ); // WPCS: XSS ok.
 
46
  echo '</th>';
47
  echo '<th colspan="3">';
48
+ echo $this->build_filter( 'component', $data['components'], __( 'Actions', 'query-monitor' ), 'subject' ); // WPCS: XSS ok.
 
49
  echo '</th>';
50
  echo '</tr>';
51
  echo '</thead>';
output/html/http.php CHANGED
@@ -36,13 +36,13 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
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.
@@ -69,25 +69,30 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
69
  foreach ( $data['http'] as $key => $row ) {
70
  $ltime = $row['ltime'];
71
  $i++;
 
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
  $code = wp_remote_retrieve_response_code( $row['response'] );
80
  $msg = wp_remote_retrieve_response_message( $row['response'] );
81
  $css = '';
82
 
83
  if ( intval( $code ) >= 400 ) {
84
- $css = 'qm-warn';
85
  }
86
 
87
  $response = $code . ' ' . $msg;
88
 
89
  }
90
 
 
 
 
 
91
  $method = esc_html( $row['args']['method'] );
92
 
93
  if ( empty( $row['args']['blocking'] ) ) {
@@ -98,16 +103,20 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
98
  ) ) . '</span>';
99
  }
100
 
101
- if ( empty( $row['args']['sslverify'] ) && empty( $row['args']['local'] ) && 'https' === parse_url( $row['url'], PHP_URL_SCHEME ) ) {
102
- $method .= '<br><span class="qm-warn">' . esc_html( sprintf(
103
- /* translators: An HTTP API request has disabled certificate verification. %s: Relevant argument name */
104
- __( '(Certificate verification disabled: %s)', 'query-monitor' ),
105
- 'sslverify=false'
106
- ) ) . '</span>';
107
- }
108
-
109
  $url = self::format_url( $row['url'] );
110
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  if ( isset( $row['transport'] ) ) {
112
  $transport = $row['transport'];
113
  } else {
@@ -174,7 +183,8 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
174
  }
175
 
176
  printf(
177
- '<td class="qm-num">%s</td>',
 
178
  esc_html( $stime )
179
  );
180
  echo '</tr>';
@@ -209,7 +219,7 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
209
  echo '</tr>';
210
  }
211
  echo '</tbody>';
212
-
213
  }
214
 
215
  echo '</table>';
@@ -223,7 +233,8 @@ class QM_Output_Html_HTTP extends QM_Output_Html {
223
 
224
  if ( isset( $data['errors']['alert'] ) ) {
225
  $class[] = 'qm-alert';
226
- } else if ( isset( $data['errors']['warning'] ) ) {
 
227
  $class[] = 'qm-warning';
228
  }
229
 
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">';
40
+ echo $this->build_filter( 'type', array_keys( $data['types'] ), __( 'Response', 'query-monitor' ) ); // 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">';
45
+ echo $this->build_filter( 'component', wp_list_pluck( $data['component_times'], 'component' ), __( 'Component', 'query-monitor' ) ); // 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.
69
  foreach ( $data['http'] as $key => $row ) {
70
  $ltime = $row['ltime'];
71
  $i++;
72
+ $is_error = false;
73
 
74
  $row_attr = array();
75
 
76
  if ( is_wp_error( $row['response'] ) ) {
77
  $response = $row['response']->get_error_message();
78
+ $is_error = true;
79
  } else {
80
  $code = wp_remote_retrieve_response_code( $row['response'] );
81
  $msg = wp_remote_retrieve_response_message( $row['response'] );
82
  $css = '';
83
 
84
  if ( intval( $code ) >= 400 ) {
85
+ $is_error = true;;
86
  }
87
 
88
  $response = $code . ' ' . $msg;
89
 
90
  }
91
 
92
+ if ( $is_error ) {
93
+ $css = 'qm-warn';
94
+ }
95
+
96
  $method = esc_html( $row['args']['method'] );
97
 
98
  if ( empty( $row['args']['blocking'] ) ) {
103
  ) ) . '</span>';
104
  }
105
 
 
 
 
 
 
 
 
 
106
  $url = self::format_url( $row['url'] );
107
 
108
+ if ( 'https' === parse_url( $row['url'], PHP_URL_SCHEME ) ) {
109
+ if ( empty( $row['args']['sslverify'] ) && empty( $row['args']['local'] ) ) {
110
+ $method .= '<br><span class="qm-warn">' . esc_html( sprintf(
111
+ /* translators: An HTTP API request has disabled certificate verification. 1: Relevant argument name */
112
+ __( '(Certificate verification disabled: %s)', 'query-monitor' ),
113
+ 'sslverify=false'
114
+ ) ) . '</span>';
115
+ } elseif ( ! $is_error ) {
116
+ $url = preg_replace( '|^https:|', '<span class="qm-true">https</span>:', $url );
117
+ }
118
+ }
119
+
120
  if ( isset( $row['transport'] ) ) {
121
  $transport = $row['transport'];
122
  } else {
183
  }
184
 
185
  printf(
186
+ '<td class="qm-num" data-qm-sort-weight="%s">%s</td>',
187
+ esc_attr( $ltime ),
188
  esc_html( $stime )
189
  );
190
  echo '</tr>';
219
  echo '</tr>';
220
  }
221
  echo '</tbody>';
222
+
223
  }
224
 
225
  echo '</table>';
233
 
234
  if ( isset( $data['errors']['alert'] ) ) {
235
  $class[] = 'qm-alert';
236
+ }
237
+ if ( isset( $data['errors']['warning'] ) ) {
238
  $class[] = 'qm-warning';
239
  }
240
 
output/html/languages.php CHANGED
@@ -42,14 +42,14 @@ class QM_Output_Html_Languages extends QM_Output_Html {
42
  ) ) . '</th>';
43
  echo '</tr>';
44
  echo '<tr>';
45
- echo '<td>' . esc_html__( 'Text Domain', 'query-monitor' ) . '</td>';
46
- echo '<td>' . esc_html__( 'Caller', 'query-monitor' ) . '</td>';
47
- echo '<td colspan="2">' . esc_html__( 'MO File', 'query-monitor' ) . '</td>';
48
  echo '</tr>';
49
  echo '</thead>';
50
  echo '<tbody>';
51
 
52
- $not_found_class = ( 'en_US' === $data['locale'] ) ? '' : 'qm-warn';
53
 
54
  foreach ( $data['languages'] as $mofile ) {
55
 
42
  ) ) . '</th>';
43
  echo '</tr>';
44
  echo '<tr>';
45
+ echo '<th>' . esc_html__( 'Text Domain', 'query-monitor' ) . '</th>';
46
+ echo '<th>' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
47
+ echo '<th colspan="2">' . esc_html__( 'MO File', 'query-monitor' ) . '</th>';
48
  echo '</tr>';
49
  echo '</thead>';
50
  echo '<tbody>';
51
 
52
+ $not_found_class = ( substr( $data['locale'], 0, 3 ) === "en_" ) ? '' : 'qm-warn';
53
 
54
  foreach ( $data['languages'] as $mofile ) {
55
 
output/html/overview.php CHANGED
@@ -112,7 +112,8 @@ class QM_Output_Html_Overview extends QM_Output_Html {
112
  if ( isset( $cache_hit_percentage ) ) {
113
  echo '<td>';
114
  echo esc_html( sprintf(
115
- '%s%% hit rate',
 
116
  number_format_i18n( $cache_hit_percentage, 1 )
117
  ) );
118
  echo '<br>' . esc_html( sprintf(
112
  if ( isset( $cache_hit_percentage ) ) {
113
  echo '<td>';
114
  echo esc_html( sprintf(
115
+ /* translators: %s: Cache hit rate percentage */
116
+ __( '%s%% hit rate', 'query-monitor' ),
117
  number_format_i18n( $cache_hit_percentage, 1 )
118
  ) );
119
  echo '<br>' . esc_html( sprintf(
output/html/php_errors.php CHANGED
@@ -120,14 +120,10 @@ class QM_Output_Html_PHP_Errors extends QM_Output_Html {
120
 
121
  $data = $this->collector->get_data();
122
 
123
- if ( isset( $data['errors']['warning'] ) ) {
124
- $class[] = 'qm-warning';
125
- } else if ( isset( $data['errors']['notice'] ) ) {
126
- $class[] = 'qm-notice';
127
- } else if ( isset( $data['errors']['strict'] ) ) {
128
- $class[] = 'qm-strict';
129
- } else if ( isset( $data['errors']['deprecated'] ) ) {
130
- $class[] = 'qm-deprecated';
131
  }
132
 
133
  return $class;
120
 
121
  $data = $this->collector->get_data();
122
 
123
+ if ( ! empty( $data['errors'] ) ) {
124
+ foreach ( $data['errors'] as $type => $errors ) {
125
+ $class[] = 'qm-' . $type;
126
+ }
 
 
 
 
127
  }
128
 
129
  return $class;
output/html/request.php CHANGED
@@ -51,7 +51,7 @@ class QM_Output_Html_Request extends QM_Output_Html {
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
  }
@@ -59,7 +59,7 @@ class QM_Output_Html_Request extends QM_Output_Html {
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
 
@@ -101,11 +101,11 @@ class QM_Output_Html_Request extends QM_Output_Html {
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 qm-has-toggle"><div class="qm-toggler">';
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
  );
@@ -124,7 +124,7 @@ class QM_Output_Html_Request extends QM_Output_Html {
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
 
@@ -137,7 +137,7 @@ class QM_Output_Html_Request extends QM_Output_Html {
137
  echo '<td colspan="2" class="qm-has-inner qm-has-toggle"><div class="qm-toggler">';
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
 
51
  }
52
 
53
  echo '<tr>';
54
+ echo '<th>' . esc_html( $name ) . '</th>';
55
  echo '<td colspan="2">' . $value . '</td>'; // WPCS: XSS ok.
56
  echo '</tr>';
57
  }
59
  $rowspan = isset( $data['qvars'] ) ? count( $data['qvars'] ) : 1;
60
 
61
  echo '<tr>';
62
+ echo '<th rowspan="' . absint( $rowspan ) . '">' . esc_html__( 'Query Vars', 'query-monitor' ) . '</th>';
63
 
64
  if ( !empty( $data['qvars'] ) ) {
65
 
101
  if ( ! empty( $data['queried_object'] ) ) {
102
 
103
  echo '<tr>';
104
+ echo '<th>' . esc_html__( 'Queried Object', 'query-monitor' ) . '</th>';
105
  echo '<td colspan="2" class="qm-has-inner qm-has-toggle"><div class="qm-toggler">';
106
 
107
  printf(
108
+ '<div class="qm-inner-toggle">%1$s (%2$s) <button class="qm-toggle" data-on="+" data-off="-">+</button></div>',
109
  esc_html( $data['queried_object']['title'] ),
110
  esc_html( get_class( $data['queried_object']['data'] ) )
111
  );
124
  $rowspan = count( $data['multisite'] );
125
 
126
  echo '<tr>';
127
+ echo '<th rowspan="' . absint( $rowspan ) . '">' . esc_html__( 'Multisite', 'query-monitor' ) . '</th>';
128
 
129
  $first = true;
130
 
137
  echo '<td colspan="2" class="qm-has-inner qm-has-toggle"><div class="qm-toggler">';
138
 
139
  printf(
140
+ '<div class="qm-inner-toggle">%1$s <button class="qm-toggle" data-on="+" data-off="-">+</button></div>',
141
  esc_html( $value['title'] )
142
  );
143
 
output/html/theme.php CHANGED
@@ -34,7 +34,7 @@ class QM_Output_Html_Theme extends QM_Output_Html {
34
  echo '<tbody>';
35
 
36
  echo '<tr>';
37
- echo '<td>' . esc_html__( 'Template File', 'query-monitor' ) . '</td>';
38
  if ( ! empty( $data['template_path'] ) ) {
39
 
40
  if ( $data['is_child_theme'] ) {
@@ -53,7 +53,7 @@ class QM_Output_Html_Theme extends QM_Output_Html {
53
 
54
  $count = count( $data['template_parts'] );
55
  echo '<tr>';
56
- echo '<td rowspan="' . absint( $count ) . '">' . esc_html__( 'Template Parts', 'query-monitor' ) . '</td>';
57
  if ( $data['is_child_theme'] ) {
58
  $parts = $data['theme_template_parts'];
59
  } else {
@@ -76,7 +76,7 @@ class QM_Output_Html_Theme extends QM_Output_Html {
76
 
77
  } else {
78
  echo '<tr>';
79
- echo '<td>' . esc_html__( 'Template Parts', 'query-monitor' ) . '</td>';
80
  echo '<td><em>' . esc_html__( 'None', 'query-monitor' ) . '</em></td>';
81
  echo '</tr>';
82
  }
@@ -85,7 +85,7 @@ class QM_Output_Html_Theme extends QM_Output_Html {
85
 
86
  $count = count( $data['timber_files'] );
87
  echo '<tr>';
88
- echo '<td rowspan="' . absint( $count ) . '">' . esc_html__( 'Timber Files', 'query-monitor' ) . '</td>';
89
  $first = true;
90
 
91
  foreach ( $data['timber_files'] as $filename ) {
@@ -105,16 +105,16 @@ class QM_Output_Html_Theme extends QM_Output_Html {
105
 
106
  echo '<tr>';
107
  if ( $data['is_child_theme'] ) {
108
- echo '<td>' . esc_html__( 'Child Theme', 'query-monitor' ) . '</td>';
109
  } else {
110
- echo '<td>' . esc_html__( 'Theme', 'query-monitor' ) . '</td>';
111
  }
112
  echo '<td>' . esc_html( $data['stylesheet'] ) . '</td>';
113
  echo '</tr>';
114
 
115
  if ( $data['is_child_theme'] ) {
116
  echo '<tr>';
117
- echo '<td>' . esc_html__( 'Parent Theme', 'query-monitor' ) . '</td>';
118
  echo '<td>' . esc_html( $data['template'] ) . '</td>';
119
  echo '</tr>';
120
  }
@@ -122,7 +122,7 @@ class QM_Output_Html_Theme extends QM_Output_Html {
122
  if ( !empty( $data['body_class'] ) ) {
123
 
124
  echo '<tr>';
125
- echo '<td rowspan="' . count( $data['body_class'] ) . '">' . esc_html__( 'Body Classes', 'query-monitor' ) . '</td>';
126
  $first = true;
127
 
128
  foreach ( $data['body_class'] as $class ) {
34
  echo '<tbody>';
35
 
36
  echo '<tr>';
37
+ echo '<th>' . esc_html__( 'Template File', 'query-monitor' ) . '</th>';
38
  if ( ! empty( $data['template_path'] ) ) {
39
 
40
  if ( $data['is_child_theme'] ) {
53
 
54
  $count = count( $data['template_parts'] );
55
  echo '<tr>';
56
+ echo '<th rowspan="' . absint( $count ) . '">' . esc_html__( 'Template Parts', 'query-monitor' ) . '</th>';
57
  if ( $data['is_child_theme'] ) {
58
  $parts = $data['theme_template_parts'];
59
  } else {
76
 
77
  } else {
78
  echo '<tr>';
79
+ echo '<th>' . esc_html__( 'Template Parts', 'query-monitor' ) . '</th>';
80
  echo '<td><em>' . esc_html__( 'None', 'query-monitor' ) . '</em></td>';
81
  echo '</tr>';
82
  }
85
 
86
  $count = count( $data['timber_files'] );
87
  echo '<tr>';
88
+ echo '<th rowspan="' . absint( $count ) . '">' . esc_html__( 'Timber Files', 'query-monitor' ) . '</th>';
89
  $first = true;
90
 
91
  foreach ( $data['timber_files'] as $filename ) {
105
 
106
  echo '<tr>';
107
  if ( $data['is_child_theme'] ) {
108
+ echo '<th>' . esc_html__( 'Child Theme', 'query-monitor' ) . '</th>';
109
  } else {
110
+ echo '<th>' . esc_html__( 'Theme', 'query-monitor' ) . '</th>';
111
  }
112
  echo '<td>' . esc_html( $data['stylesheet'] ) . '</td>';
113
  echo '</tr>';
114
 
115
  if ( $data['is_child_theme'] ) {
116
  echo '<tr>';
117
+ echo '<th>' . esc_html__( 'Parent Theme', 'query-monitor' ) . '</th>';
118
  echo '<td>' . esc_html( $data['template'] ) . '</td>';
119
  echo '</tr>';
120
  }
122
  if ( !empty( $data['body_class'] ) ) {
123
 
124
  echo '<tr>';
125
+ echo '<th rowspan="' . count( $data['body_class'] ) . '">' . esc_html__( 'Body Classes', 'query-monitor' ) . '</th>';
126
  $first = true;
127
 
128
  foreach ( $data['body_class'] as $class ) {
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.11.4
6
  Plugin URI: https://github.com/johnbillion/query-monitor
7
  Author: John Blackbourn
8
  Author URI: https://johnblackbourn.com/
2
  /*
3
  Plugin Name: Query Monitor
4
  Description: Monitoring of database queries, hooks, conditionals and more.
5
+ Version: 2.12.0
6
  Plugin URI: https://github.com/johnbillion/query-monitor
7
  Author: John Blackbourn
8
  Author URI: https://johnblackbourn.com/
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: johnbillion
3
  Tags: ajax, debug, debug-bar, debugging, development, developer, performance, profiler, profiling, queries, query monitor, rest-api
4
  Requires at least: 3.7
5
  Tested up to: 4.6
6
- Stable tag: 2.11.4
7
  License: GPLv2 or later
8
 
9
  View debugging and performance information on database queries, hooks, conditionals, HTTP requests, redirects and more.
@@ -27,7 +27,7 @@ Here's an overview of what's shown:
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
 
32
  = Hooks =
33
 
@@ -56,17 +56,17 @@ Filtering queries by component or calling function makes it easy to see which pl
56
 
57
  = Rewrite Rules =
58
 
59
- * Shows all matching rewrite rules for a given request
60
 
61
  = Scripts & Styles =
62
 
63
  * Shows all enqueued scripts and styles on the current request, along with their URL and version
64
- * Shows their dependencies and dependents, and alerts you to any broken dependencies
65
 
66
  = Languages =
67
 
68
- * Shows you language settings and text domains
69
- * Shows you the MO files for each text domain and which ones were loaded or not
70
 
71
  = HTTP Requests =
72
 
@@ -174,4 +174,4 @@ No, I do not accept donations. If you like the plugin, I'd love for you to [leav
174
 
175
  == Changelog ==
176
 
177
- See [changelog.md](https://github.com/johnbillion/query-monitor/blob/master/changelog.md) for Query Monitor's changelog.
3
  Tags: ajax, debug, debug-bar, debugging, development, developer, performance, profiler, profiling, queries, query monitor, rest-api
4
  Requires at least: 3.7
5
  Tested up to: 4.6
6
+ Stable tag: 2.12.0
7
  License: GPLv2 or later
8
 
9
  View debugging and performance information on database queries, hooks, conditionals, HTTP requests, redirects and more.
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 are making the most (or the slowest) database queries.
31
 
32
  = Hooks =
33
 
56
 
57
  = Rewrite Rules =
58
 
59
+ * Shows all matching rewrite rules for the current request
60
 
61
  = Scripts & Styles =
62
 
63
  * Shows all enqueued scripts and styles on the current request, along with their URL and version
64
+ * Shows their dependencies and dependents, and displays an alert for any broken dependencies
65
 
66
  = Languages =
67
 
68
+ * Shows language settings and text domains
69
+ * Shows the MO files for each text domain and which ones were loaded or not
70
 
71
  = HTTP Requests =
72
 
174
 
175
  == Changelog ==
176
 
177
+ For Query Monitor's changelog, please see [the Releases page on GitHub](https://github.com/johnbillion/query-monitor/releases).