diff --git a/README.md b/README.md index 7fc0e3b..bba6614 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ validate 同时支持两种规则配置方式,对应了两种规则的收集 ### 单字段多规则 - `FieldValidation`: **每条规则中,只能有一个字段,但允许多个验证器。** (_规则配置类似于Laravel_) +- `FieldValidation`: 不支持验证器`each` 配置示例: @@ -570,21 +571,12 @@ $v->validate(); ```php ['users.*.id', 'each', 'required', 'isEmpty' => function($value) { - if ($value instanceof \Inhere\Validate\Exception\ArrayValueNotExists) { - return true; - } - // your code here ... -}] -``` -规则包含 .* 时的自定义验证,如: users.*.id -```php -['users.*.id', 'string', 'isEmpty' => function(array $value) { + // each value must be verified foreach ($value as $item) { if ($item instanceof \Inhere\Validate\Exception\ArrayValueNotExists) { return true; - } - // your code here ... } + // your code here ... }] ``` diff --git a/src/Traits/ScopedValidatorsTrait.php b/src/Traits/ScopedValidatorsTrait.php index 4f1d591..46cd975 100644 --- a/src/Traits/ScopedValidatorsTrait.php +++ b/src/Traits/ScopedValidatorsTrait.php @@ -663,11 +663,12 @@ public static function isCheckFile(string $name): bool /** * @param string $name - * + * @param array $args * @return bool */ - public static function isCheckRequired(string $name): bool + public static function isCheckRequired(string $name, array $args = []): bool { + $name = $name === 'each' ? (strval($args[0] ?? '')) : $name; return 0 === strpos($name, 'required'); } diff --git a/src/ValidationTrait.php b/src/ValidationTrait.php index e7d5474..e80a2c8 100644 --- a/src/ValidationTrait.php +++ b/src/ValidationTrait.php @@ -316,7 +316,7 @@ protected function applyRule($fields, array $rule, array $onlyChecked, bool $sto } // required*系列字段检查 || 文件资源检查 - if (self::isCheckRequired($validator) || self::isCheckFile($validator)) { + if (self::isCheckRequired($validator, $args) || self::isCheckFile($validator)) { $result = $this->fieldValidate($field, $value, $validator, $args, $defMsg); if (false === $result && $stopOnError) { break; @@ -375,6 +375,9 @@ protected function fieldValidate(string $field, $value, string $validator, array // other required* methods } elseif (method_exists($this, $validator)) { $passed = $this->$validator($field, $value, ...array_values($args)); + } elseif (method_exists($this, $method = $validator . 'Validator')) { + $passed = $this->$method($value, ...$args); + // if $validator is a global custom validator {@see UserValidators::$validators}. } else { throw new InvalidArgumentException("The validator [$validator] is not exists!"); } diff --git a/src/Validators.php b/src/Validators.php index 8ae5aac..d6fab0b 100644 --- a/src/Validators.php +++ b/src/Validators.php @@ -125,6 +125,14 @@ public static function isEmpty($val): bool { if (is_string($val)) { $val = trim($val); + } elseif (is_array($val)) { + // each value must be verified + foreach ($val as $item) { + if (($item instanceof ArrayValueNotExists)) { + $val = []; + break; + } + } } elseif (is_object($val)) { if ($val instanceof ArrayValueNotExists) { $val = ''; diff --git a/test/RuleValidationTest.php b/test/RuleValidationTest.php index 0b097d6..528f176 100644 --- a/test/RuleValidationTest.php +++ b/test/RuleValidationTest.php @@ -770,7 +770,6 @@ public function testIssues21(): void ], ]; $rs = [ - ['users.*.id', 'required'], // will passed. values like: [ArrayValueNotExists, ArrayValueNotExists] ['users.*.id', 'each', 'required'], ]; @@ -790,6 +789,18 @@ public function testIssues21(): void $this->assertFalse($v->isOk()); $this->assertSame('users.*.id each value must be through the "required" verify', $v->firstError()); + $rs = [ + ['users.*.id', 'required'], // will not pass. + ]; + + $v = RV::check($d1, $rs); + //parameter users.*.id is required! + $this->assertFalse($v->isOk()); + + $v = RV::check($d2, $rs); + //parameter users.*.id is required! + $this->assertFalse($v->isOk()); + $d3 = [ 'users' => [ ['id' => 1, 'name' => 'n1'], @@ -803,4 +814,31 @@ public function testIssues21(): void $this->assertTrue($v->isOk()); } + + /** + * @link https://github.com/inhere/php-validate/issues/33 + */ + public function testIssues33(): void + { + $d = [ + 'users' => [ + ['id' => 34, 'name' => 'tom'], + ['id' => 89], + ], + ]; + + $rs1 = [ + ['users.*.name', 'each', 'required'], + ['users.*.name', 'each', 'string'] + ]; + $v2 = RuleValidation::check($d, $rs1); + + $this->assertTrue($v2->isFail()); + + $rs2[] = ['users.*.name', 'each', 'string']; + + $v1 = RuleValidation::check($d, $rs2); + $this->assertFalse($v1->isFail()); + $this->assertTrue($v1->isOk()); + } }