From eb70335324c39d59c2c4ab73739a7f311bf5d7dc Mon Sep 17 00:00:00 2001 From: bastien-phi Date: Thu, 19 Aug 2021 22:58:29 +0200 Subject: [PATCH] [8.x] Add default rules in conditional rules (#38450) * Add default rules in conditional rules * formatting Co-authored-by: Taylor Otwell --- .../Validation/ConditionalRules.php | 21 ++++++++++++++++++- src/Illuminate/Validation/Rule.php | 5 +++-- .../Validation/ValidationRuleParser.php | 6 ++++-- tests/Validation/ValidationRuleParserTest.php | 19 +++++++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Validation/ConditionalRules.php b/src/Illuminate/Validation/ConditionalRules.php index 02d8ba84529d..d52455a5d78b 100644 --- a/src/Illuminate/Validation/ConditionalRules.php +++ b/src/Illuminate/Validation/ConditionalRules.php @@ -20,17 +20,26 @@ class ConditionalRules */ protected $rules; + /** + * The rules to be added to the attribute if the condition fails. + * + * @var array|string + */ + protected $defaultRules; + /** * Create a new conditional rules instance. * * @param callable|bool $condition * @param array|string $rules + * @param array|string $defaultRules * @return void */ - public function __construct($condition, $rules) + public function __construct($condition, $rules, $defaultRules = []) { $this->condition = $condition; $this->rules = $rules; + $this->defaultRules = $defaultRules; } /** @@ -55,4 +64,14 @@ public function rules() { return is_string($this->rules) ? explode('|', $this->rules) : $this->rules; } + + /** + * Get the default rules. + * + * @return array + */ + public function defaultRules() + { + return is_string($this->defaultRules) ? explode('|', $this->defaultRules) : $this->defaultRules; + } } diff --git a/src/Illuminate/Validation/Rule.php b/src/Illuminate/Validation/Rule.php index 549a8c6d3bbe..fba3e7c7dd44 100644 --- a/src/Illuminate/Validation/Rule.php +++ b/src/Illuminate/Validation/Rule.php @@ -20,11 +20,12 @@ class Rule * * @param callable|bool $condition * @param array|string $rules + * @param array|string $defaultRules * @return \Illuminate\Validation\ConditionalRules */ - public static function when($condition, $rules) + public static function when($condition, $rules, $defaultRules = []) { - return new ConditionalRules($condition, $rules); + return new ConditionalRules($condition, $rules, $defaultRules); } /** diff --git a/src/Illuminate/Validation/ValidationRuleParser.php b/src/Illuminate/Validation/ValidationRuleParser.php index 293849d220af..a3daa168a13c 100644 --- a/src/Illuminate/Validation/ValidationRuleParser.php +++ b/src/Illuminate/Validation/ValidationRuleParser.php @@ -291,7 +291,9 @@ public static function filterConditionalRules($rules, array $data = []) } if ($attributeRules instanceof ConditionalRules) { - return [$attribute => $attributeRules->passes($data) ? $attributeRules->rules() : null]; + return [$attribute => $attributeRules->passes($data) + ? $attributeRules->rules() + : $attributeRules->defaultRules()]; } return [$attribute => collect($attributeRules)->map(function ($rule) use ($data) { @@ -299,7 +301,7 @@ public static function filterConditionalRules($rules, array $data = []) return [$rule]; } - return $rule->passes($data) ? $rule->rules() : null; + return $rule->passes($data) ? $rule->rules() : $rule->defaultRules(); })->filter()->flatten(1)->values()->all()]; })->filter()->all(); } diff --git a/tests/Validation/ValidationRuleParserTest.php b/tests/Validation/ValidationRuleParserTest.php index 48ab2be04938..0adccc4fa53a 100644 --- a/tests/Validation/ValidationRuleParserTest.php +++ b/tests/Validation/ValidationRuleParserTest.php @@ -30,4 +30,23 @@ public function test_conditional_rules_are_properly_expanded_and_filtered() 'city' => ['required', 'min:2'], ], $rules); } + + public function test_conditional_rules_with_default() + { + $rules = ValidationRuleParser::filterConditionalRules([ + 'name' => Rule::when(true, ['required', 'min:2'], ['string', 'max:10']), + 'email' => Rule::when(false, ['required', 'min:2'], ['string', 'max:10']), + 'password' => Rule::when(false, 'required|min:2', 'string|max:10'), + 'username' => ['required', Rule::when(true, ['min:2'], ['string', 'max:10'])], + 'address' => ['required', Rule::when(false, ['min:2'], ['string', 'max:10'])], + ]); + + $this->assertEquals([ + 'name' => ['required', 'min:2'], + 'email' => ['string', 'max:10'], + 'password' => ['string', 'max:10'], + 'username' => ['required', 'min:2'], + 'address' => ['required', 'string', 'max:10'], + ], $rules); + } }