Opened 5 years ago
Last modified 5 years ago
#53960 new defect (bug)
Construct WP_User::cap_key dynamically from wpdb instance
| Reported by: | chrisvanpatten | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | Users | Version: | |
| Severity: | normal | Keywords: | |
| Cc: | Focuses: | multisite |
Description
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:
<?php $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 */ ); restore_current_blog(); }
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.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)