Yii - dynamically change rules from controller

后端 未结 5 842
太阳男子
太阳男子 2021-02-09 11:08

Let\'s say I have a product which can have a colour. Depending on the product type, the colour field may or may not be required.

If colour is always required, I would ha

相关标签:
5条回答
  • 2021-02-09 11:49
    class LoginForm extends CFormModel
    {
        public $username;
        public $password;
    }
    
    $form = new LoginForm();
    $form->validatorList->add(
        CValidator::createValidator('required', $form, 'username, password')
    );
    

    Now $form has two required fields.

    0 讨论(0)
  • 2021-02-09 11:55

    You can use scenario. In the model:

    class Model extends CActiveRecord {
        // ....
        public function rules() {
            return array(
                array('colour', 'required', 'on' => 'hasColour')
            );
        }
        // ....
    }
    

    And in the controller:

    public function actionOrder() {
        // ....
        $model = new Product();
        if ($product->HasColour) {
            $model->setScenario('hasColour');
        }
    }
    

    So, required colour will be validated when the model's scenario is hasColour

    0 讨论(0)
  • 2021-02-09 11:55

    One approach is to use a custom validation rule. For example, the rule:

    array('colour', 'requiredOnHasColour'),
    

    And then the validator method in the same model class:

    public function requiredOnHasColour($attribute, $params) {
        if ($this->hasColour && $this->$attribute == null)
            $this->addError($attribute, 'Colour is required.');
    }
    

    More info: Create your own validation rule

    0 讨论(0)
  • 2021-02-09 11:56

    In your ActiveRecord you can add in any place dynamic validator. For example i overwrite parent method setAttributes and add $this->validatorList->add() depends on selected value in $this->type attribute. Official docs: https://www.yiiframework.com/doc/api/1.1/CValidator

    public function setAttributes($values, $safeOnly = true)
    {
        $result = parent::setAttributes($values, $safeOnly);
    
        if (self::TYPE_PHONE == $this->type) {
            $this->validatorList->add(CValidator::createValidator('required', $this, ['phone', 'phonePrefix']));
        } elseif (self::TYPE_EMAIL == $this->type) {
            $this->validatorList->add(CValidator::createValidator('required', $this, ['email']));
        }
    
        return $result;
    }
    
    0 讨论(0)
  • 2021-02-09 11:58

    If you want to do more complicated logic, then scenarios might not satisfy your needs. Then you can override method init and do all the logic that define validation rules over there, adding results to $validationRules array. And the in rules() method you just return that array. Something like that:

     class Person extends CActiveRecord
    {
        public function init(){
            if( TRUE){
                $this->validationRules[] = array('first_name','required');
                $this->validationRules[] = array('last_name','required');
            }
    
        }
    
        public $validationRules = array(
            array('email', 'required'),
            array('email, email1, email2, email3', 'email', 'message'=>'Email format is invalid'),
            array('email, address, email1, email2, email3', 'length', 'max'=>255),
    
        );
    
        public function rules()
        {
            return $this->validationRules;
        }
    }
    
    0 讨论(0)
提交回复
热议问题