Query Monitor - Version 3.3.3

Version Description

Download this release

Release Info

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

Code changes from version 3.3.2 to 3.3.3

collectors/assets.php CHANGED
@@ -96,6 +96,12 @@ abstract class QM_Collector_Assets extends QM_Collector {
96
  $all_dependencies = array();
97
  $all_dependents = array();
98
 
 
 
 
 
 
 
99
  foreach ( $positions as $position ) {
100
  if ( empty( $this->data[ $position ] ) ) {
101
  continue;
@@ -147,6 +153,9 @@ abstract class QM_Collector_Assets extends QM_Collector {
147
  'dependents' => $dependents,
148
  'dependencies' => $dependencies,
149
  );
 
 
 
150
  }
151
  }
152
 
96
  $all_dependencies = array();
97
  $all_dependents = array();
98
 
99
+ $this->data['counts'] = array(
100
+ 'header' => 0,
101
+ 'footer' => 0,
102
+ 'total' => 0,
103
+ );
104
+
105
  foreach ( $positions as $position ) {
106
  if ( empty( $this->data[ $position ] ) ) {
107
  continue;
153
  'dependents' => $dependents,
154
  'dependencies' => $dependencies,
155
  );
156
+
157
+ $this->data['counts'][ $position ]++;
158
+ $this->data['counts']['total']++;
159
  }
160
  }
161
 
collectors/php_errors.php CHANGED
@@ -321,11 +321,12 @@ class QM_Collector_PHP_Errors extends QM_Collector {
321
  }
322
 
323
  /**
324
- * Checks if the file path is within the specified plugin. This is
325
- * used to scope an error's file path to a plugin.
326
  *
327
- * @param string $plugin_name The name of the plugin
328
- * @param string $file_path The full path to the file
 
329
  * @return bool
330
  */
331
  public function is_affected_component( $component, $component_type, $component_context ) {
321
  }
322
 
323
  /**
324
+ * Checks if the component is of the given type and has the given context. This is
325
+ * used to scope an error to a plugin or theme.
326
  *
327
+ * @param object $component The component.
328
+ * @param string $component_type The component type for comparison.
329
+ * @param string $component_context The component context for comparison.
330
  * @return bool
331
  */
332
  public function is_affected_component( $component, $component_type, $component_context ) {
composer.json CHANGED
@@ -1,12 +1,12 @@
1
  {
2
- "name" : "johnbillion/query-monitor",
3
  "description": "The Developer Tools panel for WordPress.",
4
- "homepage" : "https://github.com/johnbillion/query-monitor/",
5
- "type" : "wordpress-plugin",
6
- "license" : "GPL-2.0-or-later",
7
- "authors" : [
8
  {
9
- "name" : "John Blackbourn",
10
  "homepage": "https://johnblackbourn.com/"
11
  }
12
  ],
@@ -33,21 +33,39 @@
33
  }
34
  }
35
  ],
 
 
 
 
 
 
36
  "require": {
37
  "php": ">=5.3",
38
  "composer/installers": "~1.0"
39
  },
40
- "require-dev" : {
41
  "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
42
  "squizlabs/php_codesniffer": "^3.2",
43
  "phpcompatibility/phpcompatibility-wp": "^2.0",
44
  "danieltj27/dark-mode": "3.2",
45
  "wp-coding-standards/wpcs": "^2",
 
 
 
 
46
  "phpunit/phpunit": "^5"
47
  },
48
  "scripts": {
 
 
 
 
 
 
 
49
  "test": [
50
- "bin/test.sh"
 
51
  ]
52
  }
53
  }
1
  {
2
+ "name": "johnbillion/query-monitor",
3
  "description": "The Developer Tools panel for WordPress.",
4
+ "homepage": "https://github.com/johnbillion/query-monitor/",
5
+ "type": "wordpress-plugin",
6
+ "license": "GPL-2.0-or-later",
7
+ "authors": [
8
  {
9
+ "name": "John Blackbourn",
10
  "homepage": "https://johnblackbourn.com/"
11
  }
12
  ],
33
  }
34
  }
35
  ],
36
+ "config": {
37
+ "preferred-install": "dist"
38
+ },
39
+ "extra": {
40
+ "wordpress-install-dir": "vendor/wordpress/wordpress"
41
+ },
42
  "require": {
43
  "php": ">=5.3",
44
  "composer/installers": "~1.0"
45
  },
