используйте «когда» во вложенном yii2 EachValidator - PullRequest
0 голосов
/ 20 февраля 2019

есть ли способ использовать атрибут когда во вложенном EveryValidator?Вот мое правило, но оно не работает:

[['list'], 'each', 'rule' => ['required', 'when' => function ($model) {return false;}, 'whenClient' => "function (attribute, value) {return false;}"]],

Я хочу проверить, могу ли я избежать требуемой проверки при некоторых условиях.Поэтому, чтобы проверить это, я всегда говорю return false .Это просто тестовый оператор возврата, чтобы проверить, работает ли он.

1 Ответ

0 голосов
/ 21 февраля 2019

Если вы посмотрите на yii \ validators \ EachValidator source, when атрибут из валидатора внутри rule, так и не был вызван:

if (!$validator->skipOnEmpty || !$validator->isEmpty($v)) {
    $validator->validateAttribute($model, $attribute);
}

Сравните это с его родителемclass yii \ validators \ Validator , он имеет такой код:

foreach ($attributes as $attribute) {
    $skip = $this->skipOnError && $model->hasErrors($attribute)
        || $this->skipOnEmpty && $this->isEmpty($model->$attribute);
    if (!$skip) {
        if ($this->when === null || call_user_func($this->when, $model, $attribute)) {
            $this->validateAttribute($model, $attribute);
        }
    }
}

Один из способов достижения вашей цели - расширить yii\validators\EachValidator и переопределить его метод validateAttribute($model, $attribute) (а также приватныйсвойства и методы, определенные там):

/**
 * @var Validator validator instance.
 */
private $_validator;

/**
 * Returns the validator declared in [[rule]].
 * @param Model|null $model model in which context validator should be created.
 * @return Validator the declared validator.
 */
private function getValidator($model = null)
{
    // same as in parent
}

/**
 * Creates validator object based on the validation rule specified in [[rule]].
 * @param Model|null $model model in which context validator should be created.
 * @throws \yii\base\InvalidConfigException
 * @return Validator validator instance
 */
private function createEmbeddedValidator($model)
{
    // same as in parent
}

/**
 * {@inheritdoc}
 */
public function validateAttribute($model, $attribute)
{
    ... // same as in parent
    foreach ($value as $k => $v) {
        $model->clearErrors($attribute);
        $model->$attribute = $v;
        // start override original code
        $skip = $validator->skipOnEmpty && $validator->isEmpty($v);
        if (!$skip) {
            if ($validator->when === null || call_user_func($validator->when, $model, $attribute)) {
                $validator->validateAttribute($model, $attribute);
            }
        }
        // end override original code
        $filteredValue[$k] = $model->$attribute;
        if ($model->hasErrors($attribute)) {
            ... // same as in parent
        }
    }
    ... // same as in parent
}

Используйте свой пользовательский класс в вашем rules(), например:

[['list'], \app\models\EachValidator::className(), 'rule' => ['required', 'when' => function ($model) {return false;}]]
...