Skip to content

Commit 985a52e

Browse files
authored
Merge pull request #718 from hypervel/upstream-sync-validation-rule-builders
Add fluent validation rule builders
2 parents d80bf13 + 8e50d89 commit 985a52e

71 files changed

Lines changed: 2590 additions & 54 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Hypervel\Contracts\Validation;
6+
7+
use Stringable;
8+
9+
interface ParameterizedRule extends Stringable
10+
{
11+
/**
12+
* Get the rule name followed by its parameters.
13+
*/
14+
public function toArray(): array;
15+
}

‎src/contracts/src/Validation/Validator.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function failed(): array;
3939
/**
4040
* Add conditions to a given field based on a Closure.
4141
*/
42-
public function sometimes(array|string $attribute, array|string $rules, callable $callback): static;
42+
public function sometimes(array|string $attribute, array|object|string $rules, callable $callback): static;
4343

4444
/**
4545
* Add an after validation callback.

‎src/data/src/Attributes/Validation/AcceptedIf.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ class AcceptedIf extends StringValidationAttribute
1414
{
1515
protected FieldReference $field;
1616

17+
protected array $values;
18+
1719
/**
1820
* Create an accepted-if rule attribute.
1921
*/
2022
public function __construct(
2123
string|FieldReference $field,
2224
protected string|bool|int|float|BackedEnum|ExternalReference $value,
25+
string|bool|int|float|BackedEnum|ExternalReference ...$values,
2326
) {
2427
$this->field = $this->parseFieldReference($field);
28+
$this->values = $values;
2529
}
2630

2731
/**
@@ -40,6 +44,7 @@ public function parameters(): array
4044
return [
4145
$this->field,
4246
$this->value,
47+
$this->values,
4348
];
4449
}
4550

‎src/data/src/Attributes/Validation/Confirmed.php‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,21 @@
55
namespace Hypervel\Data\Attributes\Validation;
66

77
use Attribute;
8+
use Hypervel\Data\Support\Validation\References\FieldReference;
89

910
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_PARAMETER)]
1011
class Confirmed extends StringValidationAttribute
1112
{
13+
protected ?FieldReference $field;
14+
15+
/**
16+
* Create a confirmed rule attribute.
17+
*/
18+
public function __construct(string|FieldReference|null $field = null)
19+
{
20+
$this->field = $field === null ? null : $this->parseFieldReference($field);
21+
}
22+
1223
/**
1324
* Get the Validator rule keyword.
1425
*/
@@ -22,6 +33,6 @@ public static function keyword(): string
2233
*/
2334
public function parameters(): array
2435
{
25-
return [];
36+
return $this->field === null ? [] : [$this->field];
2637
}
2738
}

‎src/data/src/Attributes/Validation/DateEquals.php‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
use Attribute;
88
use DateTimeInterface;
99
use Hypervel\Data\Support\Validation\References\ExternalReference;
10+
use Hypervel\Data\Support\Validation\References\FieldReference;
1011

