0

I'm working on a plugin that adds new user roles: Manager and Employee.

Managers are supposed to be a "pseudo-admin". They can manage all post content (private or otherwise), and should be allowed to add/edit/remove Employees or Managers.

I have most of this working. Capabilities of each role have been assigned correctly, but when users with the Manager role add a new user, the user is saved with no assigned role.

I've defined the capabilities for the Manager role as follows:

function wf_getManagerCaps() {
    return array(
        // [...] Stripped out the unrelated caps to keep this question on topic
        "add_users" => true,
        "create_users" => true,
        "edit_users" => true,
        "list_users" => true,
        "promote" => true,
        "remove" => true,
        "delete" => true

        // [...]
    );
}

add_role("wf_manager", "WF Manager", wf_getManagerCaps());

And I hooked into the "editable_roles" filter to limit the Managers' editable roles:

function wf_limitAvailableRoles( $roles ){
    $user = wp_get_current_user();
    if (in_array( WF_MANAGER_ROLE_SLUG, $user->roles)) {
        $roles = array(
            array(
                "name" => "wf_manager",
                "capabilities" => wf_getManagerCaps(),
            ),
            array(
                "name" => "wf_employee",
                "capabilities" => wf_getEmployeeCaps(),
            ),
        );
    }

    return $roles;
}
add_filter( 'editable_roles', 'wf_limitAvailableRoles' );

When adding a new user as a Manager, I only see "WF Employee" and "WF Manager" as options for the new user's role, but when when I hit save, the new employee's role is set to "None".

I suspect I'm missing a filter somewhere that I need to hook into, but I don't know for sure. Any help is greatly appreciated.


Update

Just for kicks, I tried updating the new user's role after adding it to the DB. Once again, I see WF manager and WF Employee as available options, but my selection is not saved. So this is more likely the result of a missing/incorrect capability on the Manager role rather than a missing filter call on the "Add User" process.


Update 2

I've continued digging, but still have not found an answer. However, I do have more information.

I added the same set of user capabilities defined for my manager role to an existing WordPress role (The editor role). Much like the admin user, the editor can successfully select a role when adding/editing users, and it saves the selection as expected.

The probably rules out a "permission" issue with custom role capabilities, and instead highlights a potential shortfall of the custom role itself. I'll keep updating as I find more. Hopefully I (or someone else) will be able to provide an answer eventually.

1 Answer 1

0

This ended up being a pretty significant problem with the function I hooked into editable_roles.

The Goal:

  • Allow Plugin Operators to add new Managers and New Employees
  • Allow Plugin Managers to add new Employees

The Problem:

  • New users added by an Operator and/or a Manager were being saved with no role
  • Operators/Managers could not modify the role of existing users

Test Results:

When the same user management capabilities were given to the WP default Editor role, Editors were able to successfully add/edit users' roles.

Since the issue was exclusive to my custom roles, I temporarily disabled the filter to see what would happen, and once I was no longer restricting editable roles, Operators and Managers were able to add new users without issue. At this point, I knew the issue was tied to my filter function.

I did a var_dump() of the editable roles for the Administrator (which would not be filtered), and a var_dump() of the editable roles for the Operator (which would be filtered).

Long story short, the structure of the two dumped arrays did not match, and that is what was ultimately causing the issue.


Solution

Here is the original function:

function wf_limitAvailableRoles( $roles ){
    $user = wp_get_current_user();
    if (in_array( 'wf_operator', $user->roles)) {
        $roles = array(
            array(
                "name" => "wf_manager",
                "capabilities" => wf_getManagerCaps(),
            ),
            array(
                "name" => "wf_employee",
                "capabilities" => wf_getEmployeeCaps(),
            ),
        );
    }

    return $roles;
}
add_filter( 'editable_roles', 'wf_limitAvailableRoles' );

The issue is my $roles argument. According to the Codex, this array has a very specific formatting requirement, which I was not adhering to.

I had formatted my array as:

array(
    array(
        "name' => [role name]
        "capabilities" => [capabilities]
    ),

    array(
        "name' => [role name]
        "capabilities" => [capabilities]
    )
);

What I really want to use is this:

array(
    [role_slug] => array(
        "name' => [role name]
        "capabilities" => [capabilities]
    ),

    [role_slug] => array(
        "name' => [role name]
        "capabilities" => [capabilities]
    ),
);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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