Query Monitor - Version 3.3.7

Version Description

Download this release

Release Info

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

Code changes from version 3.3.6 to 3.3.7

assets/query-monitor-dark.css CHANGED
@@ -388,16 +388,16 @@ body.admin-color-light #wp-admin-bar-query-monitor:not(.qm-all-clear):not(:hover
388
  background: #def !important;
389
  color: #222 !important;
390
  }
391
- #query-monitor-main #qm-panel-menu li button.qm-selected-menu {
392
  background: #0073aa !important;
393
  color: #fff !important;
394
  text-shadow: 0 -1px 1px #006291, 1px 0 1px #006291, 0 1px 1px #006291, -1px 0 1px #006291 !important;
395
  }
396
- #query-monitor-main #qm-panel-menu li button.qm-selected-menu:focus {
397
  background: #0084c4 !important;
398
  color: #fff !important;
399
  }
400
- #query-monitor-main #qm-panel-menu li button.qm-selected-menu:after {
401
  border: solid 8px transparent;
402
  border-right-color: #23282d;
403
  content: " ";
@@ -1058,5 +1058,3 @@ body.admin-color-light #wp-admin-bar-query-monitor:not(.qm-all-clear):not(:hover
1058
  #query-monitor-main.qm-broken #qm-broken h2 {
1059
  padding: 20px !important;
1060
  }
1061
-
1062
- /*# sourceMappingURL=query-monitor-dark.css.map */
388
  background: #def !important;
389
  color: #222 !important;
390
  }
391
+ #query-monitor-main #qm-panel-menu li button[aria-selected="true"] {
392
  background: #0073aa !important;
393
  color: #fff !important;
394
  text-shadow: 0 -1px 1px #006291, 1px 0 1px #006291, 0 1px 1px #006291, -1px 0 1px #006291 !important;
395
  }
396
+ #query-monitor-main #qm-panel-menu li button[aria-selected="true"]:focus {
397
  background: #0084c4 !important;
398
  color: #fff !important;
399
  }
400
+ #query-monitor-main #qm-panel-menu li button[aria-selected="true"]:after {
401
  border: solid 8px transparent;
402
  border-right-color: #23282d;
403
  content: " ";
1058
  #query-monitor-main.qm-broken #qm-broken h2 {
1059
  padding: 20px !important;
1060
  }
 
 
assets/query-monitor.css CHANGED
@@ -388,16 +388,16 @@ body.admin-color-light #wp-admin-bar-query-monitor:not(.qm-all-clear):not(:hover
388
  background: #def !important;
389
  color: #222 !important;
390
  }
391
- #query-monitor-main #qm-panel-menu li button.qm-selected-menu {
392
  background: #0073aa !important;
393
  color: #fff !important;
394
  text-shadow: 0 -1px 1px #006291, 1px 0 1px #006291, 0 1px 1px #006291, -1px 0 1px #006291 !important;
395
  }
396
- #query-monitor-main #qm-panel-menu li button.qm-selected-menu:focus {
397
  background: #0084c4 !important;
398
  color: #fff !important;
399
  }
400
- #query-monitor-main #qm-panel-menu li button.qm-selected-menu:after {
401
  border: solid 8px transparent;
402
  border-right-color: #fff;
403
  content: " ";
@@ -1058,5 +1058,3 @@ body.admin-color-light #wp-admin-bar-query-monitor:not(.qm-all-clear):not(:hover
1058
  #query-monitor-main.qm-broken #qm-broken h2 {
1059
  padding: 20px !important;
1060
  }
1061
-
1062
- /*# sourceMappingURL=query-monitor.css.map */
388
  background: #def !important;
389
  color: #222 !important;
390
  }
391
+ #query-monitor-main #qm-panel-menu li button[aria-selected="true"] {
392
  background: #0073aa !important;
393
  color: #fff !important;
394
  text-shadow: 0 -1px 1px #006291, 1px 0 1px #006291, 0 1px 1px #006291, -1px 0 1px #006291 !important;
395
  }
396
+ #query-monitor-main #qm-panel-menu li button[aria-selected="true"]:focus {
397
  background: #0084c4 !important;
398
  color: #fff !important;
399
  }
400
+ #query-monitor-main #qm-panel-menu li button[aria-selected="true"]:after {
401
  border: solid 8px transparent;
