-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3d3e3e8
commit a4a0325
Showing
10 changed files
with
293 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,4 +56,5 @@ | |
|
||
## Other Rules | ||
|
||
- [AtLeastOneOf](03-rules_at-least-one-of.md) | ||
- [Optional](03-rules_optional.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# AtLeastOneOf | ||
|
||
Checks that the value satisfies at least one of the given constraints. | ||
|
||
```php | ||
/** Validator[] $constraints */ | ||
Choice( | ||
array $constraints, | ||
?string $message = null | ||
); | ||
``` | ||
|
||
## Basic Usage | ||
|
||
```php | ||
Validator::atLeastOneOf([ | ||
Validator::isFalse(), | ||
Validator::type('int')->greaterThanOrEqual(18) | ||
])->validate(false); // true | ||
|
||
Validator::atLeastOneOf([ | ||
Validator::isFalse(), | ||
Validator::type('int')->greaterThanOrEqual(18) | ||
])->validate(20); // true | ||
|
||
Validator::atLeastOneOf([ | ||
Validator::isFalse(), | ||
Validator::type('int')->greaterThanOrEqual(18) | ||
])->validate(true); // false | ||
|
||
Validator::atLeastOneOf([ | ||
Validator::isFalse(), | ||
Validator::type('int')->greaterThanOrEqual(18) | ||
])->validate(16); // false | ||
``` | ||
|
||
> [!NOTE] | ||
> An `UnexpectedValueException` will be thrown when a value in the `constraints` array is not an instance of `Validator`. | ||
## Options | ||
|
||
### `constraints` | ||
|
||
type: `array<int, Validator>` `required` | ||
|
||
Collection of constraints to be validated against the input value. | ||
If at least one given constraint is valid, the validation is considered successful. | ||
|
||
### `message` | ||
|
||
type: `?string` default: `The {{ name }} value should satisfy at least one of the following constraints: {{ messages }}` | ||
|
||
Message that will be shown if all given constraints are not valid. | ||
|
||
The following parameters are available: | ||
|
||
| Parameter | Description | | ||
|------------------|-------------------------------------------------| | ||
| `{{ value }}` | The current invalid value | | ||
| `{{ name }}` | Name of the invalid value | | ||
| `{{ messages }}` | List of error messages based on the constraints | | ||
|
||
## Changelog | ||
|
||
- `1.3.0` Created |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?php | ||
|
||
namespace ProgrammatorDev\Validator\Exception; | ||
|
||
class AtLeastOneOfException extends ValidationException {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
|
||
namespace ProgrammatorDev\Validator\Exception\Util; | ||
|
||
trait MessageTrait | ||
{ | ||
private function formatMessage(string $message, array $parameters = []): string | ||
{ | ||
// if a name was not given, remove it from the message template but keep it intuitive | ||
if (empty($parameters['name'])) { | ||
$message = \str_replace(' {{ name }} ', ' ', $message); | ||
unset($parameters['name']); | ||
} | ||
|
||
foreach ($parameters as $parameter => $value) { | ||
// format values (with some exceptions to avoid adding unnecessary quotation marks) | ||
$message = \str_replace( | ||
\sprintf('{{ %s }}', $parameter), | ||
(\in_array($parameter, ['name', 'message', 'messages'])) ? $value : $this->formatValue($value), | ||
$message | ||
); | ||
} | ||
|
||
return $message; | ||
} | ||
|
||
private function formatValue(mixed $value): string | ||
{ | ||
if ($value instanceof \DateTimeInterface) { | ||
return $value->format('Y-m-d H:i:s'); | ||
} | ||
|
||
if (\is_object($value)) { | ||
if ($value instanceof \Stringable) { | ||
return $value->__toString(); | ||
} | ||
|
||
return 'object'; | ||
} | ||
|
||
if (\is_array($value)) { | ||
return $this->formatValues($value); | ||
} | ||
|
||
if (\is_string($value)) { | ||
// replace line breaks and tabs with single space | ||
$value = \str_replace(["\n", "\r", "\t", "\v", "\x00"], ' ', $value); | ||
|
||
return \sprintf('"%s"', $value); | ||
} | ||
|
||
if (\is_resource($value)) { | ||
return 'resource'; | ||
} | ||
|
||
if ($value === null) { | ||
return 'null'; | ||
} | ||
|
||
if ($value === false) { | ||
return 'false'; | ||
} | ||
|
||
if ($value === true) { | ||
return 'true'; | ||
} | ||
|
||
return (string) $value; | ||
} | ||
|
||
private function formatValues(array $values): string | ||
{ | ||
foreach ($values as $key => $value) { | ||
$values[$key] = $this->formatValue($value); | ||
} | ||
|
||
return \sprintf('[%s]', \implode(', ', $values)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?php | ||
|
||
namespace ProgrammatorDev\Validator\Rule; | ||
|
||
use ProgrammatorDev\Validator\Exception\AtLeastOneOfException; | ||
use ProgrammatorDev\Validator\Exception\UnexpectedValueException; | ||
use ProgrammatorDev\Validator\Exception\ValidationException; | ||
use ProgrammatorDev\Validator\Validator; | ||
|
||
class AtLeastOneOf extends AbstractRule implements RuleInterface | ||
{ | ||
private string $message = 'The {{ name }} value should satisfy at least one of the following constraints: {{ messages }}'; | ||
|
||
/** @param Validator[] $constraints */ | ||
public function __construct( | ||
private readonly array $constraints, | ||
?string $message = null | ||
) | ||
{ | ||
$this->message = $message ?? $this->message; | ||
} | ||
|
||
public function assert(mixed $value, ?string $name = null): void | ||
{ | ||
try { | ||
Validator::eachValue( | ||
validator: Validator::type(Validator::class) | ||
)->assert($this->constraints); | ||
} | ||
catch (ValidationException $exception) { | ||
throw new UnexpectedValueException($exception->getMessage()); | ||
} | ||
|
||
$messages = []; | ||
|
||
foreach ($this->constraints as $key => $constraint) { | ||
try { | ||
$constraint->assert($value, $name); | ||
return; | ||
} | ||
catch (ValidationException|UnexpectedValueException $exception) { | ||
$messages[] = \sprintf('[%d] %s', ($key + 1), $exception->getMessage()); | ||
} | ||
} | ||
|
||
throw new AtLeastOneOfException( | ||
message: $this->message, | ||
parameters: [ | ||
'value' => $value, | ||
'name' => $name, | ||
'messages' => \implode(' ', $messages) | ||
] | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.