How do I have multiple custom errors messages with Respect Validation.
I have some input that I want to validate against multiple validators. And I want a custom error message for each validation.
This is what I tried:
try {
Respect\Validation\Validator::create()
->key('foo',
v::length(20)->setName('bar')->setTemplate('Custom length message.')
->alnum()->setName('baz')->setTemplate('Custom alnum message.')
)
->assert([
'foo' => 'Hello, world!',
]);
} catch (Respect\Validation\Exceptions\ValidationException $exception) {
$errors = $exception->findMessages([
'bar',
'baz',
]);
var_dump($errors);
}
The output is:
array (size=2)
'bar' => string '' (length=0)
'baz' => string 'Custom alnum message.' (length=21)
I expected it to output both custom error messages.
Idealy I could get an array of messages for 1 input like:
var_dump($exception->findMessages(['foo']));
Would give me:
array (size=1)
'foo' =>
array (size=2)
0 => string 'Custom length message.' (length=22)
1 => string 'Custom alnum message.' (length=21)
This question seems like tumble weed.
You can not chain them together and get the custom message, because the last custom message you call will simply be assigned to the ruleset as opposed to he individual rules due to the implementation of the chaining.
To demonstrated this, I cloned it from git, created a bin directory, and modified your sample slightly with this test.php
<?php
set_include_path(implode(PATH_SEPARATOR, array(
realpath('../library')
)));
function __autoload($class_name) {
include $class_name . '.php';
}
use Respect\Validation\Validator as v;
try {
$chained = Respect\Validation\Validator::create()
->key('foo',
v::length(20)->setName('bar')->setTemplate('Custom length message.')
->alnum()->setName('baz')->setTemplate('Custom alnum message.')
);
print_r($chained);
$chained->assert(array(
'foo' => 'Hello, world!',
));
} catch (Respect\Validation\Exceptions\ValidationException $exception) {
$errors = $exception->findMessages(array(
'bar',
'baz',
));
var_dump($errors);
}
the print_r($chained) shows us:
Respect\Validation\Validator Object
(
[rules:protected] => Array
(
[00000000791c0e000000000030f3f15e] => Respect\Validation\Rules\Key Object
(
[mandatory] => 1
[reference] => foo
[validator] => Respect\Validation\Validator Object
(
[rules:protected] => Array
(
[00000000791c0e030000000030f3f15e] => Respect\Validation\Rules\Length Object
(
[minValue] => 20
[maxValue] =>
[inclusive] => 1
[name:protected] =>
[template:protected] =>
)
[00000000791c0e020000000030f3f15e] => Respect\Validation\Rules\Alnum Object
(
[additionalChars] =>
[stringFormat] => /^(\s|[a-zA-Z0-9])*$/
[name:protected] =>
[template:protected] =>
)
)
[name:protected] => baz
[template:protected] => Custom alnum message.
)
[name:protected] => foo
[template:protected] =>
)
)
[name:protected] =>
[template:protected] =>
)
You may notice that the ruleset pick up the last name and well as the last template passed in, and that neither of the actual validation objects got the Name or the Template. I don't see any way in the library to actually do what you are attempting to do.
So I decided to make a way. In my ../bin directory I created this class, extending the Valditor class.
<?php
use Respect\Validation\Validator as v;
class BubbaValidator extends v {
public function getRuleset($rulename = null){
if (is_null($rulename)) return $this->rules;
foreach ($this->rules as $rule){
if ($rule->getName() == $rulename){
return $rule;
}
}
}
public function getValidatorRules($rulesetName, $ruleType=null){
$ruleset = $this->getRuleset($rulesetName);
$validators = $ruleset->validator;
if (is_null($ruleType)){
return $validators;
}
foreach ($validators->rules as $key=>$validator){
if (get_class($validator) === 'Respect\Validation\Rules\\'.$ruleType){
$validator->name = "bar";
$validator->template = "bubba rocks";
$validators->rules[$key]->name = "bar";
$validators->rules[$key]->template = "bubba rocks";
return $validator;
}
}
}
public function setValidatorRuleName($rulesetName, $ruleType, $name){
$ruleset = $this->getRuleset($rulesetName);
$validators = $ruleset->validator;
foreach ($validators->rules as $key=>$validator){
if (get_class($validator) === 'Respect\Validation\Rules\\'.$ruleType){
$validators->rules[$key]->name = $name;
return $validator;
}
}
}
public function setValidatorRuleTemplate($rulesetName, $ruleType, $template){
$ruleset = $this->getRuleset($rulesetName);
$validators = $ruleset->validator;
foreach ($validators->rules as $key=>$validator){
if (get_class($validator) === 'Respect\Validation\Rules\\'.$ruleType){
$validators->rules[$key]->template = $template;
return $validator;
}
}
}
}
then I modifed the script and ran it
<?php
set_include_path(implode(PATH_SEPARATOR, array(
realpath('../library'),
realpath(__DIR__)
)));
function __autoload($class_name) {
include $class_name . '.php';
}
use BubbaValidator as v;
try {
$chained = new BubbaValidator();
$chained->key('foo',
v::length(20)->setName('bar')->setTemplate('Custom length message.')
->alnum()->setName('baz')->setTemplate('Custom alnum message.')
);
$chained->setValidatorRuleName('foo', 'Alnum', 'baz');
$chained->setValidatorRuleTemplate('foo', 'Alnum', 'Bubba\'s Custom Alnum!');
$chained->setValidatorRuleName('foo', 'Length', 'bar');
$chained->setValidatorRuleTemplate('foo', 'Length', 'Bubba\'s Custom Length!');
$chained->assert(array(
'foo' => 'Hello, world!',
));
} catch (Respect\Validation\Exceptions\ValidationException $exception) {
$errors = $exception->findMessages(array(
'bar',
'baz',
));
var_dump($errors);
}
to finally get this output:
D:\Users\Bubba\git\Validation\bin>php test.php
array(2) {
["bar"]=>
string(22) "Bubba's Custom Length!"
["baz"]=>
string(21) "Custom alnum message." }
That was fun!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With