Getting an extra 'Invalid' or other error on your symfony form?
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).