1

I recently had to script the adding of a number of roles to a selection of the users in my database. In order to do so I put together a script like this:

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);
}

This runs against source data that looks like this:

user@domain.com,2,role-slug-1,role-slug-2

And serves to add each of the listed roles that the user doesn't already have to their set. Thing is, it doesn't quite work. If I look in the wp_usermeta table, at the wp_capabilities row I can see the roles listed correctly, and all subsequent calls to WP_User->has_cap(<role name>) return true, but they're the only things that act as if that user has that role. Calling current_user_can() returns false, and any of the plugins that let you manage users and grant them multiple roles deny that this user has those capabilities. Am I missing something here? From the documentation it looks like calling WP_User->add_role() should be all I need to do.

2

This would be best as a comment, but no reputation :)

In the codex they say

"If you are defining a custom role, and adding capabilities to the role using add_role(), be aware that modifying the capabilities array and re-executing add_role() will not necessarily update the role with the new capabilities list. The add_role() function short-circuits if the role already exists in the database. The workaround in this case is to precede your add_role() call with a remove_role() call that targets the role you are adding."

i suspect you could be inside this short-circuit

I say this cause it seems (just from your pasted code, it could be different) that your script could be running more than once (differently as it would do with plugin activation hook). But this is a guess. In this case, just hooking once (and making first remove_role() and then add_role() ) could do the trick

  • It's probably very inefficient to remove and re-add a User Role on every execution. Instead, you should gate the remove behind some query argument like if ($_GET[reload_roles] == true) { remove_role() } That way you can control the reset instead of repeatedly wasting resources. – Mike Jan 15 '16 at 18:00
  • 1
    add_role() and WP_User::add_role() are two different things. – Steve Buzonas Jan 15 '16 at 23:02
  • Unfortunately no. I know the code isn't running twice as it isn't run by Wordpress at all, and as such isn't dependant on filter triggers or anything like that. It's run from the command line on the server to process adding a bunch of roles to users. – Adrian Jan 18 '16 at 1:46
1

I am not sure why you have written codes this way to add user role. And wp_usermeta table does not contain capabilities. It holds only roles assigned to that specific user. Capabilities are stored into wp_options table.

To add role into Wordpress, just use add_role() function. Here is the documentation. If you want to remove/change any user's role, you can use remove_role() then add_role() or simply set_role() method of WP_User class. Here is the similar topic.

To check user's capability, you must have to pass the role name or capability name as a parameter of current_user_can() function. Please see the documentation here.

  • I'm not sure why you've given me this response, because you've told me to do what I've already done, namely get a WP_User object and use add_role() to assign a role to the user account. And I never said that I was looking for capabilities in wp_usermeta. The name of the usermeta row containing the user's current roles is "wp_capabilities". I suggest you rethink your answer because it's not in any way helpful. The problem I'm seeing is not that I can't figure out how to assign roles. It was simply that doing so seemed to have no effect. – Adrian Jan 15 '16 at 0:31
  • @Saikat, you're talking about different things. You are correct in the process of adding a User Role option. The original question pertains to adding an additional role to an existing user. has_cap() is a function of the WP_User class that checks for assigned capabilities and/or roles. – Mike Jan 15 '16 at 18:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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