Yii2: custom validation for multiple attributes us

2019-07-23 10:55发布

问题:

I am trying to write a rule that validates if attribute_a or attribute_b is set;

one of the following attributes must be set : licitatii_publice or licitatiile_atribuite

The following code does not work;

<?php

namespace common\models;

use yii\base\Model;

class AbonamentValidare extends Model {

    public $licitatii_publice;
    public $licitatiile_atribuite;
    public $zone;
    public $judete;
    public $tari;
    public static $targetAttribute = [];

    public function rules() {
        return [
            [['zone'], 'required'],
            [['licitatii_publice', 'licitatiile_atribuite', 'tari', 'judete'], 'safe'],
            ['licitatii_publice', 'validate_tip_licitatie', 'targetAttribute' => ['licitatii_publice', 'licitatiile_atribuite']],
        ];
    }

    function validate_tip_licitatie($attribute, $param) {
        print_r($attribute);
        $this->addError($attribute, 'eroarea');
    }

    public function attributeLabels() {
        return array(
            'licitatii_publice' => 'lp',
            'licitatiile_atribite' => 'la',
            'tari' => 'tari',
            'judete' => 'judete',
            'zone' => 'zone',
        );
    }

    public function save() {
        return false;
    }

}

?>

回答1:

Well what I have done in a case like this is to create the validator like this:

................
    return [
                [['zone'], 'required'],
                [['licitatii_publice', 'licitatiile_atribuite', 'tari', 'judete'], 'safe'],
                [['licitatii_publice, licitatiile_atribuite'], 'validate_tip_licitatie'],
            ];
............
    function validate_tip_licitatie($attribute, $param) {
        if(!$this->licitatii_publice && $this->licitatiile_atribuite)
        $this->addError($attribute, 'eroarea');
    }

In this way you show both fields with an error.

However I have done this in Yii1, but from what I read Yii2 should be the same. The logic is the same.

If you want to show error only for 1 attribute you can always just use

return [
            [['zone'], 'required'],
            [['licitatii_publice', 'licitatiile_atribuite', 'tari', 'judete'], 'safe'],
            [['licitatii_publice'], 'validate_tip_licitatie'],
        ];

What you are trying to do is more fancy :), I get that. If you really want to use targetAttribute you might have to do it like this https://github.com/yiisoft/yii2/blob/master/framework/validators/ExistValidator.php

Just build your own validator class.

Well. After reading about the exist validator i believe that is exactly what you need. It has examples on how to use it.



回答2:

Just wanted to update this answer for Yii2 case.
In Yii2 the validators have a skipOnEmpty attribute which is by default set to true. This implies custom validators will not be called if the field is empty, which might not be the required behavior, especially in this case where either of one attribute is mandatory. In order to fix this issue we need to set the skipOnEmpty to false as shown below.

[['licitatii_publice, licitatiile_atribuite'], 'validate_tip_licitatie', 'skipOnEmpty'=> false],


标签: php yii2