ZF-2224: Behavior of Zend_Validate_Abstract::setMessage() and Zend_Validate_EmailAddress doesn't work as expected
Description
In the following scenario, i want to check an email address for validity and show the user only a single message that the email address which was entered is invalid. (this validator was used in combination with Zend_Filter_Input where the 'messages' => '...' key in the array is ignored in that case)
$emailToCheck = 'foo@bar.com)'; // note the ')'
$emailValidator = new Zend_Validate_EmailAddress();
$emailValidator->setMessage('Please enter a valid email address.');
$valid = $emailValidator->isValid($emailToCheck);
var_dump($valid);
if (!$valid) {
var_dump($emailValidator->getMessages());
}
I didn't set any key for the messages so I expected that all error messages are set to my specific error message but when I looked at the implementation of Zend_Validate_Abstract::setMessage(), only the first message key gets that message:
public function setMessage($messageString, $messageKey = null)
{
if ($messageKey === null) {
$keys = array_keys($this->_messageTemplates);
$messageKey = current($keys);
}
[...]
}
So I would expect that I can set all messages to my defined error message but neither setMessage() nor setMessages() has this implemented.
The next problem is located in the Zend_Validate_EmailAddress validator, where the hostname validator passes all messages and errors to the to Zend_Validate_EmailAddress validator:
$hostnameResult = $this->hostnameValidator->isValid($this->_hostname);
if (!$hostnameResult) {
$this->_error(self::INVALID_HOSTNAME);
// Get messages and errors from hostnameValidator
foreach ($this->hostnameValidator->getMessages() as $message) {
$this->_messages[] = $message;
}
foreach ($this->hostnameValidator->getErrors() as $error) {
$this->_errors[] = $error;
}
}
There is no possibility to break the chain at any place to only get one single user defined error message when the hostname was invalid.
Comments
Posted by Darby Felton (darby) on 2008-01-29T09:28:00.000+0000
Each validation class can emit multiple messages, each of which corresponding to a cause for validation failure. A validation failure may indeed be caused by more than one reason, and this is why validation classes can emit multiple messages. There is no method in the public API to change all of the validation failure messages to a single message because this would obfuscate the reasons for validation failure. These reasons are not necessarily intended for display to users, however, and this is where the confusion seems to be.
Of course, you may only want to show a single, consolidated validation failure message to your end users, and this is a common and perfectly valid use case.
It should be simple to implement in at least one of the following ways:
Posted by Darby Felton (darby) on 2008-01-29T09:29:14.000+0000
Reducing priority to minor, since an easy workaround should be present.
Posted by Wil Sinclair (wil) on 2008-04-18T16:55:03.000+0000
Please evaluate and categorize/assign as necessary.
Posted by Andries Seutens (andries) on 2008-04-24T08:42:26.000+0000
The validation failure messages are not really meant for user consumption. However, I undestand that a lot of people are using them this way.
I suggest that we create 2 new methods:
Posted by Andries Seutens (andries) on 2008-04-24T08:44:42.000+0000
I would also like to note that it would be nice if created a special constant that overrides all error messages. This is particulary usefull for the email validator:
this would override all error messages in the stack.
Posted by Travis Pew (travisp) on 2009-02-27T11:57:20.000+0000
It seems strange to state that the validation failure messages are "not really meant for user consumption" given that Zend_Form by default renders these messages in the form when validation fails and that Zend_Validate automatically will use Zend_Translate if set in the registry to translate its messages for the user.
In particular, the inability to set a single error message breaks the ability to quickly and easily add a Text form element that uses the EmailAddress validator and have a single message such as "Invalid e-mail address" be provided by Zend_Translate. For example, if one sets all of the error messages to "Invalid e-mail address", "Invalid e-mail address" will appear 3 times when a user enters the email address "test@!".
The "easy" workaround for the developer is of course to extend Zend_Validate_EmailAddress (and every other validation class that can output multiple methods) to consolidate error messages after Zend_Validate_EmailAddress' isValid() function is called. However, it seems to be a very common use case to want to display a single simple error message to the user (and there have been a number of questions about this exact problem).
Posted by Thomas Weidner (thomas) on 2009-02-27T12:28:33.000+0000
When you want to display a single error from an failed validation use setError() on the form element. This has nothing to do with the bahaviour or the messages returned from the element itself and is only related to the form which is being displayed to the user.
Another way is to define the messages option on the form element which does the same.
Posted by Thomas Weidner (thomas) on 2009-04-25T09:51:05.000+0000
Closing issue as setErrorMessage does exactly what was described as problem in this issue.