Skip to content
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

Handle names via the Named rule #1511

Merged
merged 1 commit into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions bin/create-mixin
Original file line number Diff line number Diff line change
Expand Up @@ -172,17 +172,18 @@ function overwriteFile(string $content, string $basename): void
'PropertyOptional',
'Attributes',
'Templated',
'Named',
];

$mixins = [
['Key', 'key', [], $structureRelatedRules],
['Length', 'length', $numberRelatedRules, []],
['Max', 'max', $numberRelatedRules, []],
['Min', 'min', $numberRelatedRules, []],
['Not', 'not', [], ['Not', 'NotEmpty', 'NotBlank', 'NotEmoji', 'NotUndef', 'NotOptional', 'NullOr', 'UndefOr', 'Optional', 'Attributes', 'Templated']],
['NullOr', 'nullOr', [], ['Nullable', 'NullOr', 'Optional', 'NotOptional', 'NotUndef', 'UndefOr', 'Templated']],
['Not', 'not', [], ['Not', 'NotEmpty', 'NotBlank', 'NotEmoji', 'NotUndef', 'NotOptional', 'NullOr', 'UndefOr', 'Optional', 'Attributes', 'Templated', 'Named']],
['NullOr', 'nullOr', [], ['Nullable', 'NullOr', 'Optional', 'NotOptional', 'NotUndef', 'UndefOr', 'Templated', 'Named']],
['Property', 'property', [], $structureRelatedRules],
['UndefOr', 'undefOr', [], ['Nullable', 'NullOr', 'NotOptional', 'NotUndef', 'Optional', 'UndefOr', 'Attributes', 'Templated']],
['UndefOr', 'undefOr', [], ['Nullable', 'NullOr', 'NotOptional', 'NotUndef', 'Optional', 'UndefOr', 'Attributes', 'Templated', 'Named']],
['', null, [], []],
];

Expand Down
4 changes: 4 additions & 0 deletions docs/09-list-of-rules-by-category.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@

## Core

- [Named](rules/Named.md)
- [Not](rules/Not.md)
- [Templated](rules/Templated.md)

Expand Down Expand Up @@ -159,6 +160,7 @@
## Miscellaneous

