Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 2a2165e

Browse files
committed
feat: set assert name parameter as optional and improved error messages
1 parent 0e29447 commit 2a2165e

33 files changed

+125
-117
lines changed

src/ChainedValidatorInterface.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ public function choice(
1212
bool $multiple = false,
1313
?int $minConstraint = null,
1414
?int $maxConstraint = null,
15-
string $message = 'The "{{ name }}" value is not a valid choice, "{{ value }}" given. Accepted values are: "{{ constraints }}".',
16-
string $multipleMessage = 'The "{{ name }}" value has one or more invalid choices, "{{ value }}" given. Accepted values are: "{{ constraints }}".',
17-
string $minMessage = 'The "{{ name }}" value must have at least {{ minConstraint }} choices, {{ numValues }} choices given.',
18-
string $maxMessage = 'The "{{ name }}" value must have at most {{ maxConstraint }} choices, {{ numValues }} choices given.'
15+
string $message = 'The {{ name }} value is not a valid choice, {{ value }} given. Accepted values are: {{ constraints }}.',
16+
string $multipleMessage = 'The {{ name }} value has one or more invalid choices, {{ value }} given. Accepted values are: {{ constraints }}.',
17+
string $minMessage = 'The {{ name }} value must have at least {{ minConstraint }} choices, {{ numValues }} choices given.',
18+
string $maxMessage = 'The {{ name }} value must have at most {{ maxConstraint }} choices, {{ numValues }} choices given.'
1919
): ChainedValidatorInterface&Validator;
2020

2121
public function country(
2222
string $code = 'alpha-2',
23-
string $message = 'The "{{ name }}" value is not a valid "{{ code }}" country code, "{{ value }}" given.'
23+
string $message = 'The {{ name }} value is not a valid {{ code }} country code, {{ value }} given.'
2424
): ChainedValidatorInterface&Validator;
2525

