Skip to content

Commit

Permalink
Replace "KeyValue" with "LazyConsecutive" rule
Browse files Browse the repository at this point in the history
I want to avoid having the Factory inside the rules. If a rule needs to
create another, it can simply instantiate that. The "KeyValue" rule does
too many things under the hood, and the behavior can be unpredictable.

The "LazyConsecutive" rule makes the validation more explicit and way
more flexible, as there could be other cases in which someone only wants
to validate something if the previous validator passes.

Signed-off-by: Henrique Moody <[email protected]>
  • Loading branch information
henriquemoody committed Feb 22, 2024
1 parent 7947399 commit 41245f6
Show file tree
Hide file tree
Showing 22 changed files with 262 additions and 352 deletions.
7 changes: 4 additions & 3 deletions docs/08-list-of-rules-by-category.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
- [Key](rules/Key.md)
- [KeyNested](rules/KeyNested.md)
- [KeySet](rules/KeySet.md)
- [KeyValue](rules/KeyValue.md)
- [Sorted](rules/Sorted.md)
- [StartsWith](rules/StartsWith.md)
- [Subset](rules/Subset.md)
Expand All @@ -39,6 +38,7 @@
- [Call](rules/Call.md)
- [CallableType](rules/CallableType.md)
- [Callback](rules/Callback.md)
- [LazyConsecutive](rules/LazyConsecutive.md)

## Comparisons

Expand All @@ -56,6 +56,7 @@

- [AllOf](rules/AllOf.md)
- [AnyOf](rules/AnyOf.md)
- [LazyConsecutive](rules/LazyConsecutive.md)
- [NoneOf](rules/NoneOf.md)
- [OneOf](rules/OneOf.md)

