Yii2:基于角色可编辑的特定表单字段
Yii2: specific form field editable based on Role
好吧,我可以使用 behaviors
.
将用户 access permissions
(即查看、创建、更新或删除)限制为基于访问控制的表单或视图
但我想知道如何限制特定用户编辑表单中的某些字段,即允许特定字段对某些用户是 read-only
,对某些用户是 editable
。
我能否在模型中提供任何类型的访问规则或在 _form.php
本身中附加一些规则。
谢谢。
正是针对这种情况,我创建了自己的 class 来扩展 ActiveForm
。使用下面的代码,可以将规则添加到一个或多个角色的特定字段。我在我的表格中这样使用它:
<?= $form->field($model, 'foo', [], [AccessUtil::USER_ROLE => RoleBasedActiveForm::INVISIBLE]) ?>
当您不添加任何规则时,基于角色的活动表单将显示一个正常的输入字段。如果你说它应该对角色不可见,它不会显示任何东西,它也支持只读(不可编辑)。
class RoleBasedActiveForm extends ActiveForm {
const VISIBLE = 0;
const INVISIBLE = 1;
const UNEDITABLE = 2;
public function field($model, $attribute, $options = [], $rules = []) {
$case = empty($rules) ? self::VISIBLE : $this->_validateRules($rules);
switch ($case) {
case self::VISIBLE:
return parent::field($model, $attribute, $options);
case self::INVISIBLE:
return;
case self::UNEDITABLE:
return parent::field($model, $attribute, array_merge($options, [
'template' => '{label}' . $model->$attribute,
]));
}
}
private function _validateRules($rules) {
// validate and return a const
}
}
这将完成表单部分。当然,您还必须在发布值后进行一些验证,以确保没有人修改表单。 (将只读更改为可使用检查器或其他内容进行编辑)
是的,就您的要求而言,无需借助任何实用程序即可轻松完成。
试试这个代码:
$form->field($model,'field')->textInput(['disabled' => !\Yii::$app->user->can('admin')]);
您需要将您的字段名称和 admin
替换为您的用户角色。在上面的示例中,只有 admin
可以编辑此字段,对于其他用户,它将显示为禁用或只读。
就是这样。
试试这个。
if(\Yii::$app->user->can('admin')) {
$form->field($model,'field')->textInput();
}
在这种情况下,只有条件匹配时才会出现输入字段。
这是一个更好的答案。您可以将其内联或作为单独的函数放入验证中。
[[ 'input-name' ],
function ($attribute, $params) {
$user_role_array = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId());
if( !array_key_exists( "Role Name", $user_role_array ) ) {
$myOldA = ( $this->getOldAttribute( $attribute ) );
if( $this->{$attribute} !== (string) $myOldA ) {
$this->addError($attribute, "Please contact XXXXX to modify this option. The field has been reset. You may now resubmit the form" );
$this->{$attribute} = $myOldA;
} //End of if attribute equals old attribute
} //End of if array key exists
}, 'skipOnEmpty' => false, 'skipOnError' => false ],
[Next Rule if inline validation]
好吧,我可以使用 behaviors
.
access permissions
(即查看、创建、更新或删除)限制为基于访问控制的表单或视图
但我想知道如何限制特定用户编辑表单中的某些字段,即允许特定字段对某些用户是 read-only
,对某些用户是 editable
。
我能否在模型中提供任何类型的访问规则或在 _form.php
本身中附加一些规则。
谢谢。
正是针对这种情况,我创建了自己的 class 来扩展 ActiveForm
。使用下面的代码,可以将规则添加到一个或多个角色的特定字段。我在我的表格中这样使用它:
<?= $form->field($model, 'foo', [], [AccessUtil::USER_ROLE => RoleBasedActiveForm::INVISIBLE]) ?>
当您不添加任何规则时,基于角色的活动表单将显示一个正常的输入字段。如果你说它应该对角色不可见,它不会显示任何东西,它也支持只读(不可编辑)。
class RoleBasedActiveForm extends ActiveForm {
const VISIBLE = 0;
const INVISIBLE = 1;
const UNEDITABLE = 2;
public function field($model, $attribute, $options = [], $rules = []) {
$case = empty($rules) ? self::VISIBLE : $this->_validateRules($rules);
switch ($case) {
case self::VISIBLE:
return parent::field($model, $attribute, $options);
case self::INVISIBLE:
return;
case self::UNEDITABLE:
return parent::field($model, $attribute, array_merge($options, [
'template' => '{label}' . $model->$attribute,
]));
}
}
private function _validateRules($rules) {
// validate and return a const
}
}
这将完成表单部分。当然,您还必须在发布值后进行一些验证,以确保没有人修改表单。 (将只读更改为可使用检查器或其他内容进行编辑)
是的,就您的要求而言,无需借助任何实用程序即可轻松完成。
试试这个代码:
$form->field($model,'field')->textInput(['disabled' => !\Yii::$app->user->can('admin')]);
您需要将您的字段名称和 admin
替换为您的用户角色。在上面的示例中,只有 admin
可以编辑此字段,对于其他用户,它将显示为禁用或只读。
就是这样。
试试这个。
if(\Yii::$app->user->can('admin')) {
$form->field($model,'field')->textInput();
}
在这种情况下,只有条件匹配时才会出现输入字段。
这是一个更好的答案。您可以将其内联或作为单独的函数放入验证中。
[[ 'input-name' ],
function ($attribute, $params) {
$user_role_array = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId());
if( !array_key_exists( "Role Name", $user_role_array ) ) {
$myOldA = ( $this->getOldAttribute( $attribute ) );
if( $this->{$attribute} !== (string) $myOldA ) {
$this->addError($attribute, "Please contact XXXXX to modify this option. The field has been reset. You may now resubmit the form" );
$this->{$attribute} = $myOldA;
} //End of if attribute equals old attribute
} //End of if array key exists
}, 'skipOnEmpty' => false, 'skipOnError' => false ],
[Next Rule if inline validation]