diff --git a/src/ValidationRule.php b/src/ValidationRule.php index b0f3486..a1caf2c 100644 --- a/src/ValidationRule.php +++ b/src/ValidationRule.php @@ -24,10 +24,19 @@ public static function make(string $name, Closure $closure, array $args = []): s return static::$pool[$hash] ?? (static::$pool[$hash] = new static($name, $closure, $args)); } + public string $rule; + protected function __construct( public string $name, public Closure $closure, public array $args = [] ) { + $this->rule = $this->name; + } + + public function setRule(string $rule): static + { + $this->rule = $rule; + return $this; } } diff --git a/src/ValidationRuleset.php b/src/ValidationRuleset.php index 694d908..67564be 100644 --- a/src/ValidationRuleset.php +++ b/src/ValidationRuleset.php @@ -3,6 +3,7 @@ namespace KK\Validation; use Closure; +use Hyperf\Validation\ValidationRuleParser; use InvalidArgumentException; use JetBrains\PhpStorm\Pure; use SplFileInfo; @@ -116,8 +117,9 @@ protected function __construct(array $ruleMap) if (count($ruleArgs) !== 2) { throw new InvalidArgumentException("Rule '{$rule}' require 2 parameter"); } + $name = "{$rule}:{$ruleArgs[0]},{$ruleArgs[1]}"; $ruleArgs[] = 'validateRequired' . static::fetchTypedRule($ruleMap); - $rules[] = ValidationRule::make('required_if', static::getClosure('validateRequiredIf'), $ruleArgs); + $rules[] = ValidationRule::make($name, static::getClosure('validateRequiredIf'), $ruleArgs)->setRule($rule); break; case 'nullable': $flags |= static::FLAG_NULLABLE; @@ -207,7 +209,7 @@ public function getRules(): array /** * @return string[] Error attribute names */ - public function check(mixed $data, array $attributes = []): array + public function check(mixed $data, array $attributes = [], ?string $ruleName = null): array { if (($this->flags & static::FLAG_NULLABLE) && $data === null) { return []; @@ -216,6 +218,10 @@ public function check(mixed $data, array $attributes = []): array $errors = []; foreach ($this->rules as $rule) { + if ($ruleName && $ruleName !== $rule->rule) { + continue; + } + $closure = $rule->closure; $valid = $closure($data, $attributes, ...$rule->args); if (!$valid) { @@ -352,6 +358,9 @@ protected static function validateRequiredIf(mixed $value, array $attributes, st { if (array_key_exists($key, $attributes)) { if ($attributes[$key] == $keyValue) { + if ($value === null) { + return false; + } return self::$validator($value, $attributes); } } @@ -422,13 +431,13 @@ protected static function getLength(mixed $value, array $attributes): int protected static function validateMin(mixed $value, array $attributes, int|float $min): bool { // TODO: file min support b, kb, mb, gb ... - return static::getLength($value) >= $min; + return static::getLength($value, $attributes) >= $min; } protected static function validateMax(mixed $value, array $attributes, int|float $max): bool { // TODO: file max support b, kb, mb, gb ... - return static::getLength($value) <= $max; + return static::getLength($value, $attributes) <= $max; } protected static function validateMinInteger(int $value, array $attributes, int|float $min): bool diff --git a/src/Validator.php b/src/Validator.php index 7cecd62..21b109c 100644 --- a/src/Validator.php +++ b/src/Validator.php @@ -112,6 +112,12 @@ protected function validRecursive(array $data, array $validationPairs, array $cu $this->recordError($currentPatternPart, 'required'); $invalid = true; } + + if($errors = $ruleset->check(null, $data, 'required_if')){ + $this->recordErrors($currentPatternPart, $errors); + $invalid = true; + } + continue; } $value = $data[$currentPatternPart]; diff --git a/tests/HyperfValidatorTest.php b/tests/HyperfValidatorTest.php index de60eac..64c7b4f 100644 --- a/tests/HyperfValidatorTest.php +++ b/tests/HyperfValidatorTest.php @@ -44,6 +44,18 @@ public function testFails() $this->assertFalse($validator->fails()); } + public function testRequiredIf() + { + $validator = $this->makeValidator(['type' => 1], ['id' => 'required_if:type,1', 'type' => 'required']); + $this->assertTrue($validator->fails()); + } + + public function testMax() + { + $validator = $this->makeValidator(['id' => 256], ['id' => 'max:255']); + $this->assertTrue($validator->fails()); + } + public function testGetMessageBag() { $data = [['id' => 256], ['id' => 'required|integer|max:255']];