Expand Down Expand Up @@ -160,7 +161,7 @@
- [Key](rules/Key.md)
- [KeyNested](rules/KeyNested.md)
- [KeySet](rules/KeySet.md)
- [KeyValue](rules/KeyValue.md)
- [LazyConsecutive](rules/LazyConsecutive.md)
- [NoneOf](rules/NoneOf.md)
- [Not](rules/Not.md)
- [Nullable](rules/Nullable.md)
Expand Down Expand Up @@ -338,8 +339,8 @@
- [Key](rules/Key.md)
- [KeyNested](rules/KeyNested.md)
- [KeySet](rules/KeySet.md)
- [KeyValue](rules/KeyValue.md)
- [LanguageCode](rules/LanguageCode.md)
- [LazyConsecutive](rules/LazyConsecutive.md)
- [LeapDate](rules/LeapDate.md)
- [LeapYear](rules/LeapYear.md)
- [Length](rules/Length.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/AllOf.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Version | Description
See also:

- [AnyOf](AnyOf.md)
- [LazyConsecutive](LazyConsecutive.md)
- [NoneOf](NoneOf.md)
- [OneOf](OneOf.md)
- [When](When.md)
1 change: 1 addition & 0 deletions docs/rules/AnyOf.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ See also:

- [AllOf](AllOf.md)
- [ContainsAny](ContainsAny.md)
- [LazyConsecutive](LazyConsecutive.md)
- [NoneOf](NoneOf.md)
- [OneOf](OneOf.md)
- [When](When.md)
1 change: 0 additions & 1 deletion docs/rules/ArrayVal.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ See also:
- [IterableType](IterableType.md)
- [Key](Key.md)
- [KeySet](KeySet.md)
- [KeyValue](KeyValue.md)
- [ScalarVal](ScalarVal.md)
- [Sorted](Sorted.md)
- [Subset](Subset.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/Call.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ See also:

- [Callback](Callback.md)
- [Each](Each.md)
- [LazyConsecutive](LazyConsecutive.md)
- [Sorted](Sorted.md)
2 changes: 1 addition & 1 deletion docs/rules/Equals.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ See also:
- [Contains](Contains.md)
- [Equivalent](Equivalent.md)
- [Identical](Identical.md)
- [KeyValue](KeyValue.md)
- [LazyConsecutive](LazyConsecutive.md)
- [Version](Version.md)
1 change: 0 additions & 1 deletion docs/rules/Key.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,4 @@ See also:
- [Each](Each.md)
- [KeyNested](KeyNested.md)
- [KeySet](KeySet.md)
- [KeyValue](KeyValue.md)
- [Property](Property.md)
1 change: 0 additions & 1 deletion docs/rules/KeyNested.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ Version | Description
See also:

- [Key](Key.md)
- [KeyValue](KeyValue.md)
- [Property](Property.md)

[Yii2 ArrayHelper]: https://github.com/yiisoft/yii2/blob/68c30c1/framework/helpers/BaseArrayHelper.php "Yii2 ArrayHelper"
1 change: 0 additions & 1 deletion docs/rules/KeySet.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,3 @@ See also:

- [ArrayVal](ArrayVal.md)
- [Key](Key.md)
- [KeyValue](KeyValue.md)
79 changes: 0 additions & 79 deletions docs/rules/KeyValue.md

This file was deleted.

65 changes: 65 additions & 0 deletions docs/rules/LazyConsecutive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# LazyConsecutive

- `LazyConsecutive(callable(mixed $input): Validatable ...$ruleCreators)`

This executes a series of callbacks that create rules. Those callbacks accept the input as an argument and must return
an instance of `Validatable`.

This is particularly useful when the creation of rules would rely on the input itself. A good example is validating
whether a `password_confirmation` field matches the `password` field when processing data from a form.

```php
v::key('password', v::notEmpty())->validate($_POST);
v::key('password_confirmation', v::equals($_POST['password'] ?? null))->validate($_POST);
```

The problem with the above code is that you do not know if the `password` is a valid key, so you must check it manually
before performing the validation on `password_confirmation`. Besides, it could make it harder to reuse the validator.

The `lazyConsecutive()` rule makes this job much simpler and more elegantly:

```php
v::lazyConsecutive(
static fn() => v::key('password', v::stringType()->notEmpty()),
static fn($input) => v::key('password_confirmation', v::equals($input['password'])),
)->validate($_POST);
```

The return of the above code will be `true` if `$_POST['password_confirmation']` [equals](Equals.md)
`$_POST['password']`. The `lazyConsecutive()` rule will only execute the second callable if the rule from the first
callable passes.

Another typical example is validating country and subdivision codes:

```php
v::lazyConsecutive(
static fn() => v::key('countryCode', v::countryCode()),
static fn($input) => v::key('subdivisionCode', v::subdivisionCode($input['countryCode'])),
)->validate($_POST);
```

The return of the above code will be `true` if `$_POST['subdivisionCode']` is a [subdivision code](SubdivisionCode.md)
of `$_POST['countryCode']`.

## Categorization

- Callables
- Composite
- Nesting

## Changelog

| Version | Description |
| ------: | ----------- |
| 3.0.0 | Created |

***
See also:

- [AllOf](AllOf.md)
- [AnyOf](AnyOf.md)
- [Call](Call.md)
- [Equals](Equals.md)
- [NoneOf](NoneOf.md)
- [OneOf](OneOf.md)
- [SubdivisionCode](SubdivisionCode.md)
1 change: 1 addition & 0 deletions docs/rules/NoneOf.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ See also:

- [AllOf](AllOf.md)
- [AnyOf](AnyOf.md)
- [LazyConsecutive](LazyConsecutive.md)
- [Not](Not.md)
- [OneOf](OneOf.md)
- [When](When.md)
1 change: 1 addition & 0 deletions docs/rules/OneOf.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ See also:

- [AllOf](AllOf.md)
- [AnyOf](AnyOf.md)
- [LazyConsecutive](LazyConsecutive.md)
- [NoneOf](NoneOf.md)
- [When](When.md)
2 changes: 1 addition & 1 deletion docs/rules/SubdivisionCode.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ See also:

- [CountryCode](CountryCode.md)
- [CurrencyCode](CurrencyCode.md)
- [KeyValue](KeyValue.md)
- [LazyConsecutive](LazyConsecutive.md)
- [Nip](Nip.md)
- [Pesel](Pesel.md)
- [PolishIdCard](PolishIdCard.md)
Expand Down
2 changes: 1 addition & 1 deletion library/ChainedValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public function keyNested(

public function keySet(Key ...$rule): ChainedValidator;

public function keyValue(string $comparedKey, string $ruleName, string $baseKey): ChainedValidator;
public function lazyConsecutive(callable $ruleCreator, callable ...$ruleCreators): ChainedValidator;

/** @param "alpha-2"|"alpha-3" $set */
public function languageCode(string $set = 'alpha-2'): ChainedValidator;
Expand Down
Loading

0 comments on commit 41245f6

Please sign in to comment.