Skip to content

Commit 2e03007

Browse files
committed
Render SQLite queries in Query Monitor debug panel
1 parent 84e9303 commit 2e03007

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

integrations/query-monitor/plugin.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php // phpcs:disable WordPress.Files.FileName.InvalidClassFileName
2+
3+
if ( ! class_exists( 'QM_Output_Html_DB_Queries' ) || ! class_exists( 'QM_Collectors' ) ) {
4+
return;
5+
}
6+
7+
/**
8+
* Override Query Monitor's "QM_Output_Html_DB_Queries" to inject SQLite info.
9+
*/
10+
class SQLite_QM_Output_Html_DB_Queries extends QM_Output_Html_DB_Queries {
11+
/**
12+
* Override the parent method to inject SQLite info.
13+
*
14+
* Currently, Query Monitor doesn't provide a way to customize the rendered
15+
* query HTML. To overcome this limitation, we capture the HTML generated by
16+
* the parent method and modify it to inject the SQLite query data.
17+
*
18+
* @param array<string, mixed> $row The row data.
19+
* @param array<int, string> $cols The column names.
20+
* @return void
21+
*/
22+
protected function output_query_row( array $row, array $cols ) {
23+
// Capture the query row HTML.
24+
ob_start();
25+
parent::output_query_row( $row, $cols );
26+
$data = ob_get_length() > 0 ? ob_get_clean() : '';
27+
28+
// Get the corresponding SQLite queries.
29+
global $wpdb;
30+
static $query_index = 0;
31+
$sqlite_queries = $wpdb->queries[ $query_index ]['sqlite_queries'] ?? array();
32+
$sqlite_query_count = count( $sqlite_queries );
33+
$query_index += 1;
34+
35+
// Build the SQLite info HTML.
36+
$sqlite_info = sprintf(
37+
'<div class="qm-info" style="margin: 15px 0 8px;">Executed %d SQLite %s:</div>',
38+
$sqlite_query_count,
39+
1 === $sqlite_query_count ? 'Query' : 'Queries'
40+
);
41+
$sqlite_info .= '<ol>';
42+
foreach ( $sqlite_queries as $query ) {
43+
$sqlite_info .= '<li class="qm-sqlite-query" style="list-style: decimal !important; margin-left: 20px !important;">';
44+
$sqlite_info .= '<code>' . str_replace( '<br>', '', self::format_sql( $query['sql'] ) ) . '</code>';
45+
$sqlite_info .= '</li>';
46+
}
47+
$sqlite_info .= '</ol>';
48+
49+
// Inject toggle button and SQLite info into the query row HTML.
50+
$toggle_button = '<button class="qm-toggle sqlite-toggle" data-on="+" data-off="-" aria-expanded="false" aria-label="Toggle SQLite queries" title="Toggle SQLite queries"><span aria-hidden="true">+</span></button>';
51+
$toggle_content = sprintf( '<div class="qm-toggled" style="display: none;">%s</div>', $sqlite_info );
52+
53+
$data = str_replace( 'qm-row-sql', 'qm-row-sql qm-has-toggle', $data );
54+
$data = preg_replace(
55+
'/(<td class="qm-row-sql.*?">)(.*?)(<\/td>)/s',
56+
implode(
57+
array(
58+
'$1',
59+
str_replace( '$', '\\$', $toggle_button ),
60+
'$2',
61+
str_replace( '$', '\\$', $toggle_content ),
62+
'$3',
63+
)
64+
),
65+
$data
66+
);
67+
echo $data;
68+
}
69+
}
70+
71+
// Remove the default Query Monitor class and replace it with the custom one.
72+
remove_filter( 'qm/outputter/html', 'register_qm_output_html_db_queries', 20 );
73+
add_filter(
74+
'qm/outputter/html',
75+
function () {
76+
$collector = QM_Collectors::get( 'db_queries' );
77+
if ( $collector ) {
78+
$output['db_queries'] = new SQLite_QM_Output_Html_DB_Queries( $collector );
79+
}
80+
return $output;
81+
},
82+
30,
83+
2
84+
);

load.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,8 @@
2626
require_once __DIR__ . '/deactivate.php';
2727
require_once __DIR__ . '/admin-notices.php';
2828
require_once __DIR__ . '/health-check.php';
29+
30+
// Query Monitor integration:
31+
if ( defined( 'SQLITE_QUERY_MONITOR_LOADED' ) && SQLITE_QUERY_MONITOR_LOADED ) {
32+
require_once __DIR__ . '/integrations/query-monitor/plugin.php';
33+
}

wp-includes/sqlite/class-wp-sqlite-db.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,13 @@ public function query( $query ) {
508508
} else {
509509
$this->queries[ $i ]['result'] = (int) $return_val;
510510
}
511+
512+
// Add SQLite query data.
513+
if ( $this->dbh instanceof WP_SQLite_Driver ) {
514+
$this->queries[ $i ]['sqlite_queries'] = $this->dbh->get_last_sqlite_queries();
515+
} else {
516+
$this->queries[ $i ]['sqlite_queries'] = $this->dbh->executed_sqlite_queries;
517+
}
511518
}
512519
return $return_val;
513520
}

0 commit comments

Comments
 (0)