In a form, I have the following element:
$email = new Zend_Form_Element_Text('username');
$email
->setLabel($this->getView()->l('E-mail'))
->setRequired(TRUE)
->addValidator('EmailAddress')
->addValidator('Db_NoRecordExists', true,
array(
'table' => 'pf_user',
'field' => 'email',
'messages' => array(
'recordFound' => 'This username is already registered',
)
))
->setErrorMessages(array(
'emailAddressInvalidFormat' => 'You must enter a valid e-mail',
'isEmpty' => 'You must enter an e-mail',
'recordFound' => 'This e-mail has already registered in out database'
));
$form->addElement($email)
the problem is that I always I get the same message "You must enter a valid e-mail" (the first one). Does anybody knows what is the mistake??
Actually, what you're doing is the following :
You set the errors on the element
Zend now thinks that the element did not validate correctly and that the first error is
"You must enter a valid e-mail"
When you display the form, since you set errors, Zend will find them and display the first one it finds. If you switch the order then you'll find that whichever error you put up top will be the error you get.
The more correct way is to set the custom messages in the validator. When the validators are called to validate the element, if the validation fails, the validator will call the setErrorMessages on the element to set the custom errors you specify. Use this type of code below to set your custom messages.
$element->addValidator( array( 'Db_NoRecordExists', true, array(
'messages' = array(
Zend_Validate_Db_Abstract::ERROR_NO_RECORD_FOUND => 'Myy custom no error record',
Zend_Validate_Db_Abstract::ERROR_RECORD_FOUND => 'My custom record error'
)
) ) );
You'll find that usually there are consts in each validator class that specify one type of error. In this case, the consts are in the parent class of the DB_NoRecordExists class but usually you'll find them directly in the class near the top.
Basically by passing 'true' as second parameter to addValidator() you are saying the validator to break the chain whenever validator fails . Since "" is not an valid email address hence the first email validator fails and breaks the chain
From Zend Doc http://framework.zend.com/manual/en/zend.validate.validator_chains.html
In some cases it makes sense to have a validator break the chain if
its validation process fails. Zend_Validate supports such use cases
with the second parameter to the addValidator() method. By setting
$breakChainOnFailure to TRUE, the added validator will break the chain
execution upon failure, which avoids running any other validations
that are determined to be unnecessary or inappropriate for the
situation. If the above example were written as follows, then the
alphanumeric validation would not occur if the string length
validation fails:
$validatorChain->addValidator(
new Zend_Validate_StringLength(array('min' => 6,
'max' => 12)),
true)
->addValidator(new Zend_Validate_Alnum());
Related
I'm having some issues with the Codeigniter 4 validation rules. I'm using the is_unique function within the ruleset in Order to except one single row from the validation.
The problem here is that there are two fields in the table that need to be checked:
'episodeTitle' => [
'label' => 'episodeTitle',
'rules' => 'required|max_length[100]|is_unique[episodes.episodeTitle,episodes.episodeID,' . $episodeID . ',episodes.podcastID,' . $podcastID . ']',
'errors' => [
'required' => lang('Errors.nested.episode.episodeTitleRequired'),
'max_length' => lang('Errors.nested.messages.maxLength100'),
'is_unique' => lang('Errors.nested.episode.episodeTitleUnique'),
],
],
Is it possible, to make the exception depending on 2 or more fields?
I want to check the episodeID AND the podcastID not only one of these values.
You need to create a custom rule to achieve what you're looking for.
Rules are stored within simple, namespaced classes. They can be stored any location you would like, as long as the autoloader can find it. These files are called RuleSets. To add a new RuleSet, edit Config/Validation.php and add the new file to the $ruleSets array:
public $ruleSets = [
\CodeIgniter\Validation\Rules::class,
\CodeIgniter\Validation\FileRules::class,
\CodeIgniter\Validation\CreditCardRules::class,
];
Within the file itself, each method is a rule and must accept a string as the first parameter, and must return a boolean true or false value signifying true if it passed the test or false if it did not:
class MyRules
{
public function check_unique(string $str): bool
{
// Your code to check the values and don't forget to return true or false.
}
}
Then in your validation just use the check_unique rule.
I need to add multiple custom error messages like this and both needs to be displayed as validations messages. I have the following code :
if (!$condition1) {
$error[] = "Condition 1 needs to be satisfied";
$validation = false;
}
if (!$condition2) {
$error[] = "Condition 2 needs to be satisfied";
$validation = false;
}
$validator->setCustomMessages($error);
But here I am getting only one message that is the first one even if it is entering to second condition. I have tried to add $validator->setCustomMessages("Message"); in each of the conditions, but it is also doing the same thing.
Why are you using conditionals for validation?
This is what I use to handle validation for uploading photos in my controller.
You have a custom error message for 'required' and one for 'size' (which refers to the size of the photos array).
To add another custom message, just pipe on another rule and its corresponding error message using dot notation.
Only after all rules are satisfied then the code continues execution.
$this->validate($request,
[
'photos' => 'required|size:4'
],
[
'photos.required' => 'Photos are Required',
'photos.size' => 'You must upload 4 Photos'
]
);
Try to change $validator->setCustomMessages($error); for $validator->getMessageBag()->merge($error);
Now if you do $validator->errors()->getMessages() you must have your array with both errors
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
setErrorMessages() - Values set here seem to be ignored altogether
clearErrorMessages() - Seems to be ignored
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");
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
http://framework.zend.com/svn/framework/standard/trunk/resources/languages/en
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.
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 ;)
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.
Currently, isEmpty errors throw:
Value is required and can't be empty
I'm loading my translator up like this:
[translation]
adapter = array
content.english["emailNotUnique"] = "Your user already exists"
content.english["Value is required and can't be empty"] = "You must specify your ID"
locale = en
The config above produces a valid array according to zend translate spec, so:
$this -> form -> setTranslator(new Zend_Translate($this -> getConfig() -> translation));
expected result is that isEmpty errors should now show up as
You must specify your ID
However I'm getting no love. No errors and no translation. I'm on Zend 1.11.1 and PHP5.3.5.
I think that the problem is with english key in your ini file. Specifically it should not be there, because what you are actually passing to Zend_Translate as a content is:
'content' => array(
'english' => array(
"emailNotUnique" => 'Your user already exists' ,
"Value is required and can't be empty" => 'You must specify your ID'
)
);
And it should be:
'content' => array(
"emailNotUnique" => 'Your user already exists' ,
"Value is required and can't be empty" => 'You must specify your ID'
);
Hope this will help.
Try to change
content.english["isEmpty"] = "You must specify your ID"
you can user language file(MO) its simple translate in multiple language
when initialize bootstrap at a time initialize selected language
Say I create a text element like this:
$firstName = new Zend_Form_Element_Text('firstName');
$firstName->setRequired(true);
Whats the best way to change the default error message from:
Value is empty, but a non-empty value
is required
to a custom message? I read somewhere that to replace the message, just use addValidator(..., instead (NO setRequired), like this:
$firstName = new Zend_Form_Element_Text('firstName');
$firstName->addValidator('NotEmpty', false, array('messages'=>'Cannot be empty'));
but in my testing, this doesn't work - it doesn't validate at all - it will pass with an empty text field. Using both (addValidator('NotEmp.. + setRequired(true)) at the same time doesn't work either - it double validates, giving two error messages.
Any ideas?
Thanks!
An easier way to set this "site-wide" would be to possibly do the following in a bootstrap or maybe a base zend_controller:
<?php
$translateValidators = array(
Zend_Validate_NotEmpty::IS_EMPTY => 'Value must be entered',
Zend_Validate_Regex::NOT_MATCH => 'Invalid value entered',
Zend_Validate_StringLength::TOO_SHORT => 'Value cannot be less than %min% characters',
Zend_Validate_StringLength::TOO_LONG => 'Value cannot be longer than %max% characters',
Zend_Validate_EmailAddress::INVALID => 'Invalid e-mail address'
);
$translator = new Zend_Translate('array', $translateValidators);
Zend_Validate_Abstract::setDefaultTranslator($translator);
?>
Give this a shot:
$firstName = new Zend_Form_Element_Text('firstName');
$firstName->setLabel('First Name')
->setRequired(true)
->addValidator('NotEmpty', true)
->addErrorMessage('Value is empty, but a non-empty value is required.');
The key is that "true" on the validator if you set that to true, it'll kill the other validations after it. If you add more than one validation method, but set that to false, it will validate all methods.
Zend_Form sets the required validation error as 'isEmpty', so you can override its message using setErrorMessages(). For example:
//Your Required Element
$element->setRequired(true)->setErrorMessages(array(
'isEmpty'=>'Please fill this field'
));
It worked for me, using ZF 1.11
Try
->addValidator('Digits', false);
or
->addValidator('Digits');
You assume that to check Digits it has to have a string length anyway.
Also, I like to do some custom error messages like this:
$firstName->getValidator('NotEmpty')->setMessage('Please enter your first name');
This allows you to "get" the validator and then "set" properties of it.
Try the following.
$subjectElement->setRequired(true)->addErrorMessage('Please enter a subject for your message');
This worked form me.
But try this:
$firstName->setRequired(true)
->addValidator('NotEmpty', false, array('messages' => 'bar'))
->addValidator('Alpha', false, array('messages'=>'Must contain only letters'));
If left empty and submitted, itll give two messages bar & '' is an empty string. Its that second message thats coming from setRequired(true) thats the problem
if you put:
$element->setRequired(false);
the validations don't work at all, you have to define:
$element->setAllowEmpty(false);
in order to get the correct behavior of the validations.
Try this..
$ausPostcode = new Zend_Form_Element_Text('aus_postcode'); $ausPostcode->setLabel('Australian Postcode')
->setRequired(true)
->addValidator('StringLength', false, array(4, 4))
->addValidator(new Zend_Validate_Digits(), false)
->getValidator('digits')->setMessage('Postcode can only contain digits');
This sets the custom error message only for the Digits validator.
One small issue. This code:
$zipCode->setLabel('Postal Code')
->addValidator('StringLength', true, array( 5, 5 ) )
->addErrorMessage('More than 5')
->addValidator('Digits', true)
->addErrorMessage('Not a digit');
Will generate both error messages if either validation fails. Isn't is supposed to stop after the first fails?
use a zend translator with zend_validate.php from
ZendFramework-1.11.3\resources\languages\en\Zend_Validate.php and then modify this file how you need
and then modify it accordingly to your needs