402
  border-right-color: #fff;
403
  content: " ";
1058
  #query-monitor-main.qm-broken #qm-broken h2 {
1059
  padding: 20px !important;
1060
  }
 
 
assets/query-monitor.js CHANGED
@@ -89,9 +89,9 @@ if ( window.jQuery ) {
89
  container.height( minheight );
90
  }
91
 
92
- $('#qm-panel-menu').find('button').removeClass('qm-selected-menu');
93
  $('#qm-panel-menu').find('li').removeClass('qm-current-menu');
94
- var selected_menu = $('#qm-panel-menu').find('[data-qm-href="' + panel + '"]').addClass('qm-selected-menu');
95
 
96
  if ( selected_menu.length ) {
97
  var selected_menu_top = selected_menu.position().top - 27;
89
  container.height( minheight );
90
  }
91
 
92
+ $('#qm-panel-menu').find('button').removeAttr('aria-selected');
93
  $('#qm-panel-menu').find('li').removeClass('qm-current-menu');
94
+ var selected_menu = $('#qm-panel-menu').find('[data-qm-href="' + panel + '"]').attr('aria-selected',true);
95
 
96
  if ( selected_menu.length ) {
97
  var selected_menu_top = selected_menu.position().top - 27;
classes/Plugin.php CHANGED
@@ -13,9 +13,7 @@ abstract class QM_Plugin {
13
 
14
  /**
15
  * Class constructor
16
- *
17
- * @author John Blackbourn
18
- **/
19
  protected function __construct( $file ) {
20
  $this->file = $file;
21
  }
@@ -25,8 +23,7 @@ abstract class QM_Plugin {
25
  *
26
  * @param $file string The path within this plugin, e.g. '/js/clever-fx.js'
27
  * @return string URL
28
- * @author John Blackbourn
29
- **/
30
  final public function plugin_url( $file = '' ) {
31
  return $this->_plugin( 'url', $file );
32
  }
@@ -36,8 +33,7 @@ abstract class QM_Plugin {
36
  *
37
  * @param $file string The path within this plugin, e.g. '/js/clever-fx.js'
38
  * @return string Filesystem path
39
- * @author John Blackbourn
40
- **/
41
  final public function plugin_path( $file = '' ) {
42
  return $this->_plugin( 'path', $file );
43
  }
@@ -47,8 +43,7 @@ abstract class QM_Plugin {
47
  *
48
  * @param $file string The path within this plugin, e.g. '/js/clever-fx.js'
49
  * @return string Version
50
- * @author John Blackbourn
51
- **/
52
  final public function plugin_ver( $file ) {
53
  return filemtime( $this->plugin_path( $file ) );
54
  }
@@ -57,17 +52,14 @@ abstract class QM_Plugin {
57
  * Returns the current plugin's basename, eg. 'my_plugin/my_plugin.php'.
58
  *
59
  * @return string Basename
60
- * @author John Blackbourn
61
- **/
62
  final public function plugin_base() {
63
  return $this->_plugin( 'base' );
64
  }
65
 
66
  /**
67
  * Populates and returns the current plugin info.
68
- *
69
- * @author John Blackbourn
70
- **/
71
  final private function _plugin( $item, $file = '' ) {
72
  if ( ! array_key_exists( $item, $this->plugin ) ) {
73
  switch ( $item ) {
13
 
14
  /**
15
  * Class constructor
16
+ */
 
 
17
  protected function __construct( $file ) {
18
  $this->file = $file;
19
  }
23
  *
24
  * @param $file string The path within this plugin, e.g. '/js/clever-fx.js'
25
  * @return string URL
26
+ */
 
27
  final public function plugin_url( $file = '' ) {
28
  return $this->_plugin( 'url', $file );
29
  }
33
  *
34
  * @param $file string The path within this plugin, e.g. '/js/clever-fx.js'
35
  * @return string Filesystem path
36
+ */
 
37
  final public function plugin_path( $file = '' ) {
38
  return $this->_plugin( 'path', $file );
39
  }
43
  *
44
  * @param $file string The path within this plugin, e.g. '/js/clever-fx.js'
45
  * @return string Version
46
+ */
 
47
  final public function plugin_ver( $file ) {
48
  return filemtime( $this->plugin_path( $file ) );
49
  }
52
  * Returns the current plugin's basename, eg. 'my_plugin/my_plugin.php'.
53
  *
54
  * @return string Basename
55
+ */
 
56
  final public function plugin_base() {
57
  return $this->_plugin( 'base' );
58
  }
59
 
60
  /**
61
  * Populates and returns the current plugin info.
62
+ */
 
 
63
  final private function _plugin( $item, $file = '' ) {
64
  if ( ! array_key_exists( $item, $this->plugin ) ) {
65
  switch ( $item ) {
classes/QueryMonitor.php CHANGED
@@ -96,7 +96,7 @@ class QueryMonitor extends QM_Plugin {
96
  *
97
  * @since 2.11.2
98
  *
99
- * @param QM_Collector[] $collectors Array of collecter instances.
100
  * @param QueryMonitor $this QueryMonitor instance.
101
  */
102
  foreach ( apply_filters( 'qm/collectors', array(), $this ) as $collector ) {
96
  *
97
  * @since 2.11.2
98
  *
99
+ * @param QM_Collector[] $collectors Array of collector instances.
100
  * @param QueryMonitor $this QueryMonitor instance.
101
  */
102
  foreach ( apply_filters( 'qm/collectors', array(), $this ) as $collector ) {
collectors/environment.php CHANGED
@@ -134,8 +134,6 @@ class QM_Collector_Environment extends QM_Collector {
134
  $info = mysql_get_server_info( $db->dbh );
135
  }
136
 
137
- $rdbms = trim( preg_replace( '#[^a-zA-Z ]#', '', $info ) );
138
-
139
  if ( $client ) {
140
  $client_version = implode( '.', QM_Util::get_client_version( $client ) );
141
  $client_version = sprintf( '%s (%s)', $client, $client_version );
@@ -144,7 +142,6 @@ class QM_Collector_Environment extends QM_Collector {
144
  }
145
 
146
  $info = array(
147
- 'rdbms' => $rdbms,
148
  'server-version' => $server,
149
  'extension' => $extension,
150
  'client-version' => $client_version,
134
  $info = mysql_get_server_info( $db->dbh );
135
  }
136
 
 
 
137
  if ( $client ) {
138
  $client_version = implode( '.', QM_Util::get_client_version( $client ) );
139
  $client_version = sprintf( '%s (%s)', $client, $client_version );
142
  }
143
 
144
  $info = array(
 
145
  'server-version' => $server,
146
  'extension' => $extension,
147
  'client-version' => $client_version,
collectors/php_errors.php CHANGED
@@ -14,7 +14,6 @@ class QM_Collector_PHP_Errors extends QM_Collector {
14
  private $error_reporting = null;
15
  private $display_errors = null;
16
  private static $unexpected_error;
17
- private static $wordpress_couldnt;
18
 
19
  public function name() {
20
  return __( 'PHP Errors', 'query-monitor' );
@@ -91,18 +90,18 @@ class QM_Collector_PHP_Errors extends QM_Collector {
91
  if ( ! isset( self::$unexpected_error ) ) {
92
  // These strings are from core. They're passed through `__()` as variables so they get translated at runtime
93
  // but do not get seen by GlotPress when it populates its database of translatable strings for QM.
94
- $unexpected_error = 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.';
95
- $wordpress_couldnt = '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)';
96
- self::$unexpected_error = call_user_func( '__', $unexpected_error );
97
- self::$wordpress_couldnt = call_user_func( '__', $wordpress_couldnt );
 
 
 
98
  }
99
 
100
  // Intentionally skip reporting these core warnings. They're a distraction when developing offline.
101
  // The failed HTTP request will still appear in QM's output so it's not a big problem hiding these warnings.
102
- if ( self::$unexpected_error === $message ) {
103
- return false;
104
- }
105
- if ( self::$unexpected_error . ' ' . self::$wordpress_couldnt === $message ) {
106
  return false;
107
  }
108
 
14
  private $error_reporting = null;
15
  private $display_errors = null;
16
  private static $unexpected_error;
 
17
 
18
  public function name() {
19
  return __( 'PHP Errors', 'query-monitor' );
90
  if ( ! isset( self::$unexpected_error ) ) {
91
  // These strings are from core. They're passed through `__()` as variables so they get translated at runtime
92
  // but do not get seen by GlotPress when it populates its database of translatable strings for QM.
93
+ $unexpected_error = 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.';
94
+ $wordpress_forums = 'https://wordpress.org/support/forums/';
95
+
96
+ self::$unexpected_error = sprintf(
97
+ call_user_func( '__', $unexpected_error ),
98
+ call_user_func( '__', $wordpress_forums )
99
+ );
100
  }
101
 
102
  // Intentionally skip reporting these core warnings. They're a distraction when developing offline.
103
  // The failed HTTP request will still appear in QM's output so it's not a big problem hiding these warnings.
104
+ if ( false !== strpos( $message, self::$unexpected_error ) ) {
 
 
 
105
  return false;
106
  }
107
 
collectors/theme.php CHANGED
@@ -114,7 +114,13 @@ class QM_Collector_Theme extends QM_Collector {
114
  * @param string[] $templates Array of template files to search for, in order.
115
  */
116
  public function action_get_template_part( $slug, $name, $templates ) {
117
- $this->data['requested_template_parts'][] = func_get_args();
 
 
 
 
 
 
118
  }
119
 
120
  public function filter_template_hierarchy( array $templates ) {
@@ -162,15 +168,23 @@ class QM_Collector_Theme extends QM_Collector {
162
  $this->data['template_hierarchy'] = array_unique( $this->data['template_hierarchy'] );
163
  }
164
 
165
- if ( function_exists( 'wp_body_open' ) ) {
 
 
 
166
  if ( ! empty( $this->data['requested_template_parts'] ) ) {
167
  $this->data['template_parts'] = array();
168
  $this->data['theme_template_parts'] = array();
169
  $this->data['count_template_parts'] = array();
170
 
171
- foreach ( $this->data['requested_template_parts'] as $party ) {
172
- $file = locate_template( $party[2] );
 
 
 
 
173
  if ( ! $file ) {
 
174
  continue;
175
  }
176
 
@@ -197,6 +211,8 @@ class QM_Collector_Theme extends QM_Collector {
197
  }
198
  }
199
  } else {
 
 
200
  foreach ( get_included_files() as $file ) {
201
  $file = QM_Util::standard_dir( $file );
202
  $filename = str_replace( array(
114
  * @param string[] $templates Array of template files to search for, in order.
115
  */
116
  public function action_get_template_part( $slug, $name, $templates ) {
117
+ $data = compact( 'slug', 'name', 'templates' );
118
+
119
+ $data['trace'] = new QM_Backtrace( array(
120
+ 'ignore_frames' => 4,
121
+ ) );
122
+
123
+ $this->data['requested_template_parts'][] = $data;
124
  }
125
 
126
  public function filter_template_hierarchy( array $templates ) {
168
  $this->data['template_hierarchy'] = array_unique( $this->data['template_hierarchy'] );
169
  }
170
 
171
+ $this->data['has_template_part_action'] = function_exists( 'wp_body_open' );
172
+
173
+ if ( $this->data['has_template_part_action'] ) {
174
+ // Since WP 5.2, the `get_template_part` action populates this data nicely:
175
  if ( ! empty( $this->data['requested_template_parts'] ) ) {
176
  $this->data['template_parts'] = array();
177
  $this->data['theme_template_parts'] = array();
178
  $this->data['count_template_parts'] = array();
179
 
180
+ foreach ( $this->data['requested_template_parts'] as $part ) {
181
+ $file = locate_template( $part['templates'] );
182
+
183
+ $part['caller'] = $part['trace']->get_caller();
184
+ unset( $part['trace'] );
185
+
186
  if ( ! $file ) {
187
+ $this->data['unsuccessful_template_parts'][] = $part;
188
  continue;
189
  }
190
 
211
  }
212
  }
213
  } else {
214
+ // Prior to WP 5.2, we need to look into `get_included_files()` and do our best to figure out
215
+ // if each one is a template part:
216
  foreach ( get_included_files() as $file ) {
217
  $file = QM_Util::standard_dir( $file );
218
  $filename = str_replace( array(
composer.json CHANGED
@@ -16,28 +16,32 @@
16
  "source": "https://github.com/johnbillion/query-monitor"
17
  },
18
  "config": {
 
19
  "preferred-install": "dist"
20
  },
21
  "extra": {
22
  "wordpress-install-dir": "tests/wordpress"
23
  },
24
  "require": {
25
- "php": ">=5.3",
26
  "composer/installers": "~1.0"
27
  },
28
  "require-dev": {
29
  "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
30
- "squizlabs/php_codesniffer": "^3.2",
31
  "phpcompatibility/phpcompatibility-wp": "^2.0",
32
- "wp-coding-standards/wpcs": "~2.0.0",
33
- "wp-phpunit/wp-phpunit": "*",
34
  "roots/wordpress": "*",
 
35
  "vlucas/phpdotenv": "^3",
36
- "johnkary/phpunit-speedtrap": "^1.1",
37
  "wp-cli/wp-cli-bundle": "^2.1",
38
- "phpunit/phpunit": "^5"
 
39
  },
40
  "scripts": {
 
 
 
41
  "test:cs": [
42
  "vendor/bin/phpcs -nps --colors --report-code --report-summary --report-width=80 ."
43
  ],
16
  "source": "https://github.com/johnbillion/query-monitor"
17
  },
18
  "config": {
19
+ "sort-packages": true,
20
  "preferred-install": "dist"
21
  },
22
  "extra": {
23
  "wordpress-install-dir": "tests/wordpress"
24
  },
25
  "require": {
26
+ "php": ">=5.3.6",
27
  "composer/installers": "~1.0"
28
  },
29
  "require-dev": {
30
  "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
31
+ "johnbillion/falsey-assertequals-detector": "^1 || ^3",
32
  "phpcompatibility/phpcompatibility-wp": "^2.0",
33
+ "phpunit/phpunit": "^5 || ^7",
 
34
  "roots/wordpress": "*",
35
+ "squizlabs/php_codesniffer": "^3.2",
36
  "vlucas/phpdotenv": "^3",
 
37
  "wp-cli/wp-cli-bundle": "^2.1",
38
+ "wp-coding-standards/wpcs": "~2.0.0",
39
+ "wp-phpunit/wp-phpunit": "*"
40
  },
41
  "scripts": {
42
+ "post-update-cmd": [
43
+ "@php -r \"! file_exists( 'tests/.env' ) && copy( 'tests/.env.dist', 'tests/.env' );\""
44
+ ],
45
  "test:cs": [
46
  "vendor/bin/phpcs -nps --colors --report-code --report-summary --report-width=80 ."
47
  ],
dispatchers/Html.php CHANGED
@@ -312,18 +312,18 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
312
  echo '</select>';
313
 
314
  echo '</div>';
315
- echo '<div class="qm-title-button"><button class="qm-button-container-settings" aria-label="' . esc_attr__( 'Settings', 'query-monitor' ) . '"><span class="dashicons dashicons-admin-generic" aria-hidden="true"></span></button></div>';
316
- echo '<div class="qm-title-button"><button class="qm-button-container-position" aria-label="' . esc_html__( 'Toggle panel position', 'query-monitor' ) . '"><span class="dashicons dashicons-image-rotate-left" aria-hidden="true"></span></button></div>';
317
- echo '<div class="qm-title-button"><button class="qm-button-container-close" aria-label="' . esc_attr__( 'Close Panel', 'query-monitor' ) . '"><span class="dashicons dashicons-no-alt" aria-hidden="true"></span></button></div>';
318
  echo '</div>'; // #qm-title
319
 
320
  echo '<div id="qm-wrapper">';
321
  echo '<nav id="qm-panel-menu" aria-labelledby="qm-panel-menu-caption">';
322
  echo '<h2 class="qm-screen-reader-text" id="qm-panel-menu-caption">' . esc_html__( 'Query Monitor Menu', 'query-monitor' ) . '</h2>';
323
- echo '<ul>';
324
 
325
  printf(
326
- '<li><button data-qm-href="%1$s">%2$s</button></li>',
327
  '#qm-overview',
328
  esc_html__( 'Overview', 'query-monitor' )
329
  );
@@ -341,13 +341,13 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
341
 
342
  protected function do_panel_menu_item( $id, array $menu ) {
343
  printf(
344
- '<li><button data-qm-href="%1$s">%2$s</button>',
345
  esc_attr( $menu['href'] ),
346
  esc_html( $menu['title'] )
347
  );
348
 
349
  if ( ! empty( $menu['children'] ) ) {
350
- echo '<ul>';
351
  foreach ( $menu['children'] as $child_id => $child ) {
352
  $this->do_panel_menu_item( $child_id, $child );
353
  }
312
  echo '</select>';
313
 
314
  echo '</div>';
315
+ echo '<button class="qm-title-button qm-button-container-settings" aria-label="' . esc_attr__( 'Settings', 'query-monitor' ) . '"><span class="dashicons dashicons-admin-generic" aria-hidden="true"></span></button>';
316
+ echo '<button class="qm-title-button qm-button-container-position" aria-label="' . esc_html__( 'Toggle panel position', 'query-monitor' ) . '"><span class="dashicons dashicons-image-rotate-left" aria-hidden="true"></span></button>';
317
+ echo '<button class="qm-title-button qm-button-container-close" aria-label="' . esc_attr__( 'Close Panel', 'query-monitor' ) . '"><span class="dashicons dashicons-no-alt" aria-hidden="true"></span></button>';
318
  echo '</div>'; // #qm-title
319
 
320
  echo '<div id="qm-wrapper">';
321
  echo '<nav id="qm-panel-menu" aria-labelledby="qm-panel-menu-caption">';
322
  echo '<h2 class="qm-screen-reader-text" id="qm-panel-menu-caption">' . esc_html__( 'Query Monitor Menu', 'query-monitor' ) . '</h2>';
323
+ echo '<ul role="tablist">';
324
 
325
  printf(
326
+ '<li role="presentation"><button role="tab" data-qm-href="%1$s">%2$s</button></li>',
327
  '#qm-overview',
328
  esc_html__( 'Overview', 'query-monitor' )
329
  );
341
 
342
  protected function do_panel_menu_item( $id, array $menu ) {
343
  printf(
344
+ '<li role="presentation"><button role="tab" data-qm-href="%1$s">%2$s</button>',
345
  esc_attr( $menu['href'] ),
346
  esc_html( $menu['title'] )
347
  );
348
 
349
  if ( ! empty( $menu['children'] ) ) {
350
+ echo '<ul role="presentation">';
351
  foreach ( $menu['children'] as $child_id => $child ) {
352
  $this->do_panel_menu_item( $child_id, $child );
353
  }
output/Html.php CHANGED
@@ -41,7 +41,7 @@ abstract class QM_Output_Html extends QM_Output {
41
  $this->current_name = $name;
42
 
43
  printf(
44
- '<div class="qm" id="%1$s" role="group" aria-labelledby="%1$s-caption" tabindex="-1">',
45
  esc_attr( $id )
46
  );
47
 
@@ -73,7 +73,7 @@ abstract class QM_Output_Html extends QM_Output {
73
  $this->current_name = $name;
74
 
75
  printf(
76
- '<div class="qm qm-non-tabular" id="%1$s" role="group" aria-labelledby="%1$s-caption" tabindex="-1">',
77
  esc_attr( $id )
78
  );
79
 
@@ -110,7 +110,7 @@ abstract class QM_Output_Html extends QM_Output {
110
  }
111
 
112
  printf(
113
- '<div class="qm qm-concerns" id="%1$s" role="group" aria-labelledby="%1$s" tabindex="-1">',
114
  esc_attr( $this->current_id . '-concerned_hooks' )
115
  );
116
 
@@ -119,7 +119,11 @@ abstract class QM_Output_Html extends QM_Output {
119
  printf(
120
  '<caption><h2 id="%1$s-caption">%2$s</h2></caption>',
121
  esc_attr( $this->current_id . '-concerned_hooks' ),
122
- esc_html__( 'Related Hooks with Filters or Actions Attached', 'query-monitor' )
 
 
 
 
123
  );
124
 
125
  echo '<thead>';
@@ -156,7 +160,7 @@ abstract class QM_Output_Html extends QM_Output {
156
  }
157
 
158
  printf(
159
- '<div class="qm qm-debug-bar" id="%1$s" role="group" aria-labelledby="%1$s-caption" tabindex="-1">',
160
  esc_attr( $id )
161
  );
162
 
41
  $this->current_name = $name;
42
 
43
  printf(
44
+ '<div class="qm" id="%1$s" role="tabpanel" aria-labelledby="%1$s-caption" tabindex="-1">',
45
  esc_attr( $id )
46
  );
47
 
73
  $this->current_name = $name;
74
 
75
  printf(
76
+ '<div class="qm qm-non-tabular" id="%1$s" role="tabpanel" aria-labelledby="%1$s-caption" tabindex="-1">',
77
  esc_attr( $id )
78
  );
79
 
110
  }
111
 
112
  printf(
113
+ '<div class="qm qm-concerns" id="%1$s" role="tabpanel" aria-labelledby="%1$s-caption" tabindex="-1">',
114
  esc_attr( $this->current_id . '-concerned_hooks' )
115
  );
116
 
119
  printf(
120
  '<caption><h2 id="%1$s-caption">%2$s</h2></caption>',
121
  esc_attr( $this->current_id . '-concerned_hooks' ),
122
+ sprintf(
123
+ /* translators: %s: Panel name */
124
+ esc_html__( '%s: Hooks in Use', 'query-monitor' ),
125
+ esc_html( $this->collector->name() )
126
+ )
127
  );
128
 
129
  echo '<thead>';
160
  }
161
 
162
  printf(
163
+ '<div class="qm qm-debug-bar" id="%1$s" role="tabpanel" aria-labelledby="%1$s-caption" tabindex="-1">',
164
  esc_attr( $id )
165
  );
166
 
output/html/environment.php CHANGED
@@ -168,7 +168,6 @@ class QM_Output_Html_Environment extends QM_Output_Html {
168
  echo '<tbody>';
169
 
170
  $info = array(
171
- 'rdbms' => __( 'RDBMS', 'query-monitor' ),
172
  'server-version' => __( 'Server Version', 'query-monitor' ),
173
  'extension' => __( 'Extension', 'query-monitor' ),
174
  'client-version' => __( 'Client Version', 'query-monitor' ),
168
  echo '<tbody>';
169
 
170
  $info = array(
 
171
  'server-version' => __( 'Server Version', 'query-monitor' ),
172
  'extension' => __( 'Extension', 'query-monitor' ),
173
  'client-version' => __( 'Client Version', 'query-monitor' ),
output/html/theme.php CHANGED
@@ -64,6 +64,10 @@ class QM_Output_Html_Theme extends QM_Output_Html {
64
  echo '<section>';
65
  echo '<h3>' . esc_html__( 'Template Parts', 'query-monitor' ) . '</h3>';
66
 
 
 
 
 
67
  if ( ! empty( $data['template_parts'] ) ) {
68
 
69
  if ( $data['is_child_theme'] ) {
@@ -100,6 +104,25 @@ class QM_Output_Html_Theme extends QM_Output_Html {
100
  echo '<p><em>' . esc_html__( 'None', 'query-monitor' ) . '</em></p>';
101
  }
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  echo '</section>';
104
 
105
  if ( ! empty( $data['timber_files'] ) ) {
64
  echo '<section>';
65
  echo '<h3>' . esc_html__( 'Template Parts', 'query-monitor' ) . '</h3>';
66
 
67
+ if ( $data['has_template_part_action'] ) {
68
+ echo '<h4>' . esc_html__( 'Loaded', 'query-monitor' ) . '</h4>';
69
+ }
70
+
71
  if ( ! empty( $data['template_parts'] ) ) {
72
 
73
  if ( $data['is_child_theme'] ) {
104
  echo '<p><em>' . esc_html__( 'None', 'query-monitor' ) . '</em></p>';
105
  }
106
 
107
+ if ( $data['has_template_part_action'] ) {
108
+ echo '<h4>' . esc_html__( 'Not Loaded', 'query-monitor' ) . '</h4>';
109
+
110
+ if ( ! empty( $data['unsuccessful_template_parts'] ) ) {
111
+ echo '<ul>';
112
+
113
+ foreach ( $data['unsuccessful_template_parts'] as $requested ) {
114
+ echo '<li>';
115
+ $text = implode( ', ', array_filter( array( $requested['slug'], $requested['name'] ) ) );
116
+ echo self::output_filename( $text, $requested['caller']['file'], $requested['caller']['line'], true ); // WPCS: XSS ok.
117
+ echo '</li>';
118
+ }
119
+
120
+ echo '</ul>';
121
+ } elseif ( $data['has_template_part_action'] ) {
122
+ echo '<p><em>' . esc_html__( 'None', 'query-monitor' ) . '</em></p>';
123
+ }
124
+ }
125
+
126
  echo '</section>';
127
 
128
  if ( ! empty( $data['timber_files'] ) ) {
query-monitor.php CHANGED
@@ -10,7 +10,7 @@
10
  *
11
  * Plugin Name: Query Monitor
12
  * Description: The Developer Tools Panel for WordPress.
13
- * Version: 3.3.6
14
  * Plugin URI: https://querymonitor.com/
15
  * Author: John Blackbourn
16
  * Author URI: https://querymonitor.com/
10
  *
11
  * Plugin Name: Query Monitor
12
  * Description: The Developer Tools Panel for WordPress.
13
+ * Version: 3.3.7
14
  * Plugin URI: https://querymonitor.com/
15
  * Author: John Blackbourn
16
  * Author URI: https://querymonitor.com/
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: johnbillion
3
  Tags: debug, debug-bar, debugging, development, developer, performance, profiler, queries, query monitor, rest-api
4
  Requires at least: 3.7
5
  Tested up to: 5.2
6
- Stable tag: 3.3.6
7
  License: GPLv2 or later
8
  Requires PHP: 5.3
9
 
@@ -22,7 +22,7 @@ For complete information, please see [the Query Monitor website](https://querymo
22
  Here's an overview of what's shown for each page load:
23
 
24
  * Database queries, including notifications for slow, duplicate, or erroneous queries. Allows filtering by query type (`SELECT`, `UPDATE`, `DELETE`, etc), responsible component (plugin, theme, WordPress core), and calling function, and provides separate aggregate views for each.
25
- * The template filename, the complete template hierarchy, and names of all template parts used.
26
  * PHP errors presented nicely along with their responsible component and call stack, and a visible warning in the admin toolbar.
27
  * Blocks and associated properties in post content when using WordPress 5.0+ or the Gutenberg plugin.
28
  * Matched rewrite rules, associated query strings, and query vars.
@@ -92,7 +92,16 @@ Yep! You just need to add `define( 'WPCOM_VIP_QM_ENABLE', true );` to your `vip-
92
 
93
  = I'm using multiple instances of `wpdb`. How do I get my additional instances to show up in Query Monitor? =
94
 
95
- 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.
 
 
 
 
 
 
 
 
 
96
 
97
  = Can I click on stack traces to open the file in my editor? =
98
 
3
  Tags: debug, debug-bar, debugging, development, developer, performance, profiler, queries, query monitor, rest-api
4
  Requires at least: 3.7
5
  Tested up to: 5.2
6
+ Stable tag: 3.3.7
7
  License: GPLv2 or later
8
  Requires PHP: 5.3
9
 
22
  Here's an overview of what's shown for each page load:
23
 
24
  * Database queries, including notifications for slow, duplicate, or erroneous queries. Allows filtering by query type (`SELECT`, `UPDATE`, `DELETE`, etc), responsible component (plugin, theme, WordPress core), and calling function, and provides separate aggregate views for each.
25
+ * The template filename, the complete template hierarchy, and names of all template parts that were loaded or not loaded.
26
  * PHP errors presented nicely along with their responsible component and call stack, and a visible warning in the admin toolbar.
27
  * Blocks and associated properties in post content when using WordPress 5.0+ or the Gutenberg plugin.
28
  * Matched rewrite rules, associated query strings, and query vars.
92
 
93
  = I'm using multiple instances of `wpdb`. How do I get my additional instances to show up in Query Monitor? =
94
 
95
+ You'll need to hook into the `qm/collect/db_objects` filter and add an item to the array containing your `wpdb` instance. For example:
96
+
97
+ `
98
+ add_filter( 'qm/collect/db_objects', function( $objects ) {
99
+ $objects['my_db'] = $GLOBALS['my_db'];
100
+ return $objects;
101
+ } );
102
+ `
103
+
104
+ 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.
105
 
106
  = Can I click on stack traces to open the file in my editor? =
107