Scriptbaker
SCRIPTBAKERAI & Software Engineering
Yii

Allow admin to change user role

Learn how to allow administrators to change user roles in Yii using the Rights module. This guide explains how to add a role dropdown to the user form, assign roles when creating users, update roles when editing accounts, and securely revoke previous roles before assigning new ones.

· 5 min read · By Tahir Yasin

Managing user roles is an important part of any Yii application that has multiple types of users. For example, an application may have administrators, managers, editors, customers, or other custom roles with different permissions.

If you are using the Yii Rights module, you can allow a superuser or administrator to select a user's role directly from the user create or update form. This makes user-role management easier and avoids having to assign roles manually from a separate permissions interface.

In this tutorial, you will learn how to:

  • Add a role dropdown to the Yii user form.
  • Display available roles using the Rights module.
  • Assign a role when creating a new user.
  • Change an existing user's role when updating the account.
  • Remove previously assigned roles before assigning a new role.
  • Restrict role management to authorized administrators.

Prerequisites

Before implementing this functionality, make sure your Yii application has the following:

  • Yii Framework 1.x installed and configured.
  • The Rights module installed and enabled.
  • A user model, such as User.
  • A user create/update form, commonly named _form.php.
  • The appropriate database tables required by the Rights module.

You should also make sure that the administrator who will manage roles has sufficient permissions to assign and revoke roles.

How the Role Assignment Works

The implementation has two main parts. First, a dropdown is added to the user form so an administrator can select a role. Second, the controller reads the selected role and uses the Rights API to assign it to the user.

When an existing user is updated, the previously assigned roles are revoked before the newly selected role is assigned. This prevents the user from unintentionally retaining an old role.

1. Add a Role Dropdown to _form.php

Open your user form file, usually _form.php, and add the following code where you want the role selection field to appear:

Yii::app()->getModule('rights');
if (Yii::app()->user->isSuperuser) {
    $all_roles = new RAuthItemDataProvider('roles', array(
        'type' => 2,
    )
    );
    $data = $all_roles->fetchData();
    echo CHtml::activeDropDownList(
        $model,
        'user_role',
        CHtml::listData($data, 'name', 'name')
    );
}

This code loads the Rights module and retrieves the available roles. The roles are then converted into a list that can be displayed in a Yii dropdown field.

The isSuperuser condition ensures that the role selector is only displayed to users recognized as superusers.

What does RAuthItemDataProvider do?

RAuthItemDataProvider is provided by the Rights module and can be used to retrieve authorization items such as roles. In this example, the provider is configured to return role-type authorization items.

The following line creates the data provider:

$all_roles = new RAuthItemDataProvider('roles', array(    'type' => 2,));

The resulting data is then fetched with:

$data = $all_roles->fetchData();

Finally, CHtml::listData() converts the returned records into values that can be used by the dropdown:

CHtml::listData($data, 'name', 'name')

2. Add the Role Attribute to the User Model

Your form uses $model->user_role, so your User model needs to be able to receive that value.

If user_role is not an actual database column, you can define it as a model property:

class User extends CActiveRecord{    public $user_role;    // Other model methods...}

If you are storing the selected role in the database, make sure the corresponding database column exists and is configured correctly.

When user_role is only being used temporarily to pass the selected role from the form to the controller, a public model property is often sufficient.

3. Update actionCreate() in UsersController.php

Next, update the user creation action so that the selected role is assigned after the user has been successfully saved.

public function actionCreate(){
    $model = new User;
    // Uncomment the following line if AJAX validation is needed
    // $this->performAjaxValidation(
    $model
);
    if (isset($_POST['User'])) {
        $model->attributes = $_POST['User'];
        if ($model->save()) {
            Rights::assign($model->user_role, $model->id);
            $this->redirect(array(
                'view',
                'id' => $model->id
            )
            );
        }
    }
    $this->render('create', array(
        'model' => $model,
    )
    );
}

The important part is:

