From b0a34737d69e13de33240e5b54f01e570ab63050 Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Fri, 6 Dec 2024 10:03:51 +0100 Subject: [PATCH] fixes #3612 --- .../core/src/Foundation/AbstractValidator.php | 20 ++++++- .../integration/extenders/ValidatorTest.php | 59 ++++++++++++++++++- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/framework/core/src/Foundation/AbstractValidator.php b/framework/core/src/Foundation/AbstractValidator.php index 12eafcd59d..a43be822c8 100644 --- a/framework/core/src/Foundation/AbstractValidator.php +++ b/framework/core/src/Foundation/AbstractValidator.php @@ -11,6 +11,8 @@ use Flarum\Locale\TranslatorInterface; use Illuminate\Support\Arr; +use Illuminate\Support\Collection; +use Illuminate\Support\Str; use Illuminate\Validation\Factory; use Illuminate\Validation\ValidationException; use Illuminate\Validation\Validator; @@ -84,9 +86,21 @@ protected function getActiveRules(array $attributes): array { $rules = $this->getRules(); - return $this->validateMissingKeys - ? $rules - : Arr::only($rules, array_keys($attributes)); + if ($this->validateMissingKeys) { + return $rules; + } + + return Collection::make($rules) + ->filter(function (mixed $rule, string $key) use ($attributes) { + foreach ($attributes as $attributeKey => $attributeValue) { + if ($attributeKey === $key || Str::startsWith($key, $attributeKey . '.')) { + return true; + } + } + + return false; + }) + ->all(); } protected function getMessages(): array diff --git a/framework/core/tests/integration/extenders/ValidatorTest.php b/framework/core/tests/integration/extenders/ValidatorTest.php index eafaf4dae0..01bf94e6cd 100644 --- a/framework/core/tests/integration/extenders/ValidatorTest.php +++ b/framework/core/tests/integration/extenders/ValidatorTest.php @@ -18,7 +18,7 @@ class ValidatorTest extends TestCase { - private function extendToRequireLongPassword() + private function extendToRequireLongPassword(): void { $this->extend((new Extend\Validator(CustomUserValidator::class))->configure(function ($flarumValidator, $validator) { $validator->setRules([ @@ -30,7 +30,7 @@ private function extendToRequireLongPassword() })); } - private function extendToRequireLongPasswordViaInvokableClass() + private function extendToRequireLongPasswordViaInvokableClass(): void { $this->extend((new Extend\Validator(CustomUserValidator::class))->configure(CustomValidatorClass::class)); } @@ -74,6 +74,51 @@ public function custom_validation_rule_doesnt_affect_other_validators() // If we have gotten this far, no validation exception has been thrown, so the test is successful. $this->assertTrue(true); } + + #[Test] + public function validator_only_validates_provided_data_by_default() + { + /** @var SecondCustomValidator $validator */ + $validator = $this->app()->getContainer()->make(SecondCustomValidator::class); + + $validator->assertValid([ + 'my_key' => 'value', + ]); + + // If we have gotten this far, no validation exception has been thrown, so the test is successful. + $this->assertTrue(true); + } + + #[Test] + public function validator_includes_path_based_rules() + { + /** @var SecondCustomValidator $validator */ + $validator = $this->app()->getContainer()->make(SecondCustomValidator::class); + + $this->expectException(ValidationException::class); + + $validator->assertValid([ + 'my_key' => 'value', + 'my_third_key' => [null], + ]); + } + + #[Test] + public function validator_can_validate_missing_keys() + { + /** @var SecondCustomValidator $validator */ + $validator = $this->app()->getContainer()->make(SecondCustomValidator::class)->validateMissingKeys(); + + $this->expectException(ValidationException::class); + + $validator->validateMissingKeys()->assertValid([ + 'my_key' => 'value', + 'my_third_key' => [ + '2021-01-01 00:00:00', + '2021-01-02 00:00:00' + ] + ]); + } } class CustomValidatorClass @@ -142,3 +187,13 @@ class CustomValidator extends AbstractValidator 'name_plural' => ['required'] ]; } + +class SecondCustomValidator extends AbstractValidator +{ + protected array $rules = [ + 'my_key' => ['required'], + 'my_other_key' => ['required'], + 'my_third_key' => ['required', 'array'], + 'my_third_key.*' => ['required', 'date'] + ]; +}