46
+ "require-dev": {
47
  "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
48
  "squizlabs/php_codesniffer": "^3.2",
49
  "phpcompatibility/phpcompatibility-wp": "^2.0",
50
  "danieltj27/dark-mode": "3.2",
51
  "wp-coding-standards/wpcs": "^2",
52
+ "wp-phpunit/wp-phpunit": "* || *",
53
+ "roots/wordpress": "* || *",
54
+ "vlucas/phpdotenv": "^3",
55
+ "johnkary/phpunit-speedtrap": "^1.1",
56
  "phpunit/phpunit": "^5"
57
  },
58
  "scripts": {
59
+ "test:cs": [
60
+ "vendor/bin/phpcs -nps --colors --report-code --report-summary --report-width=80 ."
61
+ ],
62
+ "test:ut": [
63
+ "export WP_MULTISITE=0 && vendor/bin/phpunit --verbose --colors=always --exclude-group=ms-required",
64
+ "export WP_MULTISITE=1 && vendor/bin/phpunit --verbose --colors=always --exclude-group=ms-excluded"
65
+ ],
66
  "test": [
67
+ "@test:cs",
68
+ "@test:ut"
69
  ]
70
  }
71
  }
dispatchers/Html.php CHANGED
@@ -268,6 +268,7 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
268
  'ajax_errors' => array(), # @TODO move this into the php_errors collector
269
  );
270
 
 
271
  echo '<script type="text/javascript">' . "\n\n";
272
  echo 'var qm = ' . json_encode( $json ) . ';' . "\n\n";
273
  echo '</script>' . "\n\n";
@@ -508,7 +509,7 @@ class QM_Dispatcher_Html extends QM_Dispatcher {
508
  } );
509
  <?php
510
  echo '</script>' . "\n\n";
511
- echo '<!-- End of Query Monitor output -->' . "\n\n";
512
 
513
  }
514
 
268
  'ajax_errors' => array(), # @TODO move this into the php_errors collector
269
  );
270
 
271
+ echo '<!-- Begin Query Monitor output -->' . "\n\n";
272
  echo '<script type="text/javascript">' . "\n\n";
273
  echo 'var qm = ' . json_encode( $json ) . ';' . "\n\n";
274
  echo '</script>' . "\n\n";
509
  } );
510
  <?php
511
  echo '</script>' . "\n\n";
512
+ echo '<!-- End Query Monitor output -->' . "\n\n";
513
 
514
  }
515
 
output/html/assets.php CHANGED
@@ -32,9 +32,7 @@ abstract class QM_Output_Html_Assets extends QM_Output_Html {
32
  );
33
 
34
  $type_label = $this->get_type_labels();
35
- $type = $this->collector->get_dependency_type();
36
-
37
- $this->type = $type;
38
 
39
  $hosts = array(
40
  __( 'Other', 'query-monitor' ),
@@ -52,14 +50,14 @@ abstract class QM_Output_Html_Assets extends QM_Output_Html {
52
  'local' => $data['host'],
53
  ),
54
  );
55
- echo $this->build_filter( $type . '-host', $hosts, __( 'Host', 'query-monitor' ), $args ); // WPCS: XSS ok.
56
  echo '</th>';
57
  echo '<th scope="col">' . esc_html__( 'Source', 'query-monitor' ) . '</th>';
58
  echo '<th scope="col" class="qm-filterable-column">';
59
- echo $this->build_filter( $type . '-dependencies', $data['dependencies'], __( 'Dependencies', 'query-monitor' ) ); // WPCS: XSS ok.
60
  echo '</th>';
61
  echo '<th scope="col" class="qm-filterable-column">';
62
- echo $this->build_filter( $type . '-dependents', $data['dependents'], __( 'Dependents', 'query-monitor' ) ); // WPCS: XSS ok.
63
  echo '</th>';
64
  echo '<th scope="col">' . esc_html__( 'Version', 'query-monitor' ) . '</th>';
65
  echo '</tr>';