1112
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_PARAMETER)]
1213
class DateEquals extends StringValidationAttribute
1314
{
1415
/**
1516
* Create a date-equals rule attribute.
1617
*/
17-
public function __construct(protected string|DateTimeInterface|ExternalReference $date)
18+
public function __construct(protected string|DateTimeInterface|FieldReference|ExternalReference $date)
1819
{
1920
}
2021

‎src/data/src/Attributes/Validation/DeclinedIf.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ class DeclinedIf extends StringValidationAttribute
1414
{
1515
protected FieldReference $field;
1616

17+
protected array $values;
18+
1719
/**
1820
* Create a declined-if rule attribute.
1921
*/
2022
public function __construct(
2123
string|FieldReference $field,
2224
protected string|bool|int|float|BackedEnum|ExternalReference $value,
25+
string|bool|int|float|BackedEnum|ExternalReference ...$values,
2326
) {
2427
$this->field = $this->parseFieldReference($field);
28+
$this->values = $values;
2529
}
2630

2731
/**
@@ -40,6 +44,7 @@ public function parameters(): array
4044
return [
4145
$this->field,
4246
$this->value,
47+
$this->values,
4348
];
4449
}
4550

‎src/data/src/Attributes/Validation/ExcludeIf.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ class ExcludeIf extends StringValidationAttribute
1414
{
1515
protected FieldReference $field;
1616

17+
protected array $values;
18+
1719
/**
1820
* Create a new exclude-if validation attribute.
1921
*/
2022
public function __construct(
2123
string|FieldReference $field,
2224
protected string|bool|int|float|BackedEnum|ExternalReference $value,
25+
string|bool|int|float|BackedEnum|ExternalReference ...$values,
2326
) {
2427
$this->field = $this->parseFieldReference($field);
28+
$this->values = $values;
2529
}
2630

2731
/**
@@ -43,6 +47,7 @@ public function parameters(): array
4347
return [
4448
$this->field,
4549
$this->value,
50+
$this->values,
4651
];
4752
}
4853
}

‎src/data/src/Attributes/Validation/ExcludeUnless.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ class ExcludeUnless extends StringValidationAttribute
1414
{
1515
protected FieldReference $field;
1616

17+
protected array $values;
18+
1719
/**
1820
* Create a new exclude-unless validation attribute.
1921
*/
2022
public function __construct(
2123
string|FieldReference $field,
2224
protected string|bool|int|float|BackedEnum|ExternalReference $value,
25+
string|bool|int|float|BackedEnum|ExternalReference ...$values,
2326
) {
2427
$this->field = $this->parseFieldReference($field);
28+
$this->values = $values;
2529
}
2630

2731
/**
@@ -40,6 +44,7 @@ public function parameters(): array
4044
return [
4145
$this->field,
4246
$this->value,
47+
$this->values,
4348
];
4449
}
4550
}

‎src/data/src/Attributes/Validation/ExcludeWithout.php‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ class ExcludeWithout extends StringValidationAttribute
1212
{
1313
protected FieldReference $field;
1414

15+
/** @var array<array-key, FieldReference> */
16+
protected array $fields;
17+
1518
/**
1619
* Create a new exclude-without validation attribute.
1720
*/
1821
public function __construct(
1922
string|FieldReference $field,
23+
string|FieldReference ...$fields,
2024
) {
2125
$this->field = $this->parseFieldReference($field);
26+
$this->fields = array_map($this->parseFieldReference(...), $fields);
2227
}
2328

2429
/**
@@ -36,6 +41,7 @@ public function parameters(): array
3641
{
3742
return [
3843
$this->field,
44+
$this->fields,
3945
];
4046
}
4147
}

‎src/data/src/Support/Validation/DataValidationCompiler.php‎

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Closure;
99
use DateTimeInterface;
1010
use Hypervel\Contracts\Container\Container;
11+
use Hypervel\Contracts\Validation\ParameterizedRule;
1112
use Hypervel\Data\Attributes\Validation\ArrayType;
1213
use Hypervel\Data\Attributes\Validation\BooleanType;
1314
use Hypervel\Data\Attributes\Validation\Enum;
@@ -1591,9 +1592,7 @@ protected function hasDistinctRule(array $rules): bool
15911592
return true;
15921593
}
15931594

1594-
if (is_string($rule)
1595-
&& strtolower(trim(explode(':', $rule, 2)[0])) === 'distinct'
1596-
) {
1595+
if ($this->ruleKeyword($rule) === 'distinct') {
15971596
return true;
15981597
}
15991598
}
@@ -1633,20 +1632,26 @@ protected function hasPresenceRule(array $rules): bool
16331632
return true;
16341633
}
16351634

1636-
if (! is_string($rule)) {
1637-
continue;
1638-
}
1639-
1640-
$name = strtolower(trim(explode(':', $rule, 2)[0]));
1641-
1642-
if (in_array($name, self::PRESENCE_RULES, true)) {
1635+
if (in_array($this->ruleKeyword($rule), self::PRESENCE_RULES, true)) {
16431636
return true;
16441637
}
16451638
}
16461639

16471640
return false;
16481641
}
16491642

1643+
/**
1644+
* Get the keyword of a string or structured validation rule.
1645+
*/
1646+
protected function ruleKeyword(mixed $rule): ?string
1647+
{
1648+
if ($rule instanceof ParameterizedRule) {
1649+
$rule = $rule->toArray()[0];
1650+
}
1651+
1652+
return is_string($rule) ? strtolower(trim(explode(':', $rule, 2)[0])) : null;
1653+
}
1654+
16501655
/**
16511656
* Determine if item rules can differ across one collection.
16521657
*

0 commit comments

Comments
 (0)