This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.
Hi guys,
I'm extending the backend \Backend\Models\User
model, and I would like to override the getRoleOptions()
method that populates the radio buttons to choose a user's role with a version that omits the default system roles when the current user is not a super user.
In my Plugin.php file, I have placed the following code in my boot()
method:
\Backend\Models\User::extend(function ($model) {
$model->addDynamicMethod('getRoleOptions', function () {
foreach (UserRole::all() as $role) {
// Hide built-in system roles unless the user is a super user
if (!BackendAuth::getUser()->isSuperUser() && $role->is_system) {
continue;
}
$result[$role->id] = [$role->name, $role->description];
}
return $result;
}
}
Unfortunately, this does not work. I know that my code is not the issue, because it works fine when I manually comment out the getRoleOptions()
method in the built in User
model, but that is obviously not an ideal solution.
So is there a way to override a pre-existing method using addDynamicMethod()
or some other way, or is this simply not possible?
Update:
I have figured out a workaround, it's not ideal but it seems to work reliably.
First I added a 2nd role field called user_role
:
Event::listen('backend.form.extendFields', function($widget) {
if (!$widget->getController() instanceof \Backend\Controllers\Users) {
return;
}
if (!$widget->model instanceof \Backend\Models\User) {
return;
}
$widget->addTabFields([
'user_role' => [
'label' => 'Role',
'commentAbove' => 'Roles define user permissions, which can be overriden on the user level, on the Permissions tab.',
'type' => 'radio',
'required' => 1,
],
]);
}
Then I:
- Made the original
role
field fillable (it's guarded by default) - Populated the field with the roles I want to show
- When saving the form, I reassign the value from the 2nd role field to the original role field
\Backend\Models\User::extend(function ($model) {
// Make the original role field fillable
$model->addFillable(['role']);
// Populate the field with the desired roles
$model->addDynamicMethod('getUserRoleOptions', function () {
foreach (UserRole::all() as $role) {
// Hide built-in system roles unless the user is a super user
if (!BackendAuth::getUser()->isSuperUser() && $role->is_system) {
continue;
}
$result[$role->id] = [$role->name, $role->description];
}
return $result;
}
// Reassign the value from the 2nd role field to the original role field
$model->bindEvent('model.beforeSave', function () use ($model) {
$model->role = $model->user_role;
});
}
I'm still not very excited about making the original role
field fillable, so I am still open to suggestions to improve this solution.
Last updated
Hello,
This is one way to do it. Another way might be to extend the form field and replacing the options
value with a reference to your own logic, however, it is not easy to do this in the current release. It will become easier in v2.2 when the method getField
becomes available.
It lets you do this instead of the addTabFields
call:
$this->getField('role')->options(function() { return []; });
As a side note, this is available now if you want to try October v3 beta.
1-2 of 2