mirror of
https://github.com/Respect/Validation.git
synced 2024-05-29 03:42:25 +02:00
Make getMessages() return the names or ids as keys
This method change the behavior of "getMessages()" by changin the keys of its return to the "id" of the specific exception that was triggered. It also allows users to overwrite the templates by passing an array to it. This is being requested by many users for a long time. It took that long because I was thinking too much about how to improve the old method called "findMesssage()" that I didn't realize that it could be done in a easier way with the "getMessages()". Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
parent
8c529c433e
commit
71ecea32e6
|
@ -167,10 +167,8 @@ The printed message is exactly this, as a nested Markdown list:
|
|||
|
||||
## Getting all messages as an array
|
||||
|
||||
The Markdown list is fine, but unusable on a HTML form or something more custom.
|
||||
For that you can use `getMessages()`.
|
||||
|
||||
It will return all messages from the rules that did not pass the validation.
|
||||
If you want to get all the messages as an array you can use `getMessages()` for
|
||||
that. The `getMessages()` method returns an array with all the messages.
|
||||
|
||||
```php
|
||||
try {
|
||||
|
@ -180,17 +178,56 @@ try {
|
|||
}
|
||||
```
|
||||
|
||||
The code above may display something like:
|
||||
The `getMessages()` returns an array in which the keys are the name of the
|
||||
validators, or its reference in case you are using [Key](Key.md) or
|
||||
[Attribute](Attribute.md) rule:
|
||||
|
||||
```no-highlight
|
||||
Array
|
||||
(
|
||||
[0] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
|
||||
[1] => "really messed up screen#name" must not contain whitespace
|
||||
[2] => "really messed up screen#name" must have a length between 1 and 15
|
||||
[alnum] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
|
||||
[noWhitespace] => "really messed up screen#name" must not contain whitespace
|
||||
[length] => "really messed up screen#name" must have a length between 1 and 15
|
||||
)
|
||||
```
|
||||
|
||||
## Custom messages
|
||||
|
||||
Getting messages as an array is fine, but sometimes you need to customize them
|
||||
in order to present them to the user. This is possible using the `getMessages()`
|
||||
method as well by passing the templates as an argument:
|
||||
|
||||
```php
|
||||
try {
|
||||
$usernameValidator->assert('really messed up screen#name');
|
||||
} catch(NestedValidationException $exception) {
|
||||
print_r(
|
||||
$exception->getMessages([
|
||||
'alnum' => '{{name}} must contain only letters and digits',
|
||||
'noWhitespace' => '{{name}} cannot contain spaces',
|
||||
'length' => '{{name}} must not have more than 15 chars',
|
||||
])
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
For all messages, the `{{name}}` variable is available for templates. If you do
|
||||
not define a name it uses the input to replace this placeholder.
|
||||
|
||||
The result of the code above will be:
|
||||
|
||||
```no-highlight
|
||||
Array
|
||||
(
|
||||
[alnum] => "really messed up screen#name" must contain only letters and digits
|
||||
[noWhitespace] => "really messed up screen#name" cannot contain spaces
|
||||
[length] => "really messed up screen#name" must not have more than 15 chars
|
||||
)
|
||||
```
|
||||
|
||||
Note that `getMessage()` will only return a message when the specific validation
|
||||
in the chain fails.
|
||||
|
||||
## Message localization
|
||||
|
||||
You're also able to translate your message to another language with Validation.
|
||||
|
|
|
@ -16,6 +16,8 @@ namespace Respect\Validation\Exceptions;
|
|||
use IteratorAggregate;
|
||||
use RecursiveIteratorIterator;
|
||||
use SplObjectStorage;
|
||||
use function count;
|
||||
use function is_array;
|
||||
|
||||
class NestedValidationException extends ValidationException implements IteratorAggregate
|
||||
{
|
||||
|
@ -119,18 +121,29 @@ class NestedValidationException extends ValidationException implements IteratorA
|
|||
return $childrenExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages()
|
||||
public function getMessages(array $templates = []): array
|
||||
{
|
||||
$messages = [$this->getMessage()];
|
||||
foreach ($this as $exception) {
|
||||
$messages[] = $exception->getMessage();
|
||||
$messages = [$this->getId() => $this->renderMessage($this, $templates)];
|
||||
foreach ($this->getRelated() as $exception) {
|
||||
$id = $exception->getId();
|
||||
if (!$exception instanceof self) {
|
||||
$messages[$id] = $this->renderMessage(
|
||||
$exception,
|
||||
$this->findTemplates($templates, $this->getId())
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
$messages[$id] = $exception->getMessages($this->findTemplates($templates, $id, $this->getId()));
|
||||
if (count($messages[$id]) > 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$messages[$id] = current($messages[$exception->getId()]);
|
||||
}
|
||||
|
||||
if (count($messages) > 1) {
|
||||
array_shift($messages);
|
||||
unset($messages[$this->getId()]);
|
||||
}
|
||||
|
||||
return $messages;
|
||||
|
@ -159,7 +172,7 @@ class NestedValidationException extends ValidationException implements IteratorA
|
|||
}
|
||||
|
||||
/**
|
||||
* @return SplObjectStorage
|
||||
* @return SplObjectStorage|ValidationException[]
|
||||
*/
|
||||
public function getRelated()
|
||||
{
|
||||
|
@ -170,25 +183,6 @@ class NestedValidationException extends ValidationException implements IteratorA
|
|||
return $this->exceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setParam($name, $value)
|
||||
{
|
||||
if ('translator' === $name) {
|
||||
foreach ($this->getRelated() as $exception) {
|
||||
$exception->setParam($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
parent::setParam($name, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $exceptions
|
||||
*
|
||||
|
@ -202,4 +196,25 @@ class NestedValidationException extends ValidationException implements IteratorA
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function renderMessage(ValidationException $exception, array $templates): string
|
||||
{
|
||||
if (isset($templates[$exception->getId()])) {
|
||||
$exception->updateTemplate($templates[$exception->getId()]);
|
||||
}
|
||||
|
||||
return $exception->getMessage();
|
||||
}
|
||||
|
||||
private function findTemplates(array $templates, ...$ids): array
|
||||
{
|
||||
while (count($ids) > 0) {
|
||||
$id = array_shift($ids);
|
||||
if (isset($templates[$id]) && is_array($templates[$id])) {
|
||||
$templates = $templates[$id];
|
||||
}
|
||||
}
|
||||
|
||||
return $templates;
|
||||
}
|
||||
}
|
||||
|
|
62
tests/integration/get_messages.phpt
Normal file
62
tests/integration/get_messages.phpt
Normal file
|
@ -0,0 +1,62 @@
|
|||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use Respect\Validation\Exceptions\NestedValidationException;
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
try {
|
||||
v::create()
|
||||
->key(
|
||||
'mysql',
|
||||
v::create()
|
||||
->key('host', v::stringType(), true)
|
||||
->key('user', v::stringType(), true)
|
||||
->key('password', v::stringType(), true)
|
||||
->key('schema', v::stringType(), true),
|
||||
true
|
||||
)
|
||||
->key(
|
||||
'postgresql',
|
||||
v::create()
|
||||
->key('host', v::stringType(), true)
|
||||
->key('user', v::stringType(), true)
|
||||
->key('password', v::stringType(), true)
|
||||
->key('schema', v::stringType(), true),
|
||||
true
|
||||
)
|
||||
->assert([
|
||||
'mysql' => [
|
||||
'host' => 42,
|
||||
'schema' => 42,
|
||||
],
|
||||
'postgresql' => [
|
||||
'user' => 42,
|
||||
'password' => 42,
|
||||
],
|
||||
]);
|
||||
} catch (NestedValidationException $exception) {
|
||||
print_r($exception->getMessages());
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
[mysql] => Array
|
||||
(
|
||||
[host] => host must be of type string
|
||||
[user] => Key user must be present
|
||||
[password] => Key password must be present
|
||||
[schema] => schema must be of type string
|
||||
)
|
||||
|
||||
[postgresql] => Array
|
||||
(
|
||||
[host] => Key host must be present
|
||||
[user] => user must be of type string
|
||||
[password] => password must be of type string
|
||||
[schema] => Key schema must be present
|
||||
)
|
||||
|
||||
)
|
|
@ -29,8 +29,8 @@ try {
|
|||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
[0] => username must have a length between 2 and 32
|
||||
[1] => birthdate must be a valid date/time
|
||||
[2] => password must not be empty
|
||||
[3] => Key email must be present
|
||||
[username] => username must have a length between 2 and 32
|
||||
[birthdate] => birthdate must be a valid date/time
|
||||
[password] => password must not be empty
|
||||
[email] => Key email must be present
|
||||
)
|
||||
|
|
70
tests/integration/get_messages_with_replacements.phpt
Normal file
70
tests/integration/get_messages_with_replacements.phpt
Normal file
|
@ -0,0 +1,70 @@
|
|||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use Respect\Validation\Exceptions\NestedValidationException;
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
try {
|
||||
v::create()
|
||||
->key(
|
||||
'mysql',
|
||||
v::create()
|
||||
->key('host', v::stringType(), true)
|
||||
->key('user', v::stringType(), true)
|
||||
->key('password', v::stringType(), true)
|
||||
->key('schema', v::stringType(), true),
|
||||
true
|
||||
)
|
||||
->key(
|
||||
'postgresql',
|
||||
v::create()
|
||||
->key('host', v::stringType(), true)
|
||||
->key('user', v::stringType(), true)
|
||||
->key('password', v::stringType(), true)
|
||||
->key('schema', v::stringType(), true),
|
||||
true
|
||||
)
|
||||
->assert([
|
||||
'mysql' => [
|
||||
'host' => 42,
|
||||
'schema' => 42,
|
||||
],
|
||||
'postgresql' => [
|
||||
'user' => 42,
|
||||
'password' => 42,
|
||||
],
|
||||
]);
|
||||
} catch (NestedValidationException $exception) {
|
||||
print_r($exception->getMessages([
|
||||
'mysql' => [
|
||||
'user' => 'Value should be a MySQL username',
|
||||
'host' => '{{input}} should be a MySQL host',
|
||||
],
|
||||
'postgresql' => [
|
||||
'schema' => 'You must provide a valid PostgreSQL schema',
|
||||
],
|
||||
]));
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
[mysql] => Array
|
||||
(
|
||||
[host] => 42 should be a MySQL host
|
||||
[user] => Value should be a MySQL username
|
||||
[password] => Key password must be present
|
||||
[schema] => schema must be of type string
|
||||
)
|
||||
|
||||
[postgresql] => Array
|
||||
(
|
||||
[host] => Key host must be present
|
||||
[user] => user must be of type string
|
||||
[password] => password must be of type string
|
||||
[schema] => You must provide a valid PostgreSQL schema
|
||||
)
|
||||
|
||||
)
|
|
@ -23,5 +23,5 @@ try {
|
|||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
[0] => name must have a length between 2 and 32
|
||||
[name] => name must have a length between 2 and 32
|
||||
)
|
||||
|
|
27
tests/integration/readme/custom_messages.phpt
Normal file
27
tests/integration/readme/custom_messages.phpt
Normal file
|
@ -0,0 +1,27 @@
|
|||
--FILE--
|
||||
<?php
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use Respect\Validation\Exceptions\NestedValidationException;
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
$usernameValidator = v::alnum()->noWhitespace()->length(1, 15);
|
||||
try {
|
||||
$usernameValidator->assert('really messed up screen#name');
|
||||
} catch (NestedValidationException $exception) {
|
||||
print_r(
|
||||
$exception->getMessages([
|
||||
'alnum' => '{{name}} must contain only letters and digits',
|
||||
'noWhitespace' => '{{name}} cannot contain spaces',
|
||||
'length' => '{{name}} must not have more than 15 chars',
|
||||
])
|
||||
);
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
[alnum] => "really messed up screen#name" must contain only letters and digits
|
||||
[noWhitespace] => "really messed up screen#name" cannot contain spaces
|
||||
[length] => "really messed up screen#name" must not have more than 15 chars
|
||||
)
|
|
@ -15,7 +15,7 @@ try {
|
|||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
[0] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
|
||||
[1] => "really messed up screen#name" must not contain whitespace
|
||||
[2] => "really messed up screen#name" must have a length between 1 and 15
|
||||
[alnum] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
|
||||
[noWhitespace] => "really messed up screen#name" must not contain whitespace
|
||||
[length] => "really messed up screen#name" must have a length between 1 and 15
|
||||
)
|
||||
|
|
21
tests/integration/readme/getting_messages_as_an_array.phpt
Normal file
21
tests/integration/readme/getting_messages_as_an_array.phpt
Normal file
|
@ -0,0 +1,21 @@
|
|||
--FILE--
|
||||
<?php
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use Respect\Validation\Exceptions\NestedValidationException;
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
$usernameValidator = v::alnum()->noWhitespace()->length(1, 15);
|
||||
try {
|
||||
$usernameValidator->assert('really messed up screen#name');
|
||||
} catch (NestedValidationException $exception) {
|
||||
print_r($exception->getMessages());
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
[alnum] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9)
|
||||
[noWhitespace] => "really messed up screen#name" must not contain whitespace
|
||||
[length] => "really messed up screen#name" must have a length between 1 and 15
|
||||
)
|
Loading…
Reference in a new issue