Make WordPress Core

Opened 2 years ago

Last modified 2 years ago

#54868 new defect (bug)

[WP_User_Query][Multisite] Run queries in the context of the correct site / blog_id

Reported by: janthiel's profile janthiel Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Users Keywords: has-patch
Focuses: multisite, performance Cc:


Context: WP Multisite

WP_User_Query can be executed from any site to query for users from any other site. This is done using the blog_id parameter.

$user_query = new WP_User_Query( array( 'blog_id' => 42 ) );

Contrary to the commonly used pattern when data is fetched from a specific site within a network, WP_User_Query does not make use of the switch_to_blog / restore_current_blog functions and thus executes code always within the context of the site which called the query instead of the site the query was actually called for.

This has some implications:

  1. Low level functions called within WP_Query are not aware of the correct context. Especially the WP Object Cache called from cache_users is not aware of the correct site and thus stores the resulting data at the wrong site. This has no impact running default WP installations but is conceptionally wrong and prevents any flexibility.
  2. Superfluous code could be removed
    		if ( 'all_with_meta' === $qv['fields'] ) {
    			cache_users( $this->results );
    			$r = array();
    			foreach ( $this->results as $userid ) {
    				$r[ $userid ] = new WP_User( $userid, '', $qv['blog_id'] );
    			$this->results = $r;
    		} elseif ( 'all' === $qv['fields'] ) {
    			foreach ( $this->results as $key => $user ) {
    				$this->results[ $key ] = new WP_User( $user, '', $qv['blog_id'] );
Just one example: The calls to new WP_User could be reduced to new WP_User( $user ) if done within the correct site context already. All the wp_cache_<op> calls within WP_User will also run within the wrong site context.

Using switch_to_blog shifts all wp_cache_<op> and all other functions, hooks, etc. into the right context. The global blog_id will be set correctly to the site that is queried instead of the site that is querying. This will also follow standard WordPress Multisite patterns to access data from other sites.

Change History (3)

This ticket was mentioned in PR #2199 on WordPress/wordpress-develop by JanThiel.

2 years ago

  • Keywords has-patch added

Switch to the queried blog before performing ops which might benefit

Trac ticket:

#2 @SergeyBiryukov
2 years ago

  • Component changed from General to Users

#3 @janthiel
2 years ago

I identified another location of missing context / blog switch inside the User Lists in the Network UI and added it to the PR.

Note: See TracTickets for help on using tickets.