From 6dd9c91343069485139a23b43b9b53a597a5d19a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 10:28:24 +0000 Subject: [PATCH 01/12] Initial plan From 1aa88d17d2a5362d200969e72f0566b9c6667b41 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 10:36:58 +0000 Subject: [PATCH 02/12] Add basic wp profile queries command implementation Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- composer.json | 3 +- features/profile-queries.feature | 61 ++++++++++++++++++++++++ features/profile.feature | 1 + src/Command.php | 80 ++++++++++++++++++++++++++++++++ src/QueryLogger.php | 23 +++++++++ 5 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 features/profile-queries.feature create mode 100644 src/QueryLogger.php diff --git a/composer.json b/composer.json index 7c2eee3a..0b5e4c27 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,8 @@ "profile stage", "profile hook", "profile eval", - "profile eval-file" + "profile eval-file", + "profile queries" ], "readme": { "sections": [ diff --git a/features/profile-queries.feature b/features/profile-queries.feature new file mode 100644 index 00000000..6b426ccb --- /dev/null +++ b/features/profile-queries.feature @@ -0,0 +1,61 @@ +Feature: Profile database queries + + @require-wp-4.0 + Scenario: Show all database queries + Given a WP install + + When I run `wp profile queries --fields=time` + Then STDOUT should contain: + """ + time + """ + And STDOUT should contain: + """ + total + """ + And STDERR should be empty + + @require-wp-4.0 + Scenario: Show queries with specific fields + Given a WP install + + When I run `wp profile queries --fields=query,time` + Then STDOUT should contain: + """ + query + """ + And STDOUT should contain: + """ + time + """ + And STDOUT should contain: + """ + SELECT + """ + And STDERR should be empty + + @require-wp-4.0 + Scenario: Order queries by execution time + Given a WP install + + When I run `wp profile queries --fields=time --orderby=time --order=DESC` + Then STDOUT should contain: + """ + time + """ + And STDERR should be empty + + @require-wp-4.0 + Scenario: Display queries in JSON format + Given a WP install + + When I run `wp profile queries --format=json --fields=query,time` + Then STDOUT should contain: + """ + "query" + """ + And STDOUT should contain: + """ + "time" + """ + And STDERR should be empty diff --git a/features/profile.feature b/features/profile.feature index 459d7d3b..e5c25672 100644 --- a/features/profile.feature +++ b/features/profile.feature @@ -9,6 +9,7 @@ Feature: Basic profile usage usage: wp profile eval [--hook[=]] [--fields=] [--format=] [--order=] [--orderby=] or: wp profile eval-file [--hook[=]] [--fields=] [--format=] [--order=] [--orderby=] or: wp profile hook [] [--all] [--spotlight] [--url=] [--fields=] [--format=] [--order=] [--orderby=] + or: wp profile queries [--url=] [--fields=] [--format=] [--order=] [--orderby=] or: wp profile stage [] [--all] [--spotlight] [--url=] [--fields=] [--format=] [--order=] [--orderby=] See 'wp help profile ' for more information on a specific command. diff --git a/src/Command.php b/src/Command.php index b3d6936d..e745df77 100644 --- a/src/Command.php +++ b/src/Command.php @@ -493,6 +493,86 @@ private static function include_file( $file ) { include $file; } + /** + * Profile database queries and their execution time. + * + * Displays all database queries executed during a WordPress request, + * along with their execution time and caller information. + * + * ## OPTIONS + * + * [--url=] + * : Execute a request against a specified URL. Defaults to the home URL. + * + * [--fields=] + * : Limit the output to specific fields. + * + * [--format=] + * : Render output in a particular format. + * --- + * default: table + * options: + * - table + * - json + * - yaml + * - csv + * --- + * + * [--order=] + * : Ascending or Descending order. + * --- + * default: ASC + * options: + * - ASC + * - DESC + * --- + * + * [--orderby=] + * : Set orderby which field. + * + * ## EXAMPLES + * + * # Show all queries with their execution time + * $ wp profile queries --fields=query,time + * + * # Show all queries with caller information + * $ wp profile queries --fields=query,time,caller + * + * # Show queries ordered by execution time + * $ wp profile queries --fields=query,time --orderby=time --order=DESC + * + * @when before_wp_load + */ + public function queries( $args, $assoc_args ) { + global $wpdb; + + $order = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); + $orderby = Utils\get_flag_value( $assoc_args, 'orderby', null ); + + // Run WordPress profiling + $profiler = new Profiler( null, null ); + $profiler->run(); + + // Get all queries + $queries = array(); + if ( ! empty( $wpdb->queries ) ) { + foreach ( $wpdb->queries as $query_data ) { + $query_obj = new QueryLogger( + $query_data[0], // SQL query + $query_data[1], // Time + isset( $query_data[2] ) ? $query_data[2] : '' // Caller + ); + $queries[] = $query_obj; + } + } + + // Set up fields for output + $fields = array( 'query', 'time', 'caller' ); + + $formatter = new Formatter( $assoc_args, $fields ); + $formatter->display_items( $queries, true, $order, $orderby ); + } + /** * Filter loggers with zero-ish values. * diff --git a/src/QueryLogger.php b/src/QueryLogger.php new file mode 100644 index 00000000..bf941c76 --- /dev/null +++ b/src/QueryLogger.php @@ -0,0 +1,23 @@ +query = $query; + $this->time = $time; + $this->caller = $caller; + $this->hook = $hook; + $this->callback = $callback; + } +} From 7e45434daae6887ff172cc692221988c182a5bd1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 10:38:48 +0000 Subject: [PATCH 03/12] Add hook and callback filtering support for queries command Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/profile-queries.feature | 39 ++++++++++++++ src/Command.php | 89 ++++++++++++++++++++++++++++---- src/Logger.php | 2 + 3 files changed, 121 insertions(+), 9 deletions(-) diff --git a/features/profile-queries.feature b/features/profile-queries.feature index 6b426ccb..6d6edf02 100644 --- a/features/profile-queries.feature +++ b/features/profile-queries.feature @@ -59,3 +59,42 @@ Feature: Profile database queries "time" """ And STDERR should be empty + + @require-wp-4.0 + Scenario: Filter queries by hook + Given a WP install + And a wp-content/mu-plugins/query-test.php file: + """ + query( "SELECT 1 as test_query" ); + }); + """ + + When I run `wp profile queries --hook=init --fields=query,callback` + Then STDOUT should contain: + """ + SELECT 1 as test_query + """ + And STDERR should be empty + + @require-wp-4.0 + Scenario: Filter queries by callback + Given a WP install + And a wp-content/mu-plugins/callback-test.php file: + """ + query( "SELECT 2 as callback_test" ); + } + add_action( 'init', 'my_test_callback' ); + """ + + When I run `wp profile queries --callback=my_test_callback --fields=query,hook` + Then STDOUT should contain: + """ + SELECT 2 as callback_test + """ + And STDERR should be empty diff --git a/src/Command.php b/src/Command.php index e745df77..8bc4f82f 100644 --- a/src/Command.php +++ b/src/Command.php @@ -497,13 +497,21 @@ private static function include_file( $file ) { * Profile database queries and their execution time. * * Displays all database queries executed during a WordPress request, - * along with their execution time and caller information. + * along with their execution time and caller information. You can filter + * queries to only show those executed during a specific hook or by a + * specific callback. * * ## OPTIONS * * [--url=] * : Execute a request against a specified URL. Defaults to the home URL. * + * [--hook=] + * : Filter queries to only show those executed during a specific hook. + * + * [--callback=] + * : Filter queries to only show those executed by a specific callback. + * * [--fields=] * : Limit the output to specific fields. * @@ -535,8 +543,11 @@ private static function include_file( $file ) { * # Show all queries with their execution time * $ wp profile queries --fields=query,time * - * # Show all queries with caller information - * $ wp profile queries --fields=query,time,caller + * # Show queries executed during the 'init' hook + * $ wp profile queries --hook=init --fields=query,time,caller + * + * # Show queries executed by a specific callback + * $ wp profile queries --callback='WP_Query->get_posts()' --fields=query,time * * # Show queries ordered by execution time * $ wp profile queries --fields=query,time --orderby=time --order=DESC @@ -546,21 +557,74 @@ private static function include_file( $file ) { public function queries( $args, $assoc_args ) { global $wpdb; - $order = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); - $orderby = Utils\get_flag_value( $assoc_args, 'orderby', null ); + $hook = Utils\get_flag_value( $assoc_args, 'hook' ); + $callback = Utils\get_flag_value( $assoc_args, 'callback' ); + $order = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); + $orderby = Utils\get_flag_value( $assoc_args, 'orderby', null ); - // Run WordPress profiling - $profiler = new Profiler( null, null ); + // Set up profiler to track hooks and callbacks + $type = null; + $focus = null; + if ( $hook ) { + $type = 'hook'; + $focus = $hook; + } elseif ( $callback ) { + $type = 'hook'; + $focus = true; // Profile all hooks to find the specific callback + } + + $profiler = new Profiler( $type, $focus ); $profiler->run(); + // Build a map of query indices to hooks/callbacks + $query_map = array(); + if ( $hook || $callback ) { + $loggers = $profiler->get_loggers(); + foreach ( $loggers as $logger ) { + // Skip if filtering by callback and this isn't the right one + if ( $callback && isset( $logger->callback ) ) { + // Normalize callback for comparison + $normalized_callback = str_replace( array( '->', '::' ), '', (string) $logger->callback ); + $normalized_filter = str_replace( array( '->', '::' ), '', $callback ); + if ( false === stripos( $normalized_callback, $normalized_filter ) ) { + continue; + } + } + + // Skip if filtering by hook and this isn't the right one + if ( $hook && isset( $logger->hook ) && $logger->hook !== $hook ) { + continue; + } + + // Get the query indices for this logger + if ( isset( $logger->query_indices ) && ! empty( $logger->query_indices ) ) { + foreach ( $logger->query_indices as $query_index ) { + if ( ! isset( $query_map[ $query_index ] ) ) { + $query_map[ $query_index ] = array( + 'hook' => isset( $logger->hook ) ? $logger->hook : null, + 'callback' => isset( $logger->callback ) ? $logger->callback : null, + ); + } + } + } + } + } + // Get all queries $queries = array(); if ( ! empty( $wpdb->queries ) ) { - foreach ( $wpdb->queries as $query_data ) { + foreach ( $wpdb->queries as $index => $query_data ) { + // If filtering by hook/callback, only include queries in the map + if ( ( $hook || $callback ) && ! isset( $query_map[ $index ] ) ) { + continue; + } + $query_obj = new QueryLogger( $query_data[0], // SQL query $query_data[1], // Time - isset( $query_data[2] ) ? $query_data[2] : '' // Caller + isset( $query_data[2] ) ? $query_data[2] : '', // Caller + isset( $query_map[ $index ]['hook'] ) ? $query_map[ $index ]['hook'] : null, + isset( $query_map[ $index ]['callback'] ) ? $query_map[ $index ]['callback'] : null ); $queries[] = $query_obj; } @@ -568,6 +632,13 @@ public function queries( $args, $assoc_args ) { // Set up fields for output $fields = array( 'query', 'time', 'caller' ); + if ( $hook && ! $callback ) { + $fields = array( 'query', 'time', 'callback', 'caller' ); + } elseif ( $callback && ! $hook ) { + $fields = array( 'query', 'time', 'hook', 'caller' ); + } elseif ( $hook && $callback ) { + $fields = array( 'query', 'time', 'hook', 'callback', 'caller' ); + } $formatter = new Formatter( $assoc_args, $fields ); $formatter->display_items( $queries, true, $order, $orderby ); diff --git a/src/Logger.php b/src/Logger.php index 0c3ab116..018f303a 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -7,6 +7,7 @@ class Logger { public $time = 0; public $query_count = 0; public $query_time = 0; + public $query_indices = array(); public $cache_hits = 0; public $cache_misses = 0; public $cache_ratio = null; @@ -87,6 +88,7 @@ public function stop() { for ( $i = $this->query_offset; $i < $query_total_count; $i++ ) { $this->query_time += $wpdb->queries[ $i ][1]; ++$this->query_count; + $this->query_indices[] = $i; } } From 60d53964e072b51e51253a3f7d486344dbc0ce54 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 10:39:40 +0000 Subject: [PATCH 04/12] Add documentation for wp profile queries command Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- README.md | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/README.md b/README.md index e0b95f96..808b2a9f 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,91 @@ will need to execute during the course of the request. +### wp profile queries + +Profile database queries and their execution time. + +~~~ +wp profile queries [--url=] [--hook=] [--callback=] [--fields=] [--format=] [--order=] [--orderby=] +~~~ + +Displays all database queries executed during a WordPress request, +along with their execution time and caller information. You can filter +queries to only show those executed during a specific hook or by a +specific callback. + +**OPTIONS** + + [--url=] + Execute a request against a specified URL. Defaults to the home URL. + + [--hook=] + Filter queries to only show those executed during a specific hook. + + [--callback=] + Filter queries to only show those executed by a specific callback. + + [--fields=] + Limit the output to specific fields. + + [--format=] + Render output in a particular format. + --- + default: table + options: + - table + - json + - yaml + - csv + --- + + [--order=] + Ascending or Descending order. + --- + default: ASC + options: + - ASC + - DESC + --- + + [--orderby=] + Set orderby which field. + +**EXAMPLES** + + # Show all queries with their execution time + $ wp profile queries --fields=query,time + +--------------------------------------+---------+ + | query | time | + +--------------------------------------+---------+ + | SELECT option_value FROM wp_options | 0.0001s | + | SELECT * FROM wp_posts WHERE ID = 1 | 0.0003s | + +--------------------------------------+---------+ + | total (2) | 0.0004s | + +--------------------------------------+---------+ + + # Show queries executed during the 'init' hook + $ wp profile queries --hook=init --fields=query,time,callback + +--------------------------------------+---------+------------------+ + | query | time | callback | + +--------------------------------------+---------+------------------+ + | SELECT * FROM wp_users | 0.0002s | my_init_func() | + +--------------------------------------+---------+------------------+ + | total (1) | 0.0002s | | + +--------------------------------------+---------+------------------+ + + # Show queries executed by a specific callback + $ wp profile queries --callback='WP_Query->get_posts()' --fields=query,time + +--------------------------------------+---------+ + | query | time | + +--------------------------------------+---------+ + | SELECT * FROM wp_posts | 0.0004s | + +--------------------------------------+---------+ + | total (1) | 0.0004s | + +--------------------------------------+---------+ + + + ### wp profile eval Profile arbitrary code execution. From 4a5f4cbbd340fb4c56d3f2ceac6afd20d39ae288 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Sat, 8 Nov 2025 15:27:19 +0100 Subject: [PATCH 05/12] Update src/QueryLogger.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/QueryLogger.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/QueryLogger.php b/src/QueryLogger.php index bf941c76..50ff6b9e 100644 --- a/src/QueryLogger.php +++ b/src/QueryLogger.php @@ -7,10 +7,19 @@ */ class QueryLogger { + /** @var string The SQL query string. */ public $query; + + /** @var float The time taken to execute the query, in seconds. */ public $time; + + /** @var string The caller that initiated the query. */ public $caller; + + /** @var string|null The hook associated with the query, if any. */ public $hook; + + /** @var string|null The callback associated with the query, if any. */ public $callback; public function __construct( $query, $time, $caller, $hook = null, $callback = null ) { From 26ec9f7e0c9b9e758720a753ba3134ea3dd40d04 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Sat, 8 Nov 2025 15:27:25 +0100 Subject: [PATCH 06/12] Update src/Logger.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/Logger.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Logger.php b/src/Logger.php index 018f303a..2048cfe8 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -7,6 +7,9 @@ class Logger { public $time = 0; public $query_count = 0; public $query_time = 0; + /** + * @var array Array of query indices tracked during this logger's execution. + */ public $query_indices = array(); public $cache_hits = 0; public $cache_misses = 0; From 071cb9443adba4dd348c1d0f938a962f0544eaf9 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Sat, 8 Nov 2025 15:27:32 +0100 Subject: [PATCH 07/12] Update features/profile.feature Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- features/profile.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/profile.feature b/features/profile.feature index e5c25672..a57b73fb 100644 --- a/features/profile.feature +++ b/features/profile.feature @@ -9,7 +9,7 @@ Feature: Basic profile usage usage: wp profile eval [--hook[=]] [--fields=] [--format=] [--order=] [--orderby=] or: wp profile eval-file [--hook[=]] [--fields=] [--format=] [--order=] [--orderby=] or: wp profile hook [] [--all] [--spotlight] [--url=] [--fields=] [--format=] [--order=] [--orderby=] - or: wp profile queries [--url=] [--fields=] [--format=] [--order=] [--orderby=] + or: wp profile queries [--url=] [--hook=] [--callback=] [--fields=] [--format=] [--order=] [--orderby=] or: wp profile stage [] [--all] [--spotlight] [--url=] [--fields=] [--format=] [--order=] [--orderby=] See 'wp help profile ' for more information on a specific command. From 9e5aa60f35cc7d95e65e3a31e8fdf11f4595cb6e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 14:30:39 +0000 Subject: [PATCH 08/12] Improve first test scenario to add custom queries Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/profile-queries.feature | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/features/profile-queries.feature b/features/profile-queries.feature index 6d6edf02..ab15af04 100644 --- a/features/profile-queries.feature +++ b/features/profile-queries.feature @@ -3,12 +3,33 @@ Feature: Profile database queries @require-wp-4.0 Scenario: Show all database queries Given a WP install + And a wp-content/mu-plugins/test-queries.php file: + """ + query( "SELECT 1 as test_query_one" ); + $wpdb->query( "SELECT 2 as test_query_two" ); + }); + """ - When I run `wp profile queries --fields=time` + When I run `wp profile queries --fields=query,time` Then STDOUT should contain: + """ + query + """ + And STDOUT should contain: """ time """ + And STDOUT should contain: + """ + SELECT 1 as test_query_one + """ + And STDOUT should contain: + """ + SELECT 2 as test_query_two + """ And STDOUT should contain: """ total From ec1564a4d0cf7b5a716547416b1d0c8a504b15ba Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 10 Nov 2025 16:38:58 +0100 Subject: [PATCH 09/12] Lint fix --- src/Logger.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Logger.php b/src/Logger.php index 2048cfe8..98b0317c 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -4,9 +4,9 @@ class Logger { - public $time = 0; - public $query_count = 0; - public $query_time = 0; + public $time = 0; + public $query_count = 0; + public $query_time = 0; /** * @var array Array of query indices tracked during this logger's execution. */ From 28e1e4d6163761b71eee3e91b20e19ea4dd57cdb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 17:54:20 +0000 Subject: [PATCH 10/12] Fix PHP warnings for non-numeric values in Formatter Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/Formatter.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Formatter.php b/src/Formatter.php index d09101e4..7ea5ef55 100644 --- a/src/Formatter.php +++ b/src/Formatter.php @@ -107,6 +107,7 @@ function ( $a, $b ) use ( $order, $orderby ) { } $location_index = array_search( 'location', $fields, true ); + $non_numeric_fields = array( 'query', 'caller', 'hook', 'callback' ); foreach ( $items as $item ) { $values = array_values( \WP_CLI\Utils\pick_fields( $item, $fields ) ); foreach ( $values as $i => $value ) { @@ -119,6 +120,11 @@ function ( $a, $b ) use ( $order, $orderby ) { continue; } + // Ignore non-numeric fields (query, caller, hook, callback) + if ( in_array( $fields[ $i ], $non_numeric_fields, true ) ) { + continue; + } + if ( null === $totals[ $i ] ) { if ( stripos( $fields[ $i ], '_ratio' ) ) { $totals[ $i ] = array(); @@ -131,7 +137,10 @@ function ( $a, $b ) use ( $order, $orderby ) { $totals[ $i ][] = $value; } } else { - $totals[ $i ] += $value; + // Only add numeric values to prevent warnings + if ( is_numeric( $value ) ) { + $totals[ $i ] += $value; + } } if ( stripos( $fields[ $i ], '_time' ) || 'time' === $fields[ $i ] ) { $values[ $i ] = round( $value, 4 ) . 's'; From 1f255b9f5e9e4093b67fa1a64e7697b31b2f52b6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:28:20 +0000 Subject: [PATCH 11/12] Address code review feedback: fix callback filtering and reset query_indices Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/Command.php | 13 +++++++++++-- src/Logger.php | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Command.php b/src/Command.php index 8bc4f82f..0a2c59a2 100644 --- a/src/Command.php +++ b/src/Command.php @@ -565,7 +565,11 @@ public function queries( $args, $assoc_args ) { // Set up profiler to track hooks and callbacks $type = null; $focus = null; - if ( $hook ) { + if ( $hook && $callback ) { + // When both are provided, profile all hooks to find the specific callback + $type = 'hook'; + $focus = true; + } elseif ( $hook ) { $type = 'hook'; $focus = $hook; } elseif ( $callback ) { @@ -581,6 +585,11 @@ public function queries( $args, $assoc_args ) { if ( $hook || $callback ) { $loggers = $profiler->get_loggers(); foreach ( $loggers as $logger ) { + // Skip if filtering by callback and this logger doesn't have a callback + if ( $callback && ! isset( $logger->callback ) ) { + continue; + } + // Skip if filtering by callback and this isn't the right one if ( $callback && isset( $logger->callback ) ) { // Normalize callback for comparison @@ -591,7 +600,7 @@ public function queries( $args, $assoc_args ) { } } - // Skip if filtering by hook and this isn't the right one + // Skip if filtering for a specific hook and this isn't the right one if ( $hook && isset( $logger->hook ) && $logger->hook !== $hook ) { continue; } diff --git a/src/Logger.php b/src/Logger.php index 98b0317c..03c2d4e3 100644 --- a/src/Logger.php +++ b/src/Logger.php @@ -111,6 +111,7 @@ public function stop() { $this->query_offset = null; $this->cache_hit_offset = null; $this->cache_miss_offset = null; + $this->query_indices = array(); $key = array_search( $this, self::$active_loggers, true ); if ( false !== $key ) { From cc09ca2f50aad186af02516a1d05bf6f5871f22c Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 10 Nov 2025 22:47:09 +0100 Subject: [PATCH 12/12] Update src/Command.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/Command.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Command.php b/src/Command.php index 0a2c59a2..8e1830db 100644 --- a/src/Command.php +++ b/src/Command.php @@ -593,8 +593,8 @@ public function queries( $args, $assoc_args ) { // Skip if filtering by callback and this isn't the right one if ( $callback && isset( $logger->callback ) ) { // Normalize callback for comparison - $normalized_callback = str_replace( array( '->', '::' ), '', (string) $logger->callback ); - $normalized_filter = str_replace( array( '->', '::' ), '', $callback ); + $normalized_callback = trim((string) $logger->callback); + $normalized_filter = trim($callback); if ( false === stripos( $normalized_callback, $normalized_filter ) ) { continue; }