Mannie Schumpert
WordPress Developer
(Not actually a magician)
@mannieschumpert
mannieschumpert.com
Roles Summary
Subscriber read
Contributor
create posts, edit and delete own
posts
Author
create posts, edit and delete own
posts, and publish own posts
Editor manage all content
Administrator manage everything
Subscriber Contributor Author Editor Administrator
Capability Levels by Role
“What if these don’t suit my
needs?”
Roll Your Own
add_role
add_cap
add_role('video_editor',	
  'Video	
  Editor',	
  $caps	
  );
$caps	
  =	
  array(	
  
	
  	
  	
  	
  	
  	
  	
  	
  'edit_videos'	
  =>	
  true,	
  
	
  	
  	
  	
  );
Add Role
Add Capabilities to Existing Roles
$role	
  =	
  get_role(	
  'editor'	
  );	
  
$role-­‐>add_cap(	
  'pull_rabbit_out_of_hat'	
  );
The Problem with add_role & add_cap
The Activation Hook
register_activation_hook(	
  __FILE__,	
  'wordcampchs_activate'	
  )	
  );	
  
!
function	
  wordcampchs_activate(){	
  
	
   $caps	
  =	
  array(	
  
	
   	
   	
   'edit_videos'	
  =>	
  true,	
  
	
   	
   );	
  
	
   add_role('video_editor',	
  'Video	
  Editor',	
  $caps	
  );	
  
}
The Magic Filters
user_has_cap
map_meta_cap
The Magic Filters
“Wait, what are filters?”
filter(	
  $data,	
  $info	
  );
What Are Filters?
(pseudo code)
user_has_cap
The Magic Filters
“Does the user have this capability?
Ok, do this other stuff.”
//	
  If	
  you	
  can	
  edit	
  pages,	
  you	
  can	
  edit	
  widgets	
  
	
  	
  
add_filter(	
  'user_has_cap',	
  
function(	
  $caps	
  )	
  {	
  
	
  	
  	
  	
  if	
  (	
  !	
  empty(	
  $caps['edit_pages']	
  )	
  )	
  
	
  	
  	
  	
  	
  	
  	
  	
  $caps['edit_theme_options']	
  =	
  true;	
  
	
  	
  	
  	
  return	
  $caps;	
  
}	
  );
