Make WordPress Core

Opened 3 years ago

Last modified 3 years ago

#53960 new defect (bug)

Construct WP_User::cap_key dynamically from wpdb instance

Reported by: chrisvanpatten's profile chrisvanpatten Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Users Keywords:
Focuses: multisite Cc:


Currently, WP_User is set up to set the cap_key property, which is used as the usermeta key for a user's role on a given site, only when the WP_User instance is instantiated.

This leads to some complication when setting a user role after a switch_to_blog call. While switch_to_blog internally calls a hook which ends up calling wp_switch_roles_and_user, that method only changes the current user's role without impacting other WP_User instances.

This means the following (psuedo-)code would not work as one might expect:


$user  = get_user_by( 'id', 123 ); // note: 123 is not the logged in user here
$sites = get_sites( /* some criteria */ );

foreach ( $sites as $site_id ) {
    switch_to_blog( $site_id );

    $user->set_role( /* some role */ );


The end result is that the role is only applied to the root site, because the user object's cap_key property is never updated when the site is switched.

However, the user's "user level" is updated correctly for each site — because WP_User's update_user_level_from_caps method generates the user meta key dynamically from the blog prefix when the method is called (ref).

I would propose changing the cap_key to be generated dynamically every time it is referenced, rather than only when the object is instantiated or WP_User::for_site() is explicitly called.

Change History (1)

#1 @swissspidy
3 years ago

  • Component changed from Networks and Sites to Users
Note: See TracTickets for help on using tickets.