2015-02-15 2 views
2

Ну, я могу ограничить пользователей access permissions (т. Е. Просматривать, создавать, обновлять или удалять) в формах или представлениях на основе контроля доступа с использованием behaviors.Yii2: поле конкретной формы редактируемое на основе Роль

Но мне интересно, как я могу ограничить определенный пользователь от редактирования некоторых полей в форме, то есть разрешить определенные поля для read-only для некоторых пользователей и editable некоторыми пользователями.

Могу ли я предоставить какое-либо правило доступа в модели или приложить какое-либо правило в самом _form.php.

Спасибо.

ответ

0

Да, это может быть сделано легко, поскольку ур требует, не прибегая к каким-либо утилитам.

Попробуйте этот код:

$form->field($model,'field')->textInput(['disabled' => !\Yii::$app->user->can('admin')]); 

вам нужно заменить ур имя поля и admin с ролью пользователя. В приведенном выше примере только admin может редактировать это поле, для других пользователей оно будет отображаться как отключенное или только для чтения.

Все.

+0

Работает отлично. Спасибо – Pawan

+5

Это работает, но это небезопасно делает его глупым, как ад. Ничто не мешает пользователю публиковать информацию в форме. Любой может легко редактировать HTML, сделать этот вход не отключенным и опубликовать форму, тем самым изменив значение.Если вам нужен безопасный способ сделать это, вы должны использовать это с правилами модели, которые теперь позволят пользователю изменить эту часть модели. Также любой ответ, который говорит вам скрывать ввод, глупо. –

+0

@MihaiP. - Можете ли вы показать мне, как реализовать в правилах модели. Благодарю. – Joshi

2

Для этого случая я создал свой собственный класс, который расширяет ActiveForm. С помощью приведенного ниже кода можно добавить правила в определенное поле для одной или нескольких ролей. Я использую его, как это в моих формах:

<?= $form->field($model, 'foo', [], [AccessUtil::USER_ROLE => RoleBasedActiveForm::INVISIBLE]) ?> 

Роль На основе Active Form будет отображаться нормальное поле ввода, когда вы не добавляете никаких правил. Он ничего не отобразит, если вы скажете, что он должен быть невидим для ролей, а также поддерживает только чтение (UNITED).

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 
    } 
} 

Это займет часть формы. Вы также должны будете сделать некоторую проверку после публикации значений, конечно, чтобы убедиться, что кто-то не изменил форму. (изменено только на редактирование с помощью инспектора или что-то в этом роде)

+0

Привет jagsler - Я пытался реализовать код как за ур предложение, но я получаю ошибку - 'Class«AccessUtil»не found' – Pawan

+0

AccessUtil только мои собственные утилиты Thats держит' const' значения роли, которые я определил. Поэтому у меня обычно есть что-то вроде 'const USER_ROLE = 'user';' и 'const ADMIN_ROLE = 'admin';' здесь. Я полагаю, вы собираетесь где-то хранить роль пользователя? В моем случае «AccessUtil :: USER_ROLE» - это просто ссылка на текстовое представление роли. В validateRules вы можете проверить, соответствует ли роль, которую пользователь имеет в этой строке. – jagsler

+0

Спасибо Jagsler - Можете ли вы любезно поделиться утилитой, как с моим уровнем знаний - я не думаю, что могу ее создать. – Pawan

3

Попробуйте это.

if(\Yii::$app->user->can('admin')) { 
    $form->field($model,'field')->textInput(); 
} 

В этом случае поле ввода появится только в том случае, если условие соответствует.

+0

ваш код работает с модификацией -'if ((\ Yii :: $ app-> user-> can ('admin'))) { $ form-> field ($ model, ' поле ') -> TextInput(); } ' – Pawan

+0

Да, я только дал вам образец. вы должны изменить в соответствии с вашими потребностями. – ankitr

+0

Не нравится этот ответ. Обычно каждый может вставлять данные с инъекцией. – Yevgen

0

Это лучший ответ. Вы помещаете это в валидацию либо в виде строки, либо как отдельную функцию.

[[ '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] 
Смежные вопросы