WordPress.org

Make WordPress Core

Opened 6 years ago

Closed 5 years ago

#5541 closed enhancement (wontfix)

Refactor and simplify WP_Roles

Reported by: tellyworth Owned by: jacobsantos
Milestone: Priority: normal
Severity: normal Version:
Component: Role/Capability Keywords: needs-patch
Focuses: Cc:

Description

This patch simplifies the way WP_Roles is implemented. Roles are no longer stored in the options table. Instead they are populated at runtime by an action. An action handler in capabilities.php populates the standard roles with current default capabilities. Plugins can hook the same init_roles action to create their own roles.

I also included some related fixes and improvements:

  • Capabilities were duplicated in two places previously (in WP_Roles::roles and again in WP_Role::capabilities). This created a bug where calling $wp_roles->add_cap() could cause the two to get out of sync. They're kept in a single place now.
  • There's a new "{$role}_has_cap" filter that's considerably easier to use than the old role_has_cap filter (it has only one argument).

Issues: I deliberately haven't yet provided an upgrade path for blogs that have custom roles stored in the options table. That might be necessary but I'm not sure how common or vital it is.

Attachments (1)

no_db_roles-r6510-2.patch (11.8 KB) - added by tellyworth 6 years ago.

Download all attachments as: .zip

Change History (8)

comment:1 ryan6 years ago

Translators will love this. They don't like having the role names in the DB.

This is how we should have done it in the first place, but changing will cause grief for some. If we create a plugin that restores the DB role storage, I think this would fly. We'd not use the DB by default, but make it available via plugin. Adding some actions to the various role methods would probably make a plugin pretty trivial.

comment:2 tellyworth6 years ago

It'd be easy enough for a plugin to fetch the old db roles and load them by hooking the init_roles action. Off the top of my head, something like:

function load_db_roles(&$_roles) {
   $role_key = $wpdb->prefix . 'user_roles';
   $roles = get_option($role_key);
   foreach ($roles as $k=>$role) {
      $_roles->add_role($k, $role['name'], $role['capabilities']);
   }
}
add_action('init_roles', 'load_db_roles');

My initial thought on upgrades was, we could examine the old db roles at upgrade time, use array_diff() to find any differences from the default roles, and then store just the diffs in the db (or nothing, if there are no diffs). Then at runtime we load the db roles (if any) and merge it into the new hard-coded roles. That'd be seamless if it worked, but is probably overkill and a bit too fragile.

comment:3 santosj6 years ago

  • Owner changed from anonymous to jacobsantos

comment:4 ryan5 years ago

  • Component changed from General to Role/Capability

comment:6 Denis-de-Bernardy5 years ago

  • Keywords needs-patch added; has-patch removed
  • Milestone changed from 2.9 to Future Release

comment:7 Denis-de-Bernardy5 years ago

  • Milestone Future Release deleted
  • Resolution set to wontfix
  • Status changed from new to closed

see #10201

Note: See TracTickets for help on using tickets.