-
Notifications
You must be signed in to change notification settings - Fork 775
Only create Length with subsequents when it's possible #1485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,39 +13,66 @@ | |
| use Countable as PhpCountable; | ||
| use Respect\Validation\Message\Template; | ||
| use Respect\Validation\Result; | ||
| use Respect\Validation\Rules\Core\Binder; | ||
| use Respect\Validation\Rules\Core\Wrapper; | ||
|
|
||
| use function array_map; | ||
| use function count; | ||
| use function is_array; | ||
| use function is_string; | ||
| use function mb_strlen; | ||
| use function ucfirst; | ||
|
|
||
| #[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] | ||
| #[Template('The length of', 'The length of')] | ||
| #[Template( | ||
| 'The length of', | ||
| 'The length of', | ||
| self::TEMPLATE_STANDARD | ||
| )] | ||
| #[Template( | ||
| '{{name}} must be a countable value or a string', | ||
| '{{name}} must not be a countable value or a string', | ||
| self::TEMPLATE_WRONG_TYPE | ||
| )] | ||
| final class Length extends Wrapper | ||
| { | ||
| public const TEMPLATE_WRONG_TYPE = '__wrong_type__'; | ||
|
|
||
| public function evaluate(mixed $input): Result | ||
| { | ||
| $typeResult = (new Binder($this, new OneOf(new StringType(), new Countable())))->evaluate($input); | ||
| if (!$typeResult->isValid) { | ||
| $result = $this->rule->evaluate($input); | ||
|
|
||
| return Result::failed($input, $this)->withSubsequent($result)->withId('length' . ucfirst($result->id)); | ||
| $length = $this->extractLength($input); | ||
| if ($length === null) { | ||
| return Result::failed($input, $this, [], self::TEMPLATE_WRONG_TYPE) | ||
| ->withId('length' . ucfirst($this->rule->evaluate($input)->id)); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just a way to get the |
||
| } | ||
|
|
||
| $result = $this->rule->evaluate($this->extractLength($input))->withInput($input)->withPrefixedId('length'); | ||
| return $this->enrichResult($input, $this->rule->evaluate($length)); | ||
| } | ||
|
|
||
| private function enrichResult(mixed $input, Result $result): Result | ||
| { | ||
| if (!$result->allowsSubsequent()) { | ||
| return $result | ||
| ->withInput($input) | ||
| ->withChildren( | ||
| ...array_map(fn(Result $child) => $this->enrichResult($input, $child), $result->children) | ||
| ); | ||
| } | ||
|
|
||
| return (new Result($result->isValid, $input, $this, id: $result->id))->withSubsequent($result); | ||
| return (new Result($result->isValid, $input, $this, id: $result->id)) | ||
| ->withPrefixedId('length') | ||
| ->withSubsequent($result->withInput($input)); | ||
| } | ||
|
|
||
| /** @param array<mixed>|PhpCountable|string $input */ | ||
| private function extractLength(array|PhpCountable|string $input): int | ||
| private function extractLength(mixed $input): ?int | ||
| { | ||
| if (is_string($input)) { | ||
| return (int) mb_strlen($input); | ||
| } | ||
|
|
||
| return count($input); | ||
| if ($input instanceof PhpCountable || is_array($input)) { | ||
| return count($input); | ||
| } | ||
|
|
||
| return null; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,3 +41,18 @@ | |
| '- The length of Cactus must be equal to 3', | ||
| ['lengthEquals' => 'The length of Cactus must be equal to 3'] | ||
| )); | ||
|
|
||
| test('Chained wrapped rule', expectAll( | ||
| fn() => v::length(v::between(5, 7)->odd())->assert([]), | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is pretty much the essence of the changes. If you see the other tests, When
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dmjohnsson23 I wrote some comments to this merge request. If you have any questions, you can just write here, I'll be happy to answer them! |
||
| 'The length of `[]` must be between 5 and 7', | ||
| <<<'FULL_MESSAGE' | ||
| - All of the required rules must pass for `[]` | ||
| - The length of `[]` must be between 5 and 7 | ||
| - The length of `[]` must be an odd number | ||
| FULL_MESSAGE, | ||
| [ | ||
| '__root__' => 'All of the required rules must pass for `[]`', | ||
| 'lengthBetween' => 'The length of `[]` must be between 5 and 7', | ||
| 'lengthOdd' => 'The length of `[]` must be an odd number', | ||
| ] | ||
| )); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,20 +16,20 @@ function (): void { | |
| ValidatorDefaults::setTranslator(new ArrayTranslator([ | ||
| 'All of the required rules must pass for {{name}}' => 'Todas as regras requeridas devem passar para {{name}}', | ||
| 'The length of' => 'O comprimento de', | ||
| '{{name}} must be of type string' => '{{name}} deve ser do tipo string', | ||
| '{{name}} must be a string' => '{{name}} deve ser uma string', | ||
| '{{name}} must be between {{minValue}} and {{maxValue}}' => '{{name}} deve possuir de {{minValue}} a {{maxValue}} caracteres', | ||
| '{{name}} must be a valid telephone number for country {{countryName|trans}}' | ||
| => '{{name}} deve ser um número de telefone válido para o país {{countryName|trans}}', | ||
| 'United States' => 'Estados Unidos', | ||
| ])); | ||
|
|
||
| Validator::stringType()->lengthBetween(2, 15)->phone('US')->assert(0); | ||
| Validator::stringType()->lengthBetween(2, 15)->phone('US')->assert([]); | ||
| }, | ||
| <<<'FULL_MESSAGE' | ||
| - Todas as regras requeridas devem passar para 0 | ||
| - 0 must be a string | ||
| - O comprimento de 0 deve possuir de 2 a 15 caracteres | ||
| - 0 deve ser um número de telefone válido para o país Estados Unidos | ||
| - Todas as regras requeridas devem passar para `[]` | ||
| - `[]` deve ser uma string | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed this just because it was wrong, but it doesn't have anything to do with the changes. |
||
| - O comprimento de `[]` deve possuir de 2 a 15 caracteres | ||
| - `[]` deve ser um número de telefone válido para o país Estados Unidos | ||
| FULL_MESSAGE, | ||
| )); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this is a new template, I had to add it to the documentation.