@@ -67,14 +65,11 @@ abstract class QM_Output_Html_Assets extends QM_Output_Html {
67
 
68
  echo '<tbody>';
69
 
70
- $total = 0;
71
-
72
  foreach ( $position_labels as $position => $label ) {
73
  if ( ! empty( $data['assets'][ $position ] ) ) {
74
  foreach ( $data['assets'][ $position ] as $handle => $asset ) {
75
  $this->dependency_row( $handle, $asset, $label );
76
  }
77
- $total += count( $data['assets'][ $position ] );
78
  }
79
  }
80
 
@@ -87,7 +82,7 @@ abstract class QM_Output_Html_Assets extends QM_Output_Html {
87
  '<td colspan="7">%1$s</td>',
88
  sprintf(
89
  esc_html( $type_label['total'] ),
90
- '<span class="qm-items-number">' . esc_html( number_format_i18n( $total ) ) . '</span>'
91
  )
92
  );
93
  echo '</tr>';
@@ -179,8 +174,8 @@ abstract class QM_Output_Html_Assets extends QM_Output_Html {
179
  return $menu;
180
  }
181
 
182
- $type = $this->collector->get_dependency_type();
183
- $label = $this->collector->name();
184
 
185
  $args = array(
186
  'title' => esc_html( $label ),
32
  );
33
 
34
  $type_label = $this->get_type_labels();
35
+ $this->type = $this->collector->get_dependency_type();
 
 
36
 
37
  $hosts = array(
38
  __( 'Other', 'query-monitor' ),
50
  'local' => $data['host'],
51
  ),
52
  );
53
+ echo $this->build_filter( $this->type . '-host', $hosts, __( 'Host', 'query-monitor' ), $args ); // WPCS: XSS ok.
54
  echo '</th>';
55
  echo '<th scope="col">' . esc_html__( 'Source', 'query-monitor' ) . '</th>';
56
  echo '<th scope="col" class="qm-filterable-column">';
57
+ echo $this->build_filter( $this->type . '-dependencies', $data['dependencies'], __( 'Dependencies', 'query-monitor' ) ); // WPCS: XSS ok.
58
  echo '</th>';
59
  echo '<th scope="col" class="qm-filterable-column">';
60
+ echo $this->build_filter( $this->type . '-dependents', $data['dependents'], __( 'Dependents', 'query-monitor' ) ); // WPCS: XSS ok.
61
  echo '</th>';
62
  echo '<th scope="col">' . esc_html__( 'Version', 'query-monitor' ) . '</th>';
63
  echo '</tr>';
65
 
66
  echo '<tbody>';
67
 
 
 
68
  foreach ( $position_labels as $position => $label ) {
69
  if ( ! empty( $data['assets'][ $position ] ) ) {
70
  foreach ( $data['assets'][ $position ] as $handle => $asset ) {
71
  $this->dependency_row( $handle, $asset, $label );
72
  }
 
73
  }
74
  }
75
 
82
  '<td colspan="7">%1$s</td>',
83
  sprintf(
84
  esc_html( $type_label['total'] ),
85
+ '<span class="qm-items-number">' . esc_html( number_format_i18n( $data['counts']['total'] ) ) . '</span>'
86
  )
87
  );
88
  echo '</tr>';
174
  return $menu;
175
  }
176
 
177
+ $type_label = $this->get_type_labels();
178
+ $label = sprintf( $type_label['count'], number_format_i18n( $data['counts']['total'] ) );
179
 
180
  $args = array(
181
  'title' => esc_html( $label ),
output/html/assets_scripts.php CHANGED
@@ -12,6 +12,8 @@ class QM_Output_Html_Assets_Scripts extends QM_Output_Html_Assets {
12
  /* translators: %s: Total number of enqueued scripts */
13
  'total' => _x( 'Total: %s', 'Enqueued scripts', 'query-monitor' ),
14
  'plural' => __( 'Scripts', 'query-monitor' ),
 
 
15
  );
16
  }
17
 
12
  /* translators: %s: Total number of enqueued scripts */
13
  'total' => _x( 'Total: %s', 'Enqueued scripts', 'query-monitor' ),
14
  'plural' => __( 'Scripts', 'query-monitor' ),
15
+ /* translators: %s: Total number of enqueued scripts */
16
+ 'count' => _x( 'Scripts (%s)', 'Enqueued scripts', 'query-monitor' ),
17
  );
18
  }
19
 
output/html/assets_styles.php CHANGED
@@ -12,6 +12,8 @@ class QM_Output_Html_Assets_Styles extends QM_Output_Html_Assets {
12
  /* translators: %s: Total number of enqueued styles */
13
  'total' => _x( 'Total: %s', 'Enqueued styles', 'query-monitor' ),
14
  'plural' => __( 'Styles', 'query-monitor' ),
 
 
15
  );