Rights::assign($model->user_role, $model->id);

After the user is saved, this tells the Rights module to assign the selected role to the newly created user's ID.

It is important to perform the role assignment after $model->save() succeeds because the user's ID may not exist until the record has been inserted into the database.

4. Update actionUpdate() to Change an Existing User's Role

When editing an existing user, you should first identify and revoke the user's current roles before assigning the newly selected role.

public function actionUpdate($id){
    $model = $this->loadModel($id);
    // Uncomment the following line if AJAX validation is needed
    // $this->performAjaxValidation(
    $model
);
    if (isset($_POST['User'])) {
        $model->attributes = $_POST['User'];
        if ($model->save()) {
            Yii::app()->getModule('rights');
            $assignedRoles = Rights::getAssignedRoles($model->id);
            foreach ($assignedRoles as $role => $detail) {
                Rights::revoke($role, $model->id);
            }
            Rights::assign($model->user_role, $model->id);
            $this->redirect(array(
                'view',
                'id' => $model->id
            )
            );
        }
    }
    $this->render('update', array(
        'model' => $model,
    )
    );
}

Why Revoke the Existing Role First?

Suppose a user currently has the Editor role and an administrator changes the dropdown to Manager.

If the application simply assigns the new role without removing the previous role, the user could end up with both roles.

The following code retrieves the user's currently assigned roles:

$assignedRoles = Rights::getAssignedRoles($model->id);

Each existing role is then revoked:

foreach ($assignedRoles as $role => $detail) {    Rights::revoke($role, $model->id);}

After that, the newly selected role is assigned:

Rights::assign($model->user_role, $model->id);

This creates a simple role replacement workflow: remove the old role, then assign the selected role.

5. Display the Current Role When Editing a User

For a better admin experience, the update form should ideally show the user's current role as the selected dropdown value.

You can retrieve the assigned roles before generating the dropdown and use the appropriate value as the selected option. The exact implementation depends on whether your application allows one role or multiple roles per user.

If your application is designed so that every user has exactly one role, make sure the form and controller consistently enforce that assumption.

6. Add a Label to the Role Dropdown

You can also add a label so administrators know exactly what the dropdown controls:

<?php
if (Yii::app()->user->isSuperuser) {
    echo CHtml::activeLabel($model, 'user_role');
    $all_roles = new RAuthItemDataProvider('roles', array(
        'type' => 2,
    )
    );
    $data = $all_roles->fetchData();
    echo CHtml::activeDropDownList(
        $model,
        'user_role',
        CHtml::listData($data, 'name', 'name')
    );
}
?>

This makes the field clearer and keeps it consistent with other Yii form fields.

7. Validate the Selected Role

Because the role value comes from an HTTP request, it should not be trusted blindly. An administrator could manually modify the submitted value instead of selecting an option from the dropdown.

For example, you can validate that the submitted role actually exists before assigning it:

$role = $model->user_role;
if (!empty($role)) {
    $assignedRoles = Rights::getAssignedRoles($model->id);
    foreach ($assignedRoles as $assignedRole => $detail) {
        Rights::revoke($assignedRole, $model->id);
    }
    Rights::assign($role, $model->id);
}

For production applications, it is also a good idea to validate that the current administrator is authorized to manage the requested role.

Security Considerations

User-role management affects authorization, so it should be treated as a security-sensitive operation.

  • Do not allow ordinary users to modify their own authorization role.
  • Restrict role management to trusted administrators.
  • Validate submitted role names before assigning them.
  • Use Yii's authorization checks consistently throughout the application.
  • Do not rely only on hiding the dropdown in the HTML form as a security mechanism.
  • Consider logging important role changes for administrative auditing.

The isSuperuser check is useful for controlling what the administrator sees, but authorization should also be enforced at the controller/action level.

Common Problems and Troubleshooting

Role dropdown is not displayed

Check that the Rights module is installed and configured correctly and that the logged-in account is recognized as a superuser.

