Filter: wpestate_query_2026_result
This filter fires after the database query has been executed and the result has been
formatted into a standardized array. It is the only post-execution filter in the Query 2026 pipeline.
Unlike the other filters which modify the query before it runs, this filter lets you inspect
or modify the output.
Common use cases for this filter include:
- Logging query performance (how many results were found, how long the query took).
- Recording search analytics (which keywords visitors use, how many results they get).
- Injecting debug information into the result for development.
- Replacing the query results with data from an external search engine (such as Elasticsearch or Algolia).
When Does This Filter Fire?
This filter fires inside the main orchestrator function wpestate_query_2026_property(),
after Step 16 (format and standardize the result array) and before the return statement.
At this point, the WP_Query has been executed and the result array is fully assembled.
Source file: libs/query/query2026/wpestate_query_2026_property.php
Filter Signature
$result = apply_filters( 'wpestate_query_2026_result', $result, $context, $params, $options );
Parameters
| Parameter | Type | Description |
|---|---|---|
| $result | array |
The result array containing the executed query, arguments, and metadata. This is the value you must return from your callback function. |
| $context | string |
The query context: ‘directory’, ‘map’, ‘dashboard’, or ‘featured’. |
| $params | array |
The normalized parameter array that was used to build and execute this query. Useful for understanding what the caller requested (e.g. which keyword was searched, which city was filtered). |
| $options | array | The caller’s options array (read-only reference). |
What the $result Array Contains
The $result array always has these four keys:
| Key | Type | Description |
|---|---|---|
| query | WP_Query |
The fully executed WordPress WP_Query object. You can access the matched posts via $result[‘query’]->posts, the post count via $result[‘query’]->post_count, the generated SQL via $result[‘query’]->request, and use standard loop methods like have_posts() and the_post(). |
| args | array |
The complete WP_Query arguments array that was used to execute the query. This is the same array that was passed to new WP_Query(). |
| total | int |
The total number of matching posts found in the database (equivalent to $query->found_posts). When no_found_rows was set to true, this value will be 0 because WordPress skips the total count for performance. |
| transient_appendix | string |
A cache-key segment used by the transient caching system. You generally do not need to modify this value. |
Child Theme Examples
Example 1: Log Query Performance
This example logs the query context, how many properties were returned on the current page, and the
total number of matching properties to your PHP error log. Useful during development to monitor
query behavior:
<?php
/**
* Log query performance metrics to the PHP error log.
*
* Logs the context, the number of properties returned on the current page,
* and the total number of matching properties in the database.
*
* Only active when WP_DEBUG is enabled. Remove or disable in production.
*
* Add this code to your child theme's functions.php file.
*/
add_filter( 'wpestate_query_2026_result', 'my_child_log_query_performance', 10, 4 );
function my_child_log_query_performance( $result, $context, $params, $options ) {
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
return $result;
}
$returned = $result['query']->post_count;
$total = $result['total'];
error_log( sprintf(
'[query2026-perf] context=%s | returned=%d | total=%d',
$context,
$returned,
$total
) );
return $result;
}
Example 2: Track Search Analytics
If you want to record what keywords visitors search for and how many results they get (for example,
to identify popular search terms or terms that return zero results), you can insert a record into a
custom database table:
<?php
/**
* Record keyword searches and their result counts in a custom analytics table.
*
* This only tracks directory queries where a keyword was used. You must create
* the 'wp_search_analytics' table in your database before using this code.
*
* Table schema:
* CREATE TABLE wp_search_analytics (
* id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
* keyword VARCHAR(255) NOT NULL,
* result_count INT UNSIGNED NOT NULL DEFAULT 0,
* searched_at DATETIME NOT NULL
* );
*
* Add this code to your child theme's functions.php file.
*/
add_filter( 'wpestate_query_2026_result', 'my_child_track_searches', 10, 4 );
function my_child_track_searches( $result, $context, $params, $options ) {
// Only track keyword searches on directory pages.
if ( 'directory' !== $context || empty( $params['keyword'] ) ) {
return $result;
}
global $wpdb;
$wpdb->insert(
$wpdb->prefix . 'search_analytics',
array(
'keyword' => $params['keyword'],
'result_count' => $result['total'],
'searched_at' => current_time( 'mysql' ),
),
array( '%s', '%d', '%s' )
);
return $result;
}
Example 3: Inject Debug Data Into the Result Array
During development, you might want to add extra information to the result array so you can inspect
it in your templates. This example adds a 'debug' key containing the context, params,
generated SQL, and post count:
<?php
/**
* Add debug information to the query result array.
*
* The debug data is available as $result['debug'] in your templates.
* You can output it with print_r() or var_dump() while developing.
*
* Only active when WP_DEBUG is enabled. Remove or disable in production.
*
* Add this code to your child theme's functions.php file.
*/
add_filter( 'wpestate_query_2026_result', 'my_child_debug_result', 10, 4 );
function my_child_debug_result( $result, $context, $params, $options ) {
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
return $result;
}
$result['debug'] = array(
'context' => $context,
'params' => $params,
'sql' => $result['query']->request,
'post_count' => $result['query']->post_count,
'total' => $result['total'],
);
return $result;
}
Example 4: Replace Query Results With Elasticsearch Data
If you are using an external search engine like Elasticsearch or Algolia for faster or more relevant
property searches, you can use this filter to replace the WP_Query results with IDs from your
search engine while still returning a valid WP_Query object that the template code can loop through:
<?php
/**
* Replace WP_Query results with property IDs from Elasticsearch.
*
* This assumes you have a custom function my_es_search() that accepts
* the Query 2026 params array and returns an array of matching post IDs.
*
* The function re-queries WordPress with the ES-returned IDs to get proper
* WP_Post objects, preserving the order from Elasticsearch.
*
* Add this code to your child theme's functions.php file.
*/
add_filter( 'wpestate_query_2026_result', 'my_child_elasticsearch_override', 10, 4 );
function my_child_elasticsearch_override( $result, $context, $params, $options ) {
// Only use Elasticsearch if the function exists (plugin is active).
if ( ! function_exists( 'my_es_search' ) ) {
return $result;
}
// Run the Elasticsearch query with the same params.
$es_ids = my_es_search( $params );
if ( empty( $es_ids ) || ! is_array( $es_ids ) ) {
return $result;
}
// Re-query WordPress with the Elasticsearch IDs to get WP_Post objects.
// This is necessary because template code expects a real WP_Query object.
$es_query = new WP_Query( array(
'post_type' => 'estate_property',
'post__in' => array_map( 'intval', $es_ids ),
'orderby' => 'post__in',
'posts_per_page' => count( $es_ids ),
'no_found_rows' => true,
) );
$result['query'] = $es_query;
$result['total'] = count( $es_ids );
return $result;
}
Important Notes
-
The WP_Query object is fully executed. When your callback receives the
$result array, the query has already run against the database. You can access
properties like$result['query']->posts(array of matched WP_Post objects),
$result['query']->post_count(number of posts on the current page),
$result['query']->found_posts(total matching posts), and
$result['query']->request(the generated SQL string). -
If you replace the
querykey, it must be a WP_Query object.
The template code downstream calls methods likehave_posts()and
the_post()on the query object. If you replace it with something that is not a
WP_Query instance, the property listing templates will break. -
This filter fires for every query context. Use the
$context
parameter to target your callback to specific page types. Without a context check, your callback
will run on every property query including AJAX requests. -
Keep callbacks lightweight. This filter runs after every property query. If your
callback does something expensive (like an HTTP API call or a database insert), make sure you
target a specific context and consider caching to avoid performance issues. -
You can add custom keys to the result array. The pipeline only uses the four
standard keys (query,args,total,
transient_appendix). Any additional keys you add (likedebug) will
be available in the calling code but will be ignored by the pipeline.