Favourite Onwuemene
Favourite Onwuemene

Reputation: 4377

yii CUniqueValidator specify compare attribute

I have a signup form that allows users to input either their email or phone number in a form field email_or_phone. I wrote a validation function which i used in the rules() function to ensure that the value submitted is either a valid email or phone number. The value is then assigned to the correct model attribute in the afterValidation() function.

My problem is, the model attributes email and phone are supposed to be unique. I wrote the afterValidation() function to test for uniqueness against the appropriate table column. But the code doesnt work. Below is my afterValidation() function:

protected function afterValidate(){
    parent::afterValidate();

    if(!$this->hasErrors() && $this->isNewRecord){

        $validator = new CEmailValidator;

        if($validator->validateValue($this->email_or_phone)){
            $validator = new CUniqueValidator;
            $validator->attributeName = 'email';
            $validator->validate($model, 'email_or_phone');
            if(!$this->hasErrors()) $this->email = $this->email_or_phone;
        }else{
            $validator = new CUniqueValidator;
            $validator->attributeName = 'phone';
            $validator->validate($model, 'email_or_phone');
            if(!$this->hasErrors()) $this->phone = $this->email_or_phone;
        }
    }
}

What am i doing wrong?

Upvotes: 1

Views: 900

Answers (1)

user133408
user133408

Reputation:

Just use CUniqueValidator for each email and phone, but configure 'allowEmpty' = true.

Also define setter for email and phone field where you check if it is phone or email and set it or leave it empty.

To get uniqueness error message on email_or_phone add to it messages from both email and phone. But to get it to work, a little trick is needed. You have to define your own validation rule as a separate class extending from CValidator, so you could call protected method from CUniqueValidator:

class MyValidator extends CValidator
{
protected function validateAttribute($object, $attribute)
{
    // Some validation:
    if(!isPhoneOrEmail($object->$attribute))
    {
        $this->addError($attribute, 'This is not phone or email');
    }
    // Now check phone and email
    $validator = new CuniqueValidator();
    $validator->allowEmpty = true;
    $validator->validateAttribute($object, 'phone');
    // Now get errors for phone attribute
    $errors = $object->getErrors('phone');
    if($errors)
    {
        foreach($errors as $error)
        {
            $this->addError($attribute, $error);
        }
    }

    // Same for email
}
}

Upvotes: 1

Related Questions