Also verify that your application can access the Rights module:

Yii::app()->getModule('rights');

No roles appear in the dropdown

If the dropdown is empty, check the authorization items configured in the Rights module. Make sure the roles you expect to display have the correct authorization-item type.

user_role is not recognized by the model

If user_role is not a database column, define it as a public property in the User model:

public $user_role;

You should also make sure your model's validation rules allow the attribute to be populated when using Yii's mass assignment:

array('user_role', 'safe')

The old role is still assigned

When updating an existing user, make sure you retrieve and revoke the existing roles before assigning the new one:

$assignedRoles = Rights::getAssignedRoles($model->id);foreach ($assignedRoles as $role => $detail) {    Rights::revoke($role, $model->id);}

The role is assigned to the wrong user

Always use the ID of the user that was successfully saved or loaded. In the create action, this is normally $model->id. In the update action, use the ID of the loaded model.

Complete Role Management Flow

The overall workflow can be summarized as follows:

  1. Load the available roles from the Rights module.
  2. Display the roles in a dropdown for authorized administrators.
  3. Submit the selected role with the user form.
  4. Save the user account.
  5. When creating a user, assign the selected role.
  6. When updating a user, revoke existing roles.
  7. Assign the newly selected role.
  8. Redirect the administrator to the user record.

Benefits of Managing Roles from the User Form

Adding role management directly to the user form can simplify administration in applications that frequently create or update user accounts.

  • Faster user management: Administrators can create an account and assign its role in one workflow.
  • Centralized administration: User details and role assignment can be managed from the same interface.
  • Fewer manual steps: Administrators do not need to navigate to a separate role-assignment screen.
  • Consistent permissions: Existing Rights module functionality continues to handle role assignment and revocation.

Conclusion

Allowing an administrator to change a user's role from the Yii user form is straightforward when the Rights module is already integrated into the application. You can load available roles with RAuthItemDataProvider, display them with a Yii dropdown, and use Rights::assign() and Rights::revoke() to manage permissions.

For new users, assign the selected role after the account has been successfully saved. For existing users, remove the previous role before assigning the new one. Most importantly, make sure role-management actions are protected by proper authorization checks because changing a user's role can directly change what that user is allowed to do.

Frequently Asked Questions

How do I add a role dropdown to a Yii user form?

You can use the Rights module's RAuthItemDataProvider to retrieve available roles and CHtml::activeDropDownList() to display them in the Yii user form.

How do I assign a role to a new user in Yii?

After successfully saving the user, call Rights::assign() with the selected role and the new user's ID.

How do I change a user's role in Yii Rights?

Retrieve the user's assigned roles with Rights::getAssignedRoles(), revoke the existing role or roles with Rights::revoke(), and then assign the newly selected role with Rights::assign().

What is RAuthItemDataProvider in Yii?

RAuthItemDataProvider is a data provider included with the Yii Rights module that can retrieve authorization items such as roles for display or management.

Can a Yii user have more than one role?

Yes. The Rights module can support multiple assigned authorization items. However, if your application's business logic expects each user to have only one role, your form and controller should explicitly enforce a single-role workflow.

Why is user_role not saving to the database?

If user_role is not a database column, it is only a temporary model attribute and will not be persisted automatically. In that case, use it to pass the selected role to the Rights module rather than expecting User->save() to store it.

How can I restrict role changes to administrators?

You can conditionally display the role selector to authorized administrators and, more importantly, enforce authorization in the controller before allowing role changes. Hiding a form field alone should not be considered sufficient access control.

Why should I revoke the old role before assigning a new role?

Revoking the previous role prevents an update operation from unintentionally leaving the user with multiple roles when the application is designed for one role per user.

Last updated:

Work with Scriptbaker

Let's talk about your project

Whether you're extending an existing platform, modernising legacy code, or planning something new, our engineers can help. Tell us what you're working on and we'll explore a practical technical solution together.