开发者

zend form email validation

I have the following code to generate an input field for user's email address

$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email:')
    ->addFilters(array('StringTrim', 'StripTags'))
    ->addValidator('EmailAddress')
    ->addValidator(new Zend_Validate_Db_NoRecordExists(
                                                        array(
                                                                'adapter'=>Zend_Registry::get('user_db'),
                                                                'field'=>'email',
                                                                'table'=>'tbl_user'
                                                                )))
    ->setRequired(true)
    ->setDecorators(array(
                            array('Label', array('escape'=>false, 'placement'=>'append')),
                            array('ViewHelper'),
                            array('Errors'),
                            array('Description',array('escape'=>false,'tag'=>'div')),
                            array('HtmlTag', array('tag' => 'div')),
                        ));
$this->addElement($email);

now the problem is if user enter invalid hostname for email, it generate 3 errors. lets say user enter 'admin@l' as email address, and the errors will be

* 'l' is no valid hostname for email address 'admin@l'

* 'l' does not match the expected structure for a DNS hostname

* 'l' appears to be a local network name but local network names are not allowe开发者_如何学Pythond

I just want it to give only one custom error instead of all these. If I set error message "Invalid Email Address" by addErrorMessage method, it will again generate the same message against the db_validation.


Well, it's a late answer but I think is always useful.

Simply add true as second param of addValidator()

From Zend docs (http://framework.zend.com/apidoc/1.8/):

addValidator (line 67)

Adds a validator to the end of the chain

If $breakChainOnFailure is true, then if the validator fails, the next validator in the chain, if one exists, will not be executed.

return: Provides a fluent interface

access: public

Here the signature:

Zend_Validate addValidator (Zend_Validate_Interface $validator, [boolean $breakChainOnFailure = false])

Zend_Validate_Interface $validator
boolean $breakChainOnFailure

So the code is:

$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email:')
    ->addFilters(array('StringTrim', 'StripTags'))
    ->addValidator('EmailAddress',  TRUE  ) // added true here
    ->addValidator(new Zend_Validate_Db_NoRecordExists(
                array(
                        'adapter'=>Zend_Registry::get('user_db'),
                        'field'=>'email',
                        'table'=>'tbl_user'
                        ), TRUE )
            );


You have to create an instance of the Zend_Validate_EmailAddress class and call the setMessages method and then override the messages that you like, to remove the ones that you mention it would be something like this:

$emailValidator->setMessages(array(
    Zend_Validate_EmailAddress::INVALID_FORMAT => "Your error message",
    Zend_Validate_Hostname::INVALID_HOSTNAME => "Your error message",
    Zend_Validate_Hostname::LOCAL_NAME_NOT_ALLOWED => "Your error message"
));

I hope this help somebody :-)


$email->addErrorMessage("Please Enter Valid Email Address");

you can use custom validator. create a file Email.php inside folder Validate in your library folder at the root of project

class Validate_Email extends Zend_Validate_Abstract
{

    const INVALID = 'Email is required';
    protected $_messageTemplates = array(
    self::INVALID => "Invalid Email Address",
    self::ALREADYUSED => "Email is already registered"
    );

     public function isValid($value)
     {
          if(preg_match($email_regex, trim($value))){
            $dataModel = new Application_Model_Data(); //check if the email exists
            if(!$dataModel->email_exists($value)){
                return true;
            }
            else{
                $this->_error(self::ALREADYUSED);
                return false;
            }
          }
          else
          {
            $this->_error(self::INVALID);
            return false;
          }
     }
}

and in you form.php file

    $mailValidator = new Validate_Email();
    $email->addValidator($mailValidator, true);

Don't know if it works or not but for me it worked in case of telephone. Courtesy of http://softwareobjects.net/technology/other/zend-framework-1-10-7-telephone-validator/


It seems to be missing quite a few lines...

probably should use this: $mailValidator = new Zend_Validate_EmailAddress();

you can also do some other validations see here: http://framework.zend.com/manual/en/zend.validate.set.html


Using a custom validator is the only way I found to avoid this problem.

If what you want is:

  • Having only one error message if the email address is in a wrong format
  • If the format is good, then validate if the email address is already in the database

Then I suggest you to do something like this:

$where = array('users', 'email', array('field' => 'user_id',
                                       'value' => $this->getAttrib('user_id')));
$email = new Zend_Form_Element_Text('email');
$email->setLabel('E-mail:')
      ->setRequired(true)
      ->setAttrib('required name', 'email') // html5
      ->setAttrib('maxlength', '50')
      ->addFilter('StripTags')
      ->addFilter('StringTrim')
      ->addFilter('StringToLower')
      ->addValidator('email', true)
      ->addValidator('stringLength', true, array(1, 50))
      ->addValidator('db_NoRecordExists', true, $where)
      ->addDecorators($this->_elementDecorators);
$this->addElement($email);

$this->getAttrib('user_id') represents the current user's id.

There are three validators here, all of them have their second parameter $breakOnFailureset to false, so if a validator fails, the other ones won't be called.

The first validator is email, which is my own custom validator:

class My_Validate_Email extends Zend_Validate_EmailAddress
{
    public function getMessages()
    {
        return array('invalidEmail' => 'Your email address is not valid.');
    }
}

You can add this validator in your library, in /application/library/My/Validate for example, and then add $this->addElementPrefixPath('My_Validate', 'My/Validate', 'validator'); into your form. Of course, you need to replace "My" by the name of your library.

Now if an email is in the wrong format, it will always display 'Your email address is not valid.'. If your email is too long and doesn't fit into your database field (VARCHAR(100) for example), it's going to show your stringLength validator errors, and in the last case, if an entry already exists in the database, only this error will be shown.

Of course you can add more methods into your custom validator and overload setMessages, so that you can display your own messages whatever the form you are working on.

Hope it can help someone!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