- [FilterVar](rules/FilterVar.md)
- [Named](rules/Named.md)
- [NotBlank](rules/NotBlank.md)
- [NotEmpty](rules/NotEmpty.md)
- [NotUndef](rules/NotUndef.md)
Expand Down Expand Up @@ -260,6 +262,7 @@
- [KeyExists](rules/KeyExists.md)
- [KeyOptional](rules/KeyOptional.md)
- [KeySet](rules/KeySet.md)
- [Named](rules/Named.md)
- [Property](rules/Property.md)
- [PropertyExists](rules/PropertyExists.md)
- [PropertyOptional](rules/PropertyOptional.md)
Expand Down Expand Up @@ -392,6 +395,7 @@
- [Mimetype](rules/Mimetype.md)
- [Min](rules/Min.md)
- [Multiple](rules/Multiple.md)
- [Named](rules/Named.md)
- [Negative](rules/Negative.md)
- [NfeAccessKey](rules/NfeAccessKey.md)
- [Nif](rules/Nif.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/Attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ v::attributes()->assert(new Person('', 'not an email', 'not a date', 'not a phon
***
See also:

- [Named](Named.md)
- [NullOr](NullOr.md)
- [ObjectType](ObjectType.md)
- [Property](Property.md)
Expand Down
48 changes: 48 additions & 0 deletions docs/rules/Named.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Named

- `Named(Rule $rule, string $name)`

Validates the input with the given rule, and uses the custom name in the error message.

```php
v::named(v::email(), 'Your email')->assert('not an email');
// Message: Your email must be a valid email address
```

Here's an example of a similar code, but without using the `Named` rule:

```php
v::email()->assert('not an email');
// Message: "not an email" must be a valid email address
```

The `Named` rule can be also useful when you're using [Attributes](Attributes.md) and want a custom name for a specific property.

## Templates

This rule does not have any templates, as it will use the template of the given rule.

## Template placeholders

| Placeholder | Description |
|-------------|---------------------------------------|
| `name` | The value that you define as `$name`. |

## Categorization

- Core
- Structures
- Miscellaneous

## Changelog

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

***
See also:

- [Attributes](Attributes.md)
- [Not](Not.md)
- [Templated](Templated.md)
1 change: 1 addition & 0 deletions docs/rules/Not.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ Each other validation has custom messages for negated rules.
***
See also:

- [Named](Named.md)
- [NoneOf](NoneOf.md)
- [Templated](Templated.md)
1 change: 1 addition & 0 deletions docs/rules/Templated.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ This rule does not have any templates, as you must define the templates yourself
See also:

- [Attributes](Attributes.md)
- [Named](Named.md)
- [Not](Not.md)
23 changes: 0 additions & 23 deletions library/Helpers/CanExtractPropertyValue.php

This file was deleted.

39 changes: 0 additions & 39 deletions library/Helpers/DeprecatedValidatableMethods.php

This file was deleted.

2 changes: 2 additions & 0 deletions library/Mixins/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ public static function min(Rule $rule): Chain;

public static function multiple(int $multipleOf): Chain;

public static function named(Rule $rule, string $name): Chain;

public static function negative(): Chain;

public static function nfeAccessKey(): Chain;
Expand Down
2 changes: 2 additions & 0 deletions library/Mixins/Chain.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ public function min(Rule $rule): Chain;

public function multiple(int $multipleOf): Chain;

public function named(Rule $rule, string $name): Chain;

public function negative(): Chain;

public function nfeAccessKey(): Chain;
Expand Down
32 changes: 25 additions & 7 deletions library/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

namespace Respect\Validation;

use Respect\Validation\Rules\Core\Nameable;
use Respect\Validation\Rules\Core\Renameable;

use function array_filter;
use function array_map;
use function count;
Expand All @@ -25,8 +28,6 @@ final class Result

public readonly string $id;

public readonly ?string $name;

/** @param array<string, mixed> $parameters */
public function __construct(
public readonly bool $isValid,
Expand All @@ -35,13 +36,12 @@ public function __construct(
public readonly array $parameters = [],
public readonly string $template = Rule::TEMPLATE_STANDARD,
public readonly Mode $mode = Mode::DEFAULT,
?string $name = null,
public readonly ?string $name = null,
?string $id = null,
public readonly ?Result $adjacent = null,
public readonly bool $unchangeableId = false,
Result ...$children,
) {
$this->name = $rule->getName() ?? $name;
$this->id = $id ?? lcfirst(substr((string) strrchr($rule::class, '\\'), 1));
$this->children = $children;
}
Expand Down Expand Up @@ -109,6 +109,11 @@ public function withId(string $id): self
return $this->clone(id: $id);
}

public function withIdFrom(Rule $rule): self
{
return $this->clone(id: lcfirst(substr((string) strrchr($rule::class, '\\'), 1)));
}

public function withUnchangeableId(string $id): self
{
return $this->clone(id: $id, unchangeableId: true);
Expand All @@ -128,14 +133,27 @@ public function withChildren(Result ...$children): self
return $this->clone(children: $children);
}

public function withNameIfMissing(string $name): self
public function withName(string $name): self
{
return $this->clone(
name: $this->name ?? $name,
children: array_map(static fn (Result $child) => $child->withNameIfMissing($name), $this->children),
name: $this->rule instanceof Renameable ? $name : ($this->name ?? $name),
adjacent: $this->adjacent?->withName($name),
children: array_map(
static fn (Result $child) => $child->withName($child->name ?? $name),
$this->children
),
);
}

public function withNameFrom(Rule $rule): self
{
if ($rule instanceof Nameable && $rule->getName() !== null) {
return $this->withName($rule->getName());
}

return $this;
}

public function withInput(mixed $input): self
{
$currentInput = $this->input;
Expand Down
4 changes: 0 additions & 4 deletions library/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,4 @@ interface Rule
public const TEMPLATE_STANDARD = '__standard__';

public function evaluate(mixed $input): Result;

public function getName(): ?string;

public function setName(string $name): static;
}
5 changes: 2 additions & 3 deletions library/Rules/Attributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use ReflectionObject;
use Respect\Validation\Result;
use Respect\Validation\Rule;
use Respect\Validation\Rules\Core\Binder;
use Respect\Validation\Rules\Core\Reducer;
use Respect\Validation\Rules\Core\Standard;

Expand All @@ -23,7 +22,7 @@ final class Attributes extends Standard
{
public function evaluate(mixed $input): Result
{
$objectType = (new Binder($this, new ObjectType()))->evaluate($input);
$objectType = (new ObjectType())->evaluate($input);
if (!$objectType->isValid) {
return $objectType->withId('attributes');
}
Expand All @@ -49,6 +48,6 @@ public function evaluate(mixed $input): Result
return (new AlwaysValid())->evaluate($input)->withId('attributes');
}

return (new Binder($this, new Reducer(...$rules)))->evaluate($input)->withId('attributes');
return (new Reducer(...$rules))->evaluate($input)->withId('attributes');
}
}
3 changes: 1 addition & 2 deletions library/Rules/Circuit.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

use Attribute;
use Respect\Validation\Result;
use Respect\Validation\Rules\Core\Binder;
use Respect\Validation\Rules\Core\Composite;

#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
Expand All @@ -20,7 +19,7 @@ final class Circuit extends Composite
public function evaluate(mixed $input): Result
{
foreach ($this->rules as $rule) {
$result = (new Binder($this, $rule))->evaluate($input);
$result = $rule->evaluate($input);
if (!$result->isValid) {
return $result;
}
Expand Down
31 changes: 0 additions & 31 deletions library/Rules/Core/Binder.php

This file was deleted.

Loading
Loading