Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

even though I think I understand the hierarchy of roles in WordPress, I never really bothered creating my own user roles or custom capabilities.

What I need to achieve is to assign a few capabilities to certain users (who might belonging to different roles: authors, subscribers, contributors...). I plan to use these capabilities to assign some badges in my BuddyPress driven community or to trigger some actions/events in other contexts (discounts in a WooCommerce store for example). At the moment I do not plan to use these to restrict content access.

I understand that WordPress does not allow users to have multiple roles (and this is a bit frustrating). Yet I don't know how to address my case. I might want to have a subscriber with a new capability "x" and also a contributor with new capability "x" or as well as some subscribers with capability "y" but not "x". It's really impractical to me to create several new user roles only to match all the combinations.

An alternative approach would be one similar to bbPress. I noticed that bbPress has its own user roles, which can be assigned to users who may have any WordPress roles. How to do someting alike with my own roles? (and being able to edit such roles for users from the user admin panels?)

Or yet alternatively should I forget about user roles/capabilities and use user_meta instead?

thank you

share|improve this question

1 Answer 1

In WordPress is pretty simple create custom roles and also assign specific capabilities to specific user roles (no matter if from core or custom).

In my plugins I often create an user role that has all the capabilities required by my plugin, and then I attach some of thos capabilities to existing roles.

I'll give you an example, that I think will help you facing this issues.

Assuming you create a plugin that needs 3 capabilities:

  • 'do_foo'
  • 'do_bar'
  • 'do_baz'

You can create a custom role that has all three capabilities, and then

  • assign all 3 categories to administrators
  • assign 'do_bar' and 'do_baz' to editors, authors and constributors
  • assign only 'do_baz' to subscribers

Following simple function does all previous things:

function my_plugin_custom_caps()
{
  $caps = array('do_foo' => true, 'do_bar' => true, 'do_baz' => true);
  // First of all create the new user role, add all custom caps + 'read'
  add_role( 'myrole', 'My Role', array_merge( $caps, array( 'read' => true ) ) );
  // Set specific caps to specific roles.
  // 1. prepare the roles array
  $all_roles = array('administrator', 'editor', 'author', 'constributor', 'subscriber');
  // 2. get WP_Roles object to do the work
  $roles_obj = new WP_Roles();
  // 3. Loop roles and assign caps
  foreach ( $all_roles as $role ) {
    // 4. cycle the caps and assign them one by one using some logic to assign right caps
    foreach ( $assign as $cap ) {
       if( $role === 'subscriber' && $cap !== 'do_baz' ) continue;
       if( $role !== 'administrator' && $cap === 'do_foo' ) continue;
       $roles_obj->add_cap( $role, $cap );
    }
  }
}

Once WordPress saves capabilities on database, is a good idea perform this task on plugin activation, so it runs only once:

register_activation_hook( __FILE__, 'my_plugin_custom_caps' );

Also is a good habit remove added capabilities and custom roles when plugin is deactivated, so you can create a my_plugin_custom_caps_undo function and use it with register_deactivation_hook.

That function would be almost identical to my_plugin_custom_caps(), but remove_role is used instead of add_role and remove_cap instead of add_cap:

function my_custom_caps_undo() {
  remove_role( 'myrole' );
  $caps = array('do_foo' => true, 'do_bar' => true, 'do_baz' => true );
  $all_roles = array('administrator', 'editor', 'author', 'constributor', 'subscriber');
  $roles_obj = new WP_Roles();
  foreach ( $all_roles as $role ) {
    foreach ( $caps as $cap ) {
      if( $role === 'subscriber' && $cap !== 'do_baz' ) continue;
      if( $role !== 'administrator' && $cap === 'do_foo' ) continue;
      $roles_obj->remove_cap( $role, $cap );
    }
  }
}

register_deactivation_hook( __FILE__, 'my_custom_caps_undo' );
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.