• I’ve put together a script to update roles on a number of users on my wordpress site. It reads a simple CSV file to know what role or roles to give to a particular user, looks up that user by their user ID, and then checks to see if they have a particular role already, adding it if they don’t.

    error_reporting(E_ALL);
    require("../../wp-load.php");
    
    $source_file = 'role_source';
    
    if(($source_handle = fopen($source_file, "r")) !== false) {
    	while(($row = fgetcsv($source_handle)) !== false) {
    		if(count($row) > 2) {
    			if(($user = get_user_by('id', $row[1])) !== false) {
    				for($i = 2; $i < count($row); $i++) {
    					if(!$user->has_cap($row[$i])) {
    						$user->add_role($row[$i]);
    					}
    				}
    			}
    		}
    	}
    
    	fclose($source_handle);
    }

    If I check the users in the database afterwards their wp_capabilities entries in wp_usermeta have been updated, but that’s all. In my template when I call current_user_can() with one of the roles that should have been added to my test user (and that I can see listed in the database) it returns false. So it looks like there’s something else that should be happening that isn’t, or something else I should be doing that I don’t know about.

Viewing 4 replies - 1 through 4 (of 4 total)
  • Moderator bcworkz

    (@bcworkz)

    Are your role names properly formatted? They need to be like post slugs – all lowercase, no special characters except hyphens ‘-‘, no spaces, no diacritics or non-latin characters.

    Thread Starter aoverbury

    (@aoverbury)

    Yes, they are. An example CSV line used as the source is:

    [email protected],99,privilege-group-1,privilege-group-2

    As I noted, the call to WPUser->add_role() succeeds, and wp_usermeta is updated to add the role name to wp_capabilities. It just doesn’t seem to do anything else, so when my template checks to see if the user has a particular role applied, the answer is always ‘no’.

    Moderator bcworkz

    (@bcworkz)

    It looks like current_user_can() works off a cached user object, so when updating roles or capabilities, the function does not reflect the new state until a subsequent request. I don’t have a clue about how to force the cached object to refresh ??

    I made a test page sort of like yours. current_user_can() returned false, just like you experienced. When I reloaded the page, then current_user_can() returned true. If you need the proper result in the same request, do it like the following instead of current_user_can('privilege-group-1'):

    global $current_user;
    $user = get_user_by('id', $current_user->ID );
    if ( $user->has_cap('privilege-group-1')) {
       //do something
    }

    BTW, when you add a role using the user object(such that there is no corresponding role in the global $wp_roles), it actually gets added as a user capability. Everything else works either way, so it doesn’t matter functionally speaking. To make your code more “honest” you may as well use $user->add_cap() instead of $user->add_role(). The result is the same.

    FYI, the intended way to add roles is create an abstract role, add capabilities to it, then assign that role to users. Then when checking capabilities, you check one of the assigned capabilities, not the role itself. So many people have used roles exclusive of capabilities that role support has been retained.

    Thread Starter aoverbury

    (@aoverbury)

    Thanks, bcworkz.

    I know what I’m doing isn’t the best way to do it, but it’s honestly the best I could come up with. The full situation is this:

    We have a number of download packages that we’re making available via WordPress Download Manager. It uses role-based authorisation to enable/disable the ability for a given user to download the files in a package.

    With this, though, I can make it work now. I’ve already got some patches to give to the developers of the plugin because they don’t handle roles as well as they could.

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘WPUser->add_role not really adding role’ is closed to new replies.