Give Editors Widget Capability
Subscriber Contributor Author Editor Administrator
Capability Levels by Role
Subscriber Contributor Author Editor Administrator
add_filter('user_has_cap',	
  
function(	
  $caps	
  ){	
  
	
   if	
  (!	
  empty(	
  $caps['edit_pages']	
  )	
  )	
  {	
  
	
   	
   $caps['gravityforms_delete_entries']	
  =	
  true;	
  
	
   	
   $caps['gravityforms_edit_entries']	
  =	
  true;	
  
	
   	
   $caps['gravityforms_edit_entry_notes']	
  =	
  true;	
  
	
   	
   $caps['gravityforms_view_entries']	
  =	
  true;	
  
	
   	
   $caps['gravityforms_view_entry_notes']	
  =	
  true;	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
   return	
  $caps;	
  
});
Let Editors View Gravity Forms Entries
map_meta_cap
The Magic Filters
map_meta_cap
/**	
  
	
  *	
  Filter	
  a	
  user's	
  capabilities	
  depending	
  on	
  specific	
  context	
  and/or	
  privilege.	
  
	
  *	
  
	
  *	
  @since	
  2.8.0	
  
	
  *	
  
	
  *	
  @param	
  array	
  	
  $caps	
  	
  	
  	
  Returns	
  the	
  user's	
  actual	
  capabilities.	
  
	
  *	
  @param	
  string	
  $cap	
  	
  	
  	
  	
  Capability	
  name.	
  
	
  *	
  @param	
  int	
  	
  	
  	
  $user_id	
  The	
  user	
  ID.	
  
	
  *	
  @param	
  array	
  	
  $args	
  	
  	
  	
  Adds	
  the	
  context	
  to	
  the	
  cap.	
  Typically	
  the	
  object	
  ID.	
  
	
  */	
  
return	
  apply_filters(	
  'map_meta_cap',	
  $caps,	
  $cap,	
  $user_id,	
  $args	
  );
add_filter('map_meta_cap',	
  'prevent_user_edit',	
  10,	
  4	
  );	
  
!
function	
  prevent_user_edit(	
  $caps,	
  $cap,	
  $user_id,	
  $args	
  ){	
  
	
  	
  
	
   $protected_user	
  =	
  1;	
  //	
  ID	
  of	
  user	
  not	
  editable	
  	
  
!
	
   //	
  Don't	
  block	
  caps	
  if	
  current	
  user	
  =	
  protected	
  user	
  
	
   if	
  (	
  $user_id	
  ===	
  $protected_user	
  )	
  
	
   	
   return	
  $caps;	
  
	
  	
  
	
   $blocked_caps	
  =	
  array(	
  
	
   	
   'delete_user',	
  
	
   	
   'edit_user'	
  
	
   	
   );	
  
	
   if	
  (	
  in_array(	
  $cap,	
  $blocked_caps	
  )	
  &&	
  $args[0]	
  ===	
  $protected_user	
  )	
  
	
   	
   $caps[]	
  =	
  'do_not_allow';	
  
	
  	
  
	
   return	
  $caps;	
  
}
Prevent User Edit
NO
add_filter('map_meta_cap',	
  'prevent_users_edit',	
  10,	
  4	
  );	
  
!
function	
  prevent_users_edit(	
  $caps,	
  $cap,	
  $user_id,	
  $args	
  ){	
  
	
  	
  
	
   $protected_users	
  =	
  array(1,4,19);	
  //	
  IDs	
  of	
  users	
  not	
  editable	
  
	
   $allowed_editor	
  =	
  1;	
  //	
  ID	
  of	
  user	
  who	
  can	
  edit	
  
	
   	
  
	
   if	
  (	
  $user_id	
  ===	
  $allowed_editor	
  )	
  //	
  Don't	
  block	
  caps	
  if	
  allowed	
  editor	
  
	
   	
   return	
  $caps;	
  
	
  	
  
	
   $blocked_caps	
  =	
  array(	
  
	
   	
   'delete_user',	
  
	
   	
   'edit_user'	
  
	
   	
   );	
  
	
   if	
  (	
  in_array(	
  $cap,	
  $blocked_caps	
  )	
  &&	
  in_array(	
  $args[0],	
  
$protected_user	
  )	
  )	
  
	
   	
   $caps[]	
  =	
  'do_not_allow';	
  
	
  	
  
	
   return	
  $caps;	
  
}
Prevent Editing of an Array of Users
DO NOT ALLOW
The Possibilities are Endless
• let a particular user role only edit one taxonomy
• let users of one role edit any other users of the same role
• remove Tools capabilities from all but the primary admin
• prevent some Super Admins from adding sites on a multisite
network
Appendix A
Codex:
http://codex.wordpress.org/Roles_and_Capabilities
http://codex.wordpress.org/Plugin_API/Filter_Reference/
user_has_cap
http://codex.wordpress.org/Function_Reference/
map_meta_cap
Core:
map_meta_cap - /wp-includes/capabilities.php Line 1317
Appendix B
Videos:
“Current User Can Watch This Talk” - Andrew Nacin
http://wordpress.tv/2013/08/10/andrew-nacin-current-user-
can-watch-this-talk/
Code Snippets from Andrew Nacin’s “Current User Can
Watch This Talk”
https://gist.github.com/mannieschumpert/8886289
Appendix C
Article:
WordPress Capabilities Magic with map_meta_cap
http://mannieschumpert.com/blog/wordpress-capabilities-
magic-with-map_meta_cap/

WordPress Capabilities Magic

  • 2.
    Mannie Schumpert WordPress Developer (Notactually a magician) @mannieschumpert mannieschumpert.com
  • 3.
    Roles Summary Subscriber read Contributor createposts, edit and delete own posts Author create posts, edit and delete own posts, and publish own posts Editor manage all content Administrator manage everything
  • 4.
    Subscriber Contributor AuthorEditor Administrator Capability Levels by Role
  • 5.
    “What if thesedon’t suit my needs?”
  • 6.
  • 7.
    add_role('video_editor',  'Video  Editor',  $caps  ); $caps  =  array(                  'edit_videos'  =>  true,          ); Add Role
  • 8.
    Add Capabilities toExisting Roles $role  =  get_role(  'editor'  );   $role-­‐>add_cap(  'pull_rabbit_out_of_hat'  );
  • 9.
    The Problem withadd_role & add_cap
  • 11.
    The Activation Hook register_activation_hook(  __FILE__,  'wordcampchs_activate'  )  );   ! function  wordcampchs_activate(){     $caps  =  array(         'edit_videos'  =>  true,       );     add_role('video_editor',  'Video  Editor',  $caps  );   }
  • 12.
  • 13.
  • 14.
    “Wait, what arefilters?”
  • 15.
    filter(  $data,  $info  ); What Are Filters? (pseudo code)
  • 16.
    user_has_cap The Magic Filters “Doesthe user have this capability? Ok, do this other stuff.”
  • 17.
    //  If  you  can  edit  pages,  you  can  edit  widgets       add_filter(  'user_has_cap',   function(  $caps  )  {          if  (  !  empty(  $caps['edit_pages']  )  )                  $caps['edit_theme_options']  =  true;          return  $caps;   }  ); Give Editors Widget Capability
  • 18.
    Subscriber Contributor AuthorEditor Administrator Capability Levels by Role
  • 19.
    Subscriber Contributor AuthorEditor Administrator
  • 20.
    add_filter('user_has_cap',   function(  $caps  ){     if  (!  empty(  $caps['edit_pages']  )  )  {       $caps['gravityforms_delete_entries']  =  true;       $caps['gravityforms_edit_entries']  =  true;       $caps['gravityforms_edit_entry_notes']  =  true;       $caps['gravityforms_view_entries']  =  true;       $caps['gravityforms_view_entry_notes']  =  true;                  }     return  $caps;   }); Let Editors View Gravity Forms Entries
  • 21.
  • 22.
    map_meta_cap /**    *  Filter  a  user's  capabilities  depending  on  specific  context  and/or  privilege.    *    *  @since  2.8.0    *    *  @param  array    $caps        Returns  the  user's  actual  capabilities.    *  @param  string  $cap          Capability  name.    *  @param  int        $user_id  The  user  ID.    *  @param  array    $args        Adds  the  context  to  the  cap.  Typically  the  object  ID.    */   return  apply_filters(  'map_meta_cap',  $caps,  $cap,  $user_id,  $args  );
  • 23.
    add_filter('map_meta_cap',  'prevent_user_edit',  10,  4  );   ! function  prevent_user_edit(  $caps,  $cap,  $user_id,  $args  ){         $protected_user  =  1;  //  ID  of  user  not  editable     !   //  Don't  block  caps  if  current  user  =  protected  user     if  (  $user_id  ===  $protected_user  )       return  $caps;         $blocked_caps  =  array(       'delete_user',       'edit_user'       );     if  (  in_array(  $cap,  $blocked_caps  )  &&  $args[0]  ===  $protected_user  )       $caps[]  =  'do_not_allow';         return  $caps;   } Prevent User Edit
  • 24.
  • 25.
    add_filter('map_meta_cap',  'prevent_users_edit',  10,  4  );   ! function  prevent_users_edit(  $caps,  $cap,  $user_id,  $args  ){         $protected_users  =  array(1,4,19);  //  IDs  of  users  not  editable     $allowed_editor  =  1;  //  ID  of  user  who  can  edit         if  (  $user_id  ===  $allowed_editor  )  //  Don't  block  caps  if  allowed  editor       return  $caps;         $blocked_caps  =  array(       'delete_user',       'edit_user'       );     if  (  in_array(  $cap,  $blocked_caps  )  &&  in_array(  $args[0],   $protected_user  )  )       $caps[]  =  'do_not_allow';         return  $caps;   } Prevent Editing of an Array of Users
  • 26.
  • 27.
    The Possibilities areEndless • let a particular user role only edit one taxonomy • let users of one role edit any other users of the same role • remove Tools capabilities from all but the primary admin • prevent some Super Admins from adding sites on a multisite network
  • 28.
  • 29.
    Appendix B Videos: “Current UserCan Watch This Talk” - Andrew Nacin http://wordpress.tv/2013/08/10/andrew-nacin-current-user- can-watch-this-talk/ Code Snippets from Andrew Nacin’s “Current User Can Watch This Talk” https://gist.github.com/mannieschumpert/8886289
  • 30.
    Appendix C Article: WordPress CapabilitiesMagic with map_meta_cap http://mannieschumpert.com/blog/wordpress-capabilities- magic-with-map_meta_cap/