Yii form model validation- either one is required

后端 未结 8 981
时光取名叫无心
时光取名叫无心 2020-12-11 15:27

I have two fields on the form ( forgotpassword form ) username and email Id . User should enter one of them . I mean to retrieve the password user can enter user name or th

相关标签:
8条回答
  • 2020-12-11 16:06

    I don't think there is a predefined rule that would work in that case, but it would be easy enough to define your own where for username and password fields the rule was "if empty($username . $password) { return error }" - you might want to check for a min length or other field-level requirements as well.

    0 讨论(0)
  • 2020-12-11 16:07

    I was trying to solve same problem today. What I've got is the code below.

    public function rules()
    {
        return array(
            // array('username, email', 'required'), // Remove these fields from required!!
            array('email', 'email'),
            array('username, email', 'my_equired'), // do it below any validation of username and email field
        );
    }
    
    public function my_required($attribute_name, $params)
    {
        if (empty($this->username)
                && empty($this->email)
        ) {
            $this->addError($attribute_name, Yii::t('user', 'At least 1 of the field must be filled up properly'));
    
            return false;
        }
    
        return true;
    }
    

    General idea is to move 'required' validation to custom my_required() method which can check if any of field is filled up.

    I see this post is from 2011 however I couldn't find any other solution for it. I Hope it will work for you or other in the future.

    Enjoy.

    0 讨论(0)
  • 2020-12-11 16:07

    don't forget "skipOnEmpty" attr. It cost me some hours.

     protected function customRules()
    {
        return [
                  [['name', 'surname', 'phone'], 'compositeRequired', 'skipOnEmpty' => false,],
        ];
    }
    
    public function compositeRequired($attribute_name, $params)
    {
        if (empty($this->name)
            && empty($this->surname)
            && empty($this->phone)
        ) {
            $this->addError($attribute_name, Yii::t('error', 'At least 1 of the field must be filled up properly'));
    
            return false;
        }
    
        return true;
    }
    
    0 讨论(0)
  • 2020-12-11 16:13

    You can use private property inside model class for preventing displays errors two times (do not assign error to model's attribute, but only add to model without specifying it):

    class CustomModel extends CFormModel
    {
        public $username;
        public $email;
    
        private $_addOtherOneOfTwoValidationError = true;
    
        public function rules()
        {
            return array(
                array('username, email', 'requiredOneOfTwo'),
            );
        }
    
        public function requiredOneOfTwo($attribute, $params)
        {
            if(empty($this->username) && empty($this->email))
            {
                // if error is not already added to model, add it!
                if($this->_addOtherOneOfTwoValidationError)
                {
                    $this->addErrors(array('Please enter your username or emailId.'));
    
                    // after first error adding, make error addition impossible
                    $this->_addOtherOneOfTwoValidationError = false;
                }
    
                return false;
            }
    
            return true;
        }
    }
    
    0 讨论(0)
  • 2020-12-11 16:14

    Yii 1

    It can be optimized of course but may help someone

    class OneOfThemRequiredValidator extends \CValidator
    {
        public function validateAttribute($object, $attribute)
        {
            $all_empty = true;
            foreach($this->attributes as $_attribute) {
                if (!$this->isEmpty($object->{$_attribute})) {
                    $all_empty = false;
                    break;
                }
            }
    
            if ($all_empty) {
                $message = "Either of the following attributes are required: ";
                $attributes_labels = array_map(function($a) use ($object) {
                        return $object->getAttributeLabel($a);
                    }, $this->attributes);
                $this->addError($object, $_attribute, $message . implode(',', 
                $attributes_labels));
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-11 16:19

    This works for me:

                ['clientGroupId', 'required', 'when' => function($model) {
                    return empty($model->clientId);
                }, 'message' => 'Client group or client selection is required'],
    
    0 讨论(0)
提交回复
热议问题