[wp-hackers] User Capabilities

Ryan Boren ryan at boren.nu
Sun Jul 10 22:00:35 GMT 2005


On Sun, 2005-07-10 at 14:39 -0400, Owen Winkler wrote:
> Ryan Boren wrote:
> 
> >For plugin back compat, we'll need to add some code that sets an
> >"equivalent user level" whenever we change a user's role.
> >  
> >
> What do you think about adding a param to add_role() that specifies an 
> equivalent user level?  Not WP_User::set_role(), but WP_Roles::add_role().
> 
> The default set of roles would already have built-in equivalent user 
> levels (via "level_x" caps).  A role itself defines its level, and any 
> future roles that anyone might define will automatically (if added 
> through this API rather than direct database additions) be backwards 
> compatible, since the system will add the appropriate "level_x" caps 
> automatically. 
> 
> Like this:
> 
> $wp_roles->add_role('foo', array('eat_pie'=>true),'Foo',3);
> 
> executes:
> 
> function add_role($role, $capabilities, $display_name, $user_level = 0) {
>     for($z=0;$z<=$user_level;$z++) $capabilities["level_{$z}"] = true;  
> //New line
>     $this->roles[$role] = array('name' => $display_name,
>                                                             
> 'capabilities' => $capabilities);
>     update_option($this->role_key, $this->roles);
>     $this->role_objects[$role] = new WP_Role($role, $capabilities);
>     $this->role_names[$role] = $display_name;
> }

How about we just tell plugin authors to specify "level_X" capabilities
when creating new roles?  One day, when levels are deprecated entirely,
we can simply ignore any level_x capabilities and not be left with any
user_level cruft in the role/cap API.

> When the system updates a user's role, the WP_User class would filter 
> through allcaps (after the role change) looking for the highest 
> "level_x" and then use that to set the user_level for backwards 
> compatibility.
> 
> Something like:
> 
> function level_reduction($max, $item) {
>     if(preg_match('/^level_(10|[0-9])$/i', $item, $matches)) {
>         $level = intval($matches[1]);
>         return max($max, $level);
>     } else {
>         return $max;
>     }
> }
> function update_user_level_from_caps() {
>     global $table_prefix;
>     $this->data->user_level = array_reduce(array_keys($this->allcaps), 
> array(&$this, 'level_reduction'), 0);
>     update_usermeta($this->id, $table_prefix.'user_level', 
> $this->data->user_level);
> }

Sounds good.

> This would help avoid a hard-coded switch statement that converts 
> default roles into user levels, which wouldn't accomodate custom role 
> schemes.  It also doesn't really discourage people from using the old 
> user_level permissions, because everything would still work pretty well 
> that way.
> 
> Grr.  This backwards compatibility thing is a bear.  It's almost not 
> worth the trouble.
> 
> Similarly - I'm just noting this now - capabilities.php probably 
> shouldn't be using translate_level_to_role() from upgrade_functions.php, 
> since the roles in the switch might not exist in a custom role scheme.  
> In what case would get_role() be used with a numeric argument anyway?

I think that is just leftover.  It can probably be removed.

Ryan



More information about the wp-hackers mailing list