Skip to content

Commit 27f9c73

Browse files
authored
Improve Query Monitor setup to better support multisite installs (#222)
This PR improves the Query Monitor setup to better support multisite installs. The Query Monitor integration logic tries to eagerly check whether the Query Monitor plugin is active. This is non-trivial for multisites (at that stage, we don't know yet which site is active, etc.). I created a fix that doesn’t do the eager load on multisites. All is set up correctly a bit later, when the QM plugin loads. Not loading it eagerly means we won't log a couple of queries that WP core does before it loads the QM plugin. For single sites, the eager load is still in place.
1 parent 43c60f9 commit 27f9c73

File tree

1 file changed

+57
-31
lines changed

1 file changed

+57
-31
lines changed

integrations/query-monitor/boot.php

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
define( 'QM_DB_SYMLINK', false );
2222
}
2323

24-
// 1. Check if we should load Query Monitor (as per the original "db.php" file).
24+
// Check if we should load Query Monitor (as per the original "db.php" file).
2525
if ( ! defined( 'ABSPATH' ) ) {
2626
exit;
2727
}
@@ -56,29 +56,77 @@
5656
}
5757
}
5858

59+
/*
60+
* Register SQLite enhancements for Query Monitor when plugins are loaded.
61+
*
62+
* This will also ensure that the plugin Query Monitor is fully initialized even
63+
* when we can't load it eagerly, e.g. on a multisite install.
64+
*/
65+
function register_sqlite_enhancements_for_query_monitor() {
66+
if ( ! class_exists( 'QM_Backtrace' ) ) {
67+
return;
68+
}
69+
70+
require_once __DIR__ . '/plugin.php';
71+
72+
if ( ! defined( 'SQLITE_QUERY_MONITOR_LOADED' ) ) {
73+
define( 'SQLITE_QUERY_MONITOR_LOADED', true );
74+
}
75+
}
76+
77+
if ( function_exists( 'add_action' ) ) {
78+
add_action( 'plugins_loaded', 'register_sqlite_enhancements_for_query_monitor' );
79+
}
80+
81+
/*
82+
* On a multisite install, we can't easily determine the current site eagerly.
83+
* Therefore, let's bail out and let Query Monitor activate later as a plugin.
84+
*/
85+
if ( is_multisite() ) {
86+
return;
87+
}
88+
89+
/*
90+
* Now, let's try to load Query Monitor eagerly, to start logging queries early.
91+
* When the plugin is installed, we will check the database if it is also active.
92+
*/
5993
global $wpdb;
6094
if ( ! isset( $wpdb ) ) {
6195
return;
6296
}
6397

64-
// 2. Check if Query Monitor is active.
98+
// Check if Query Monitor is installed.
99+
if ( defined( 'WP_PLUGIN_DIR' ) ) {
100+
$plugins_dir = WP_PLUGIN_DIR;
101+
} else {
102+
$plugins_dir = WP_CONTENT_DIR . '/plugins';
103+
}
104+
105+
$qm_dir = "{$plugins_dir}/query-monitor";
106+
$qm_php = "{$qm_dir}/classes/PHP.php";
107+
108+
if ( ! is_readable( $qm_php ) ) {
109+
return;
110+
}
111+
112+
// Check if Query Monitor is active.
65113
if ( null === $wpdb->options ) {
66114
global $table_prefix;
67115
$wpdb->set_prefix( $table_prefix ?? '' );
68116
}
69117

70118
$query_monitor_active = false;
71119
try {
72-
$value = $wpdb->get_row(
120+
// Make sure no errors are displayed when the query fails.
121+
$show_errors = $wpdb->hide_errors();
122+
$value = $wpdb->get_row(
73123
$wpdb->prepare(
74124
"SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1",
75125
'active_plugins'
76126
)
77127
);
78-
/**
79-
* $value may be null during WordPress Playground multisite setup.
80-
* @see https://github.com/WordPress/sqlite-database-integration/pull/219.
81-
*/
128+
$wpdb->show_errors( $show_errors );
129+
82130
if ( null !== $value ) {
83131
$query_monitor_active = in_array(
84132
'query-monitor/query-monitor.php',
@@ -94,20 +142,7 @@
94142
return;
95143
}
96144

97-
// 3. Determine the plugins directory.
98-
if ( defined( 'WP_PLUGIN_DIR' ) ) {
99-
$plugins_dir = WP_PLUGIN_DIR;
100-
} else {
101-
$plugins_dir = WP_CONTENT_DIR . '/plugins';
102-
}
103-
104-
// 4. Load Query Monitor (as per the original "db.php" file).
105-
$qm_dir = "{$plugins_dir}/query-monitor";
106-
$qm_php = "{$qm_dir}/classes/PHP.php";
107-
108-
if ( ! is_readable( $qm_php ) ) {
109-
return;
110-
}
145+
// Load Query Monitor eagerly (as per the original "db.php" file).
111146
require_once $qm_php;
112147

113148
if ( ! QM_PHP::version_met() ) {
@@ -129,14 +164,5 @@
129164
define( 'SAVEQUERIES', true );
130165
}
131166

132-
// 5. Mark the Query Monitor integration as loaded.
167+
// Mark the Query Monitor integration as loaded.
133168
define( 'SQLITE_QUERY_MONITOR_LOADED', true );
134-
135-
// 6. Register the SQLite enhancements for Query Monitor.
136-
function register_sqlite_enhancements_for_query_monitor() {
137-
require_once __DIR__ . '/plugin.php';
138-
}
139-
140-
if ( function_exists( 'add_action' ) ) {
141-
add_action( 'plugins_loaded', 'register_sqlite_enhancements_for_query_monitor' );
142-
}

0 commit comments

Comments
 (0)