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]