New User Related Short Circuit Filters

WordPress 5.1 introduces new short circuit filters to WP_User_Query and count_users().

The users_pre_query filterFilter 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 pluginPlugin 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 APIAPI 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