3

I have a form element for capturing email addresses. I am using Zend_Validate_EmailAddress on the element, and it generates error messages that aren't very user-friendly.

My first step was to specify new messages that were more user-friendly, but some of the checks simply don't lend themselves to a user-friendly message. I then tried to simply clear those messages after running isValid() on the form and specify my own, but none of the functions I've found will clear the messages.

What I've tried and results

  1. setErrorMessages() - Values set here seem to be ignored altogether
  2. clearErrorMessages() - Seems to be ignored
  3. setErrors() - Adds my message, but leaves the others intact

This is the code that displays the errors in my custom view script:

<?php if ($this->element->hasErrors()): ?>
    <?php echo $this->formErrors($this->element->getMessages()); ?>
<?php endif; ?>

MY SOLUTION

I'm awarding Gordon with the answer, because his solution is most complete, but I ended up using the addErrorMessage() function on the element like this:

$element->addValidator('EmailAddress', false, $this->_validate['EmailAddress'])
        ->addErrorMessage("'%value%' is not a valid email address");

$element->addValidator('Date', false, array('MM/dd/yyyy'))
        ->addErrorMessage("Date must be in MM/DD/YYYY format");
Community
  • 1
  • 1
Sonny
  • 8,204
  • 7
  • 63
  • 134

3 Answers3

5

From the Reference Guide (emphasis mine):

Some developers may wish to provide custom error messages for a validator. The $options argument of the Zend_Form_Element::addValidator() method allows you to do so by providing the key 'messages' and mapping it to an array of key/value pairs for setting the message templates. You will need to know the error codes of the various validation error types for the particular validator.

So you can do:

$form = new Zend_Form;
$username = new Zend_Form_Element_Text('username');
$username->addValidator('regex', false, array(
    '/^[a-z]/i',
    'messages' => array(
        'regexInvalid'  => 'foo',
        'regexNotMatch' => 'bar',
        'regexErrorous' => 'baz'
    )
));
$form->addElement($username);
$form->isValid(array('username' => '!foo'));

which will then render 'bar' for the error message, because the regex does not match because it doesnt start with a letter from a-Z.

This is equivalent to using:

$username->setErrorMessages(
    array(
        'regexNotMatch' => 'The value %value% must start with a-Z',
        …
    )
);

I've used a different pattern to illustrate how to use the validated value in the pattern.

You can also use setErrors, if you want to delete any default templates, e.g.

$username->setErrors(array('The value must start with a-Z'));

Whatever you do, you have to configure that before validating with isValid. Once the validation is run, the Zend_Form_Element will contain the default error message otherwise. I am not aware of any way to reset that then (though someone might want to correct me on that).

Further quoting the reference guide:

A better option is to use a Zend_Translate_Adapter with your form. Error codes are automatically passed to the adapter by the default Errors decorator; you can then specify your own error message strings by setting up translations for the various error codes of your validators.

All the validation messages can be customized from the file in

The file should be in APPLICATION_PATH/resources/languages, but can really be placed anywhere as long as you tell Zend_Translate where to find it.

Gordon
  • 312,688
  • 75
  • 539
  • 559
1

When you define a form element like this

$titel = new Zend_Form_Element_Text ( "titel" );
$titel->setLabel ( "Titel" )->setRequired ( true )
      ->addValidator ( 'regex', false, array ("/[\pL\pN_\-]+/" ) );

you can specify a error message in your view script

<?php 
    $form = $this->form;
    $errorsMessages =$this->form->getMessages();
?>

<div>
    <label>Titel</label> <?php echo $form->titel->renderViewHelper()?>
    <?php 
           if(isset($errorsMessages['titel'])){
               echo "<p class='error'>There's something wrong!</p>";
           }
    ?>
</div>

I don't know if this conforms your way but I really like defining my forms this way ;)

DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601
1

One way you can attack it is to create your own custom validator by extending the validator you plan on using and overriding the messages. For instance, looking at Zend_Validate_Alnum, it looks like this:

class Zend_Validate_Alnum extends Zend_Validate_Abstract
{
    const INVALID      = 'alnumInvalid';
    const NOT_ALNUM    = 'notAlnum';
    const STRING_EMPTY = 'alnumStringEmpty';

    [ ... ]

    protected $_messageTemplates = array(
        self::INVALID      => "Invalid type given. String, integer or float expected",
        self::NOT_ALNUM    => "'%value%' contains characters which are non alphabetic and no digits",
        self::STRING_EMPTY => "'%value%' is an empty string",
    );

    [ ... ]
}

Override the $_messageTemplates array in your own class like this

class My_Validate_Alnum extends Zend_Validate_Alnum
{
    protected $_messageTemplates = array(
        self::INVALID      => "My invalid message",
        self::NOT_ALNUM    => "foo",
        self::STRING_EMPTY => "'%value%' is bar",
    );

    [ ... ]
}

Then instead of using Zend_Validate_Alnum, use My_Validate_Alnum as your validator. Custom validators are very simple to create.

ashurexm
  • 6,209
  • 3
  • 45
  • 69