1

Hopefully this makes sense. I'm still learning.

There is a function in a plugin I'm developing that I want to modify to recognize custom roles.

My function works when it is hard-coded to accept administrator, editor, author, contributor, and subscriber. However, I'm stuck on modifying the conditional to accept all editable roles.

Here is the working code (but hard-coded):

    if ( $current_user->data->wp_capabilities['administrator'] ) {
        $role = 'administrator';
    } elseif ( $current_user->data->wp_capabilities['editor'] ) {
        $role = 'editor';
    } elseif ( $current_user->data->wp_capabilities['author'] ) {
        $role = 'author';
    } elseif ( $current_user->data->wp_capabilities['contributor'] ) {
        $role = 'contributor';
    } elseif ( $current_user->data->wp_capabilities['subscriber'] ) {
        $role = 'subscriber';
    }

    if ( isset( $role ) ) {
        /* If they are an admin then we grant them all permissions that they ask for */
        if ( $current_user->data->wp_capabilities['administrator'] ) {
            foreach ( $new_caps as $new_cap ) {
                $capabilities[ $new_cap ] = true;
            }
            $user->add_role( $role );
        } /* Otherwise lets check if their role deserves that capability    */
        else {
            foreach ( $new_caps as $new_cap ) {
                if ( $wp_roles->get_role( $role )->has_cap( $new_cap ) ) {
                    $capabilities[ $new_cap ] = true;
                    $user->add_role( $role );
                }
            }
        }
    }

Instead of if ... administrator then assign role .... it should be a variable.

I'm guessing but somehow editable roles should be available (?) such as the following.

    $all_roles = $wp_roles->roles;

    $editable_roles = apply_filters('editable_roles', $all_roles);

Can someone help me out and suggest how to rewrite the conditional so it is not hard-coded?

Thank you.

  • You should set a debug message in an else statement for when $role is not set to help debug this question and any answers. It should also be noted that setting a role is a permanent change, it persists after the current page load. I made this mistake and set the user role on every page load in the past not realising WordPress would remember it. – Tom J Nowell Mar 25 '14 at 0:43
2

First, your check code works, and takes this pattern:

if ( $current_user->data->wp_capabilities['hardcoded role name'] ) {
    $role = 'hardcoded role name';
}

So lets swap the hardcoded role string out for a variable called $role_name ( you could call it something else if you want ). The check for a role name is now:

if ( $current_user->data->wp_capabilities[$role_name] ) {
    $role = $role_name;
}

But we need to check more than one role, so, lets make a list of the roles to check

$roles_to_check = array(
    'administrator',
    'editor',
    'author',
    'contributor',
    'subscriber'
);

Then check each role in our list

foreach ( $roles_to_check as $role_name ) {
    .. do the check ..
}

So far everything we've done has been standard programming, with very little PHP specific knowledge. I recommend you take a good look at for loops and arrays as your question indicates a lack of knowledge or confidence in these areas.

But we're not finished. You want to be able to handle any arbitrary role!

So lets start with get_editable_roles(). This will give us an array of roles, but we can't swap out the array from above without a slight modification.

$roles = get_editable_roles();
foreach ( $roles as $role_name => $role_info ) {
    .. do our check ..
}

In your case however you want the roles of a specific user, so going back to your original check, you use this array:

$current_user->data->wp_capabilities

so if we do this for our loop:

foreach ( $current_user->data->wp_capabilities as $role_name => $capability ) {

You should be able to do what you desire

  • First - thank you for the answer. You are correct. I don't think like a programmer because too many manuals, books, videos leave out "obvious" information which takes me a long time to piece together. For example, you state "do the check" ... I suspect you mean 'do the new conditional' with the $role = $role_name. I started walking through your excellent answer by changing the conditionals to the array and foreach. Unfortunately, now the add_role doesn't write to the database. If you could clarify the 'do the check' in case I'm wrong. – LPH Mar 25 '14 at 0:30
  • the .. do the check .. part I already covered in the question, and can be copied as is. The entire final code example can be assembled by copy pasting from my question. I simply refuse to place it all in a single copy paste block because it means people copy paste without reading the answer and don't really understand what the code is doing. – Tom J Nowell Mar 25 '14 at 0:37
  • I've amended the wording slightly of my answer encase it wasn't clear what some things meant to remove some ambiguities – Tom J Nowell Mar 25 '14 at 0:40
  • Argh sorry I added a bit at the end that should simplify things for you, using $current_user->data->wp_capabilities – Tom J Nowell Mar 25 '14 at 0:46
  • Thank you for the edits. I either missed or read past, "The check for a role name is now" ... so I'm on the right track but my code fails. I'll keep reading. Again - I appreciate the help. A var_dump shows the user's correct role is being returned after the foreach. It's just not writing to the database with the add_role in the bottom part. I'm sure it's an 'obvious' error on my part. Many thanks. – LPH Mar 25 '14 at 0:49

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.