On a project I’m working on I came across the following problem: we had a email field that we needed to be unique in our system, but we also made sure that it matched a confirm email field. A snippet of our form looks like this:
<?php
public function configure()
{
$this->setWidgets( array(
'email' => new sfWidgetFormInputText()
'confirm_email' => new sfWidgetFormInputText()
));
$this->setValidators(array(
'email'=> new sfValidatorAnd(
array(
new sfValidatorEmail( array('required' => true) ),
new sfValidatorDoctrineUnique(
array('throw_global_error' => true, 'model' => 'sfGuardUser', 'column' => 'username'),
array('invalid' => 'Sorry! A user with that email address already exists.')
)
)),
'confirm_email' => new sfValidatorEmail( array('required' => true) )
));
$this->validatorSchema->setPostValidator(
new sfValidatorSchemaCompare('password', '==', 'confirm_password')
);
}
When we submitted an email that was already in the system we got back two errors:
- Sorry! A user with that email address already exists.
- Invalid.
For a while I thought is there some extra validator somewhere that I left on? Where is this invalid coming from? It ended up being due to the way the validators work. If a validator throws an error it doesn’t return that validator’s value. So by the time it gets to the sfValidatorSchemaCompare post validator the value of email is null and confirm_email has the value you input, thus the seemingly extra ‘Invalid’ message.
This can be fixed easily with a sfValidatorCallback instead of the sfValidatorSchemaCompare. Here is the fix:
<?php
public function validateConfirmEmail( $validator, $values ){
if($values['email']&&$values['email']!=$values['confirm_email'])
{
throw new sfValidatorError($validator, 'Please confirm your email, currently they do not match!.');
}
return $values;
}
This way if the email is blank it doesn’t both making sure that the email matches the confirm_email. You don’t need to worry about a person just passing two blank emails as the earlier validator(the sfValidatorEmail requires it to be there and valid).
If you are getting an extra validation error, check your postValidators and how the values get to them.