• Dear WordPress team,

    I am learning your WP_Role-System by try and error and found following pretty annoying:

    If adding a role, you check if it is set in the $wp_roles->roles – but if you remove it, you check $wp_roles->role_objects although you just update $wp_roles->roles into the database.
    Finally you get a mess: I try to activate Roles during the activation-hook, but he finds Roles with the same name in the $wp_roles->roles. If I write $wp_roles->remove_role($name); in the line above the $wp_roles->add_role($name) it cannot find the name in the $wp_roles->role_objects and therefore doesn’t unset the role in $wp_roles->roles.

    I changed following:
    wp-includes/capabilities.php
    FROM:

    function remove_role( $role ) {
    		if ( ! isset( $this->role_objects[$role] ))
    			return;
    
    		unset( $this->role_objects[$role] );
    		unset( $this->role_names[$role] );
    		unset( $this->roles[$role] );
    
    		if ( $this->use_db )
    			update_option( $this->role_key, $this->roles );
    	}

    TO:

    function remove_role( $role ) {
    		if ( ! isset( $this->roles[$role] ))
    			return;
    
    		unset( $this->role_objects[$role] );
    		unset( $this->role_names[$role] );
    		unset( $this->roles[$role] );
    
    		if ( $this->use_db )
    			update_option( $this->role_key, $this->roles );
    	}

    It’s only the line if ( ! isset( $this->roles[$role] )) set to roles instead of role_objects.

    I personally think this is a mistake in the logic, cause I would check both times the same variable and it’s no bit change.
    I’d be happy if you see it my way and change it, otherwise I will be changing future releases too (but I don’t like messing with the core).

    Thanks,

    P.S.: I just didn’t know, where to report bugs to, SORRY!

Viewing 2 replies - 1 through 2 (of 2 total)
  • Thread Starter IM_natascha

    (@im_natascha)

    I think it would also be a great idea to make Roles be translated while needed:

    You give them a String, such as ‘My-Member’ and while returning the name, WP translates it for you.
    You would need a text-domain for each role and change the function a bit.

    function get_names() {
    	// old return $this->role_names;
            // new:
            $returning = array()
            foreach($this->role_names as $role => $name) {
                 $returning[$role] = __($name, $this->roles[$role]['textdomain']);
            }
            return $returning;
    }

    Thread Starter IM_natascha

    (@im_natascha)

    I found another thing my common sense is struggling with:

    My workflow with roles is to add those roles everytime WP loades, so if i add a capability to this role, it will be assigned to the $wp_roles->roles BUT NOT to the $wp_roles->role_objects. If I now set a WP_User-Object, it will get all capabilities by $wp_role->get_caps($role) and this will look into $wp_roles->role_objects — this was where the currently added capabilities weren’t applied to!

    I ended up with capabilities which contained the identifier of the role, granted and all capabilities, directly asigned to when creating the role, but none of the capabilities added later on!

    Who else has problems, simply add the following line:

    /**
    	 * Add capability to role.
    	 *
    	 * @since 2.0.0
    	 * @access public
    	 *
    	 * @param string $role Role name.
    	 * @param string $cap Capability name.
    	 * @param bool $grant Optional, default is true. Whether role is capable of performing capability.
    	 */
    	function add_cap( $role, $cap, $grant = true ) {
    		$this->roles[$role]['capabilities'][$cap] = $grant;
    		$this->role_objects[$role]->capabilities[$cap] = $grant; // ADD THIS LINE
    		if ( $this->use_db )
    			update_option( $this->role_key, $this->roles );
    	}
Viewing 2 replies - 1 through 2 (of 2 total)
  • The topic ‘[Bug report] WP_Roles’ is closed to new replies.