16
  }
17
 
12
  /* translators: %s: Total number of enqueued styles */
13
  'total' => _x( 'Total: %s', 'Enqueued styles', 'query-monitor' ),
14
  'plural' => __( 'Styles', 'query-monitor' ),
15
+ /* translators: %s: Total number of enqueued styles */
16
+ 'count' => _x( 'Styles (%s)', 'Enqueued styles', 'query-monitor' ),
17
  );
18
  }
19
 
output/html/overview.php CHANGED
@@ -28,13 +28,6 @@ class QM_Output_Html_Overview extends QM_Output_Html {
28
 
29
  $cache = QM_Collectors::get( 'cache' );
30
 
31
- if ( $cache ) {
32
- $cache_data = $cache->get_data();
33
- if ( isset( $cache_data['stats'] ) && isset( $cache_data['cache_hit_percentage'] ) ) {
34
- $cache_hit_percentage = $cache_data['cache_hit_percentage'];
35
- }
36
- }
37
-
38
  $qm_broken = __( 'A JavaScript problem on the page is preventing Query Monitor from working correctly. jQuery may have been blocked from loading.', 'query-monitor' );
39
  $ajax_errors = __( 'PHP errors were triggered during an Ajax request. See your browser developer console for details.', 'query-monitor' );
40
 
@@ -156,69 +149,76 @@ class QM_Output_Html_Overview extends QM_Output_Html {
156
  echo '</section>';
157
  }
158
 
159
- echo '<section>';
160
- echo '<h3>' . esc_html__( 'Object Cache', 'query-monitor' ) . '</h3>';
 
161
 
162
- if ( isset( $cache_hit_percentage ) ) {
163
- echo '<p>';
164
- echo esc_html( sprintf(
165
- /* translators: 1: Cache hit rate percentage, 2: number of cache hits, 3: number of cache misses */
166
- __( '%1$s%% hit rate (%2$s hits, %3$s misses)', 'query-monitor' ),
167
- number_format_i18n( $cache_hit_percentage, 1 ),
168
- number_format_i18n( $cache_data['stats']['cache_hits'], 0 ),
169
- number_format_i18n( $cache_data['stats']['cache_misses'], 0 )
170
- ) );
171
- echo '</p>';
172
- } else {
173
- echo '<p>';
174
- echo esc_html__( 'Object cache statistics are not available', 'query-monitor' );
175
- echo '</p>';
176
- }
177
 
178
- if ( $cache_data['has_object_cache'] ) {
179
- echo '<p><span class="qm-info">';
180
- printf(
181
- '<a href="%s" class="qm-link">%s</a>',
182
- esc_url( network_admin_url( 'plugins.php?plugin_status=dropins' ) ),
183
- esc_html__( 'External object cache in use', 'query-monitor' )
184
- );
185
- echo '</span></p>';
186
- } else {
187
- echo '<p><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
188
- echo esc_html__( 'External object cache not in use', 'query-monitor' );
189
- echo '</span></p>';
 
 
 
190
 
191
- $potentials = array_filter( $cache_data['object_cache_extensions'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
- if ( ! empty( $potentials ) ) {
194
- echo '<ul>';
195
- foreach ( $potentials as $name => $value ) {
196
- echo '<li><span class="qm-warn">';
197
  echo esc_html( sprintf(
198
- /* translators: %s: PHP extension name */
199
- __( 'The %s extension for PHP is installed but is not in use by WordPress', 'query-monitor' ),
200
- $name
201
  ) );
202
- echo '</span></li>';
203
  }
204
- echo '</ul>';
205
  }
206
- }
207
 
208
- if ( $cache_data['has_opcode_cache'] ) {
209
- foreach ( array_filter( $cache_data['opcode_cache_extensions'] ) as $opcache_name => $opcache_state ) {
210
- echo '<p>';
211
- echo esc_html( sprintf(
212
- /* translators: %s: Name of cache driver */
213
- __( 'Opcode cache in use: %s', 'query-monitor' ),
214
- $opcache_name
215
- ) );
216
- echo '</p>';
217
- }
218
  }
219
 
220
- echo '</section>';
221
-
222
  $this->after_non_tabular_output();
223
  }
224
 
28
 
29
  $cache = QM_Collectors::get( 'cache' );
30
 
 
 
 
 
 
 
 
31
  $qm_broken = __( 'A JavaScript problem on the page is preventing Query Monitor from working correctly. jQuery may have been blocked from loading.', 'query-monitor' );
32
  $ajax_errors = __( 'PHP errors were triggered during an Ajax request. See your browser developer console for details.', 'query-monitor' );
33
 
149
  echo '</section>';
150
  }
151
 
152
+ if ( $cache ) {
153
+ echo '<section>';
154
+ echo '<h3>' . esc_html__( 'Object Cache', 'query-monitor' ) . '</h3>';
155
 
156
+ $cache_data = $cache->get_data();
157
+ if ( isset( $cache_data['stats'] ) && isset( $cache_data['cache_hit_percentage'] ) ) {
158
+ $cache_hit_percentage = $cache_data['cache_hit_percentage'];
159
+ }
 
 
 
 
 
 
 
 
 
 
 
160
 
161
+ if ( isset( $cache_hit_percentage ) ) {
162
+ echo '<p>';
163
+ echo esc_html( sprintf(
164
+ /* translators: 1: Cache hit rate percentage, 2: number of cache hits, 3: number of cache misses */
165
+ __( '%1$s%% hit rate (%2$s hits, %3$s misses)', 'query-monitor' ),
166
+ number_format_i18n( $cache_hit_percentage, 1 ),
167
+ number_format_i18n( $cache_data['stats']['cache_hits'], 0 ),
168
+ number_format_i18n( $cache_data['stats']['cache_misses'], 0 )
169
+ ) );
170
+ echo '</p>';
171
+ } else {
172
+ echo '<p>';
173
+ echo esc_html__( 'Object cache statistics are not available', 'query-monitor' );
174
+ echo '</p>';
175
+ }
176
 
177
+ if ( $cache_data['has_object_cache'] ) {
178
+ echo '<p><span class="qm-info">';
179
+ printf(
180
+ '<a href="%s" class="qm-link">%s</a>',
181
+ esc_url( network_admin_url( 'plugins.php?plugin_status=dropins' ) ),
182
+ esc_html__( 'External object cache in use', 'query-monitor' )
183
+ );
184
+ echo '</span></p>';
185
+ } else {
186
+ echo '<p><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
187
+ echo esc_html__( 'External object cache not in use', 'query-monitor' );
188
+ echo '</span></p>';
189
+
190
+ $potentials = array_filter( $cache_data['object_cache_extensions'] );
191
+
192
+ if ( ! empty( $potentials ) ) {
193
+ echo '<ul>';
194
+ foreach ( $potentials as $name => $value ) {
195
+ echo '<li><span class="qm-warn">';
196
+ echo esc_html( sprintf(
197
+ /* translators: %s: PHP extension name */
198
+ __( 'The %s extension for PHP is installed but is not in use by WordPress', 'query-monitor' ),
199
+ $name
200
+ ) );
201
+ echo '</span></li>';
202
+ }
203
+ echo '</ul>';
204
+ }
205
+ }
206
 
207
+ if ( $cache_data['has_opcode_cache'] ) {
208
+ foreach ( array_filter( $cache_data['opcode_cache_extensions'] ) as $opcache_name => $opcache_state ) {
209
+ echo '<p>';
 
210
  echo esc_html( sprintf(
211
+ /* translators: %s: Name of cache driver */
212
+ __( 'Opcode cache in use: %s', 'query-monitor' ),
213
+ $opcache_name
214
  ) );
215
+ echo '</p>';
216
  }
 
217
  }
 
218
 
219
+ echo '</section>';
 
 
 
 
 
 
 
 
 
220
  }
221
 
 
 
222
  $this->after_non_tabular_output();
223
  }
224
 
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.2
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.3
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.1
6
- Stable tag: 3.3.2
7
  License: GPLv2 or later
8
  Requires PHP: 5.3
9
 
@@ -94,6 +94,10 @@ Yep! You just need to add `define( 'WPCOM_VIP_QM_ENABLE', true );` to your `vip-
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
  = Do you accept donations? =
98
 
99
  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!
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.1
6
+ Stable tag: 3.3.3
7
  License: GPLv2 or later
8
  Requires PHP: 5.3
9
 
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
+
99
+ Yes! You just need to [enable clickable stack traces](https://querymonitor.com/blog/2019/02/clickable-stack-traces-and-function-names-in-query-monitor/).
100
+
101
  = Do you accept donations? =
102
 
103
  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!