New Network and Sites Query Filters

WordPress 5.2 introduces new short circuit filters to WP_Site_Query and WP_Network_Query.

These two filters, sites_pre_query and network_pre_query, were introduced in [44983] and run before the database queries are executed. This enables short-circuiting the database query entirely to return custom results. Returning a non-null value from either filter will bypass WordPress’s default network and sites queries respectively (similar to the users_pre_query filter introduced in #44373).

Sites Query Filter

Developers should note that filtering functions that require pagination information are encouraged to set the found_sites property of the WP_Site_Query object (which is passed to the filter by reference). If WP_Site_Query does not perform a database query, it will not have enough information to generate these values itself.

Using the Filter

Below is a rough example of how a plugin can use the filter to replace the default behavior of WP_Site_Query with a call to a remote data store.

function myplugin_do_external_site_query( $sites, $site_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 ) );
		$sites              = array_map( 'intval', $response->site_ids );
		$query->found_sites = (int) $response->found_sites;
	}

	return $sites;
}
add_filter( 'sites_pre_query', 'myplugin_do_external_site_query', 10, 2 );

Networks Query Filter

Developers should note that filtering functions that require pagination information are encouraged to set the total_networks property of the WP_Network_Query object (which is passed to the filter by reference). If WP_Network_Query does not perform a database query, it will not have enough information to generate these values itself.

Using the Filter

Below is a rough example of how a plugin can use the filter to replace the default behavior of WP_Network_Query with a call to a remote data store.

function myplugin_do_external_network_query( $networks, $network_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 ) );
		$networks              = array_map( 'intval', $response->network_ids );
		$query->total_networks = (int) $response->total_networks;
	}

	return $networks;
}
add_filter( 'network_pre_query', 'myplugin_do_external_network_query', 10, 2 );

Other Similar Query Filters

Similar filters for WP_User_Query and count_users() were added in WordPress 5.1.

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_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-2, #dev-notes, #multisite, #networks-sites