2626
public function eachKey(
@@ -30,38 +30,38 @@ public function eachKey(
3030

3131
public function eachValue(
3232
Validator $validator,
33-
string $message = 'At key "{{ key }}": {{ message }}'
33+
string $message = 'At key {{ key }}: {{ message }}'
3434
): ChainedValidatorInterface&Validator;
3535

3636
public function greaterThan(
3737
mixed $constraint,
38-
string $message = 'The "{{ name }}" value should be greater than "{{ constraint }}", "{{ value }}" given.'
38+
string $message = 'The {{ name }} value should be greater than {{ constraint }}, {{ value }} given.'
3939
): ChainedValidatorInterface&Validator;
4040

4141
public function greaterThanOrEqual(
4242
mixed $constraint,
43-
string $message = 'The "{{ name }}" value should be greater than or equal to "{{ constraint }}", "{{ value }}" given.'
43+
string $message = 'The {{ name }} value should be greater than or equal to {{ constraint }}, {{ value }} given.'
4444
): ChainedValidatorInterface&Validator;
4545

4646
public function lessThan(
4747
mixed $constraint,
48-
string $message = 'The "{{ name }}" value should be less than "{{ constraint }}", "{{ value }}" given.'
48+
string $message = 'The {{ name }} value should be less than {{ constraint }}, {{ value }} given.'
4949
): ChainedValidatorInterface&Validator;
5050

5151
public function lessThanOrEqual(
5252
mixed $constraint,
53-
string $message = 'The "{{ name }}" value should be less than or equal to "{{ constraint }}", "{{ value }}" given.'
53+
string $message = 'The {{ name }} value should be less than or equal to {{ constraint }}, {{ value }} given.'
5454
): ChainedValidatorInterface&Validator;
5555

5656
public function notBlank(
5757
?callable $normalizer = null,
58-
string $message = 'The "{{ name }}" value should not be blank, "{{ value }}" given.'
58+
string $message = 'The {{ name }} value should not be blank, {{ value }} given.'
5959
): ChainedValidatorInterface&Validator;
6060

6161
public function range(
6262
mixed $minConstraint,
6363
mixed $maxConstraint,
64-
string $message = 'The "{{ name }}" value should be between "{{ minConstraint }}" and "{{ maxConstraint }}", "{{ value }}" given.'
64+
string $message = 'The {{ name }} value should be between {{ minConstraint }} and {{ maxConstraint }}, {{ value }} given.'
6565
): ChainedValidatorInterface&Validator;
6666

6767
public function rule(
@@ -71,11 +71,11 @@ public function rule(
7171
public function timezone(
7272
int $timezoneGroup = \DateTimeZone::ALL,
7373
?string $countryCode = null,
74-
string $message = 'The "{{ name }}" value is not a valid timezone, "{{ value }}" given.'
74+
string $message = 'The {{ name }} value is not a valid timezone, {{ value }} given.'
7575
): ChainedValidatorInterface&Validator;
7676

7777
public function type(
7878
string|array $constraint,
79-
string $message = 'The "{{ name }}" value should be of type "{{ constraint }}", "{{ value }}" given.'
79+
string $message = 'The {{ name }} value should be of type {{ constraint }}, {{ value }} given.'
8080
): ChainedValidatorInterface&Validator;
8181
}

src/Exception/ValidationException.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,25 @@ class ValidationException extends \Exception
77
public function __construct(string $message, array $parameters = [])
88
{
99
$message = $this->formatMessage($message, $parameters);
10+
1011
parent::__construct($message);
1112
}
1213

1314
private function formatMessage(string $message, array $parameters = []): string
1415
{
16+
// If a name was not given, remove it from the message template but keep it intuitive
17+
if (empty($parameters['name'])) {
18+
$message = \str_replace(' {{ name }} ', ' ', $message);
19+
unset($parameters['name']);
20+
}
21+
1522
foreach ($parameters as $parameter => $value) {
16-
$message = str_replace("{{ $parameter }}", $this->formatValue($value), $message);
23+
// Format values (with some exceptions [name, message] to avoid adding unnecessary quotation marks)
24+
$message = \str_replace(
25+
\sprintf('{{ %s }}', $parameter),
26+
(\in_array($parameter, ['name', 'message'])) ? $value : $this->formatValue($value),
27+
$message
28+
);
1729
}
1830

1931
return $message;
@@ -39,7 +51,9 @@ private function formatValue(mixed $value): string
3951

4052
if (\is_string($value)) {
4153
// Replace line breaks and tabs with single space
42-
return str_replace(["\n", "\r", "\t", "\v", "\x00"], ' ', $value);
54+
$value = \str_replace(["\n", "\r", "\t", "\v", "\x00"], ' ', $value);
55+
56+
return \sprintf('"%s"', $value);
4357
}
4458

4559
if (\is_resource($value)) {

src/Rule/AbstractComparisonRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ abstract class AbstractComparisonRule extends AbstractRule
99
{
1010
use ComparableTrait;
1111

12-
public function assert(mixed $value, string $name): void
12+
public function assert(mixed $value, ?string $name = null): void
1313
{
1414
if (!$this->isComparable($value, $this->constraint)) {
1515
throw new UnexpectedComparableException(

src/Rule/AbstractRule.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ abstract class AbstractRule
99
public function validate($value): bool
1010
{
1111
try {
12-
$this->assert($value, 'null');
12+
$this->assert($value);
1313
}
1414
catch (ValidationException) {
1515
return false;
@@ -21,5 +21,5 @@ public function validate($value): bool
2121
/**
2222
* @throws ValidationException
2323
*/
24-
public abstract function assert(mixed $value, string $name): void;
24+
public abstract function assert(mixed $value, ?string $name = null): void;
2525
}

src/Rule/Choice.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ public function __construct(
1212
private readonly bool $multiple = false,
1313
private readonly ?int $minConstraint = null,
1414
private readonly ?int $maxConstraint = null,
15-
private readonly string $message = 'The "{{ name }}" value is not a valid choice, "{{ value }}" given. Accepted values are: "{{ constraints }}".',
16-
private readonly string $multipleMessage = 'The "{{ name }}" value has one or more invalid choices, "{{ value }}" given. Accepted values are: "{{ constraints }}".',
17-
private readonly string $minMessage = 'The "{{ name }}" value must have at least {{ minConstraint }} choices, {{ numValues }} choices given.',
18-
private readonly string $maxMessage = 'The "{{ name }}" value must have at most {{ maxConstraint }} choices, {{ numValues }} choices given.'
15+
private readonly string $message = 'The {{ name }} value is not a valid choice, {{ value }} given. Accepted values are: {{ constraints }}.',
16+
private readonly string $multipleMessage = 'The {{ name }} value has one or more invalid choices, {{ value }} given. Accepted values are: {{ constraints }}.',
17+
private readonly string $minMessage = 'The {{ name }} value must have at least {{ minConstraint }} choices, {{ numValues }} choices given.',
18+
private readonly string $maxMessage = 'The {{ name }} value must have at most {{ maxConstraint }} choices, {{ numValues }} choices given.'
1919
) {}
2020

21-
public function assert(mixed $value, string $name): void
21+
public function assert(mixed $value, ?string $name = null): void
2222
{
2323
if ($this->multiple && !\is_array($value)) {
2424
throw new UnexpectedValueException(

src/Rule/Country.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ class Country extends AbstractRule implements RuleInterface
1818

1919
public function __construct(
2020
private readonly string $code = self::ALPHA_2_CODE,
21-
private readonly string $message = 'The "{{ name }}" value is not a valid "{{ code }}" country code, "{{ value }}" given.'
21+
private readonly string $message = 'The {{ name }} value is not a valid {{ code }} country code, {{ value }} given.'
2222
) {}
2323

24-
public function assert(mixed $value, string $name): void
24+
public function assert(mixed $value, ?string $name = null): void
2525
{
2626
if (!\in_array($this->code, self::CODE_OPTIONS)) {
2727
throw new UnexpectedValueException(

src/Rule/EachKey.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public function __construct(
1414
private readonly string $message = 'Invalid key: {{ message }}'
1515
) {}
1616

17-
public function assert(mixed $value, string $name): void
17+
public function assert(mixed $value, ?string $name = null): void
1818
{
1919
if (!\is_iterable($value)) {
2020
throw new UnexpectedValueException(
@@ -35,12 +35,7 @@ public function assert(mixed $value, string $name): void
3535
'name' => $name,
3636
'key' => $key,
3737
'element' => $element,
38-
// Replaces string "value" with string "key" to get a more intuitive error message
39-
'message' => \preg_replace(
40-
\sprintf('/"(%s)" value/', $name),
41-
'"$1" key',
42-
$exception->getMessage()
43-
)
38+
'message' => \str_replace(' value ', ' key value ', $exception->getMessage())
4439
]
4540
);
4641
}

src/Rule/EachValue.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ class EachValue extends AbstractRule implements RuleInterface
1111
{
1212
public function __construct(
1313
private readonly Validator $validator,
14-
private readonly string $message = 'At key "{{ key }}": {{ message }}'
14+
private readonly string $message = 'At key {{ key }}: {{ message }}'
1515
) {}
1616

17-
public function assert(mixed $value, string $name): void
17+
public function assert(mixed $value, ?string $name = null): void
1818
{
1919
if (!\is_iterable($value)) {
2020
throw new UnexpectedValueException(

src/Rule/GreaterThan.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class GreaterThan extends AbstractComparisonRule implements RuleInterface
88
{
99
public function __construct(
1010
protected readonly mixed $constraint,
11-
protected readonly string $message = 'The "{{ name }}" value should be greater than "{{ constraint }}", "{{ value }}" given.'
11+
protected readonly string $message = 'The {{ name }} value should be greater than {{ constraint }}, {{ value }} given.'
1212
) {}
1313

1414
protected function compareValues(mixed $value1, mixed $value2): bool

src/Rule/GreaterThanOrEqual.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class GreaterThanOrEqual extends AbstractComparisonRule implements RuleInterface
88
{
99
public function __construct(
1010
protected readonly mixed $constraint,
11-
protected readonly string $message = 'The "{{ name }}" value should be greater than or equal to "{{ constraint }}", "{{ value }}" given.'
11+
protected readonly string $message = 'The {{ name }} value should be greater than or equal to {{ constraint }}, {{ value }} given.'
1212
) {}
1313

1414
protected function compareValues(mixed $value1, mixed $value2): bool

0 commit comments

Comments
 (0)