WordPress 5.1 introduces new short circuit filters to WP_User_Query
and count_users()
.
The users_pre_query
filter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. was introduced in #44373 and runs before the database query takes place. This enables short-circuiting the database query entirely to return custom results. Returning a non-null value from the filter will bypass WordPress’s default user query (similar to the posts_pre_query
filter for WP_Query
added in #36687).
Developers should note that filtering functions that require pagination information are encouraged to set the total_users
property of the WP_User_Query
object (which is passed to the filter by reference). If WP_User_Query
does not perform a database query, it will not have enough information to generate these values itself.
Using the users_pre_query
Filter
Below is a rough example of how a plugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party can use the filter to replace the default behavior of WP_User_Query
with a call to a remote data store.
function myplugin_do_external_users_query( $users, $user_query ) {
$response = wp_remote_get( 'https://my-remote-data-store/foo/bar' );
if ( 200 === wp_remote_response_code( $response ) ) {
$response = json_decode( wp_remote_retrieve_body( $response ) );
$users = array_map( 'intval', $response->user_ids );
$query->found_users = (int) $response->found_users;
}
return $users;
}
add_filter( 'users_pre_query', 'myplugin_do_external_users_query', 10, 2 );
Similar to posts_pre_query
, callbacks must be careful about fields
– the external API An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. may have to return user IDs or quasi-WP_User
objects, depending on the value of fields
.
A more in-depth example of how this filter can be utilized can be found in this project, which enables user query caching.
Filtering the count_users()
Function
In addition, a pre_count_users
filter was added in #43693 which enables short-circuiting the count_users
function before the database query takes place. Returning a non-null value from the filter will bypass the default queries.
Using the pre_count_users
Filter
Here is a sample code snippet showing how to use this filter:
function myplugin_do_external_users_count( $user_count) {
$response = wp_remote_get( 'https://my-remote-data-store/foo/bar' );
if ( 200 === wp_remote_response_code( $response ) ) {
$response = json_decode( wp_remote_retrieve_body( $response ) );
$user_count = $response->user_count;
}
return $user_count;
}
add_filter( 'pre_count_users', 'myplugin_do_external_users_count', 10, 2 );
More Filters Coming Soon…
Several additional filters for similar query objects are currently being explored and worked on, and are currently slated for a future release:
- A short circuit for
WP_Comment_Query
(#45800). - A short circuit for
WP_Site_Query
and WP_Network_Query
with a plan to add a sites_pre_query
filter (#45749). - A short circuit for
WP_Term_Query
with a plan to add a terms_pre_query
filter (#41246).
Why Add These Filters?
These query pre-filters enable plugins to use an alternate database store for queries, for example returning results from an external service such as an Elasticsearch server. The process started with the main post query, and these are now being expanded that to other queries in WordPress.
#5-1, #dev-notes