From 393ccc64e25952249e07c12b37447ee9b29f95ed Mon Sep 17 00:00:00 2001 From: Timmy D'Hooghe <63366355+timmydhooghe@users.noreply.github.com> Date: Fri, 12 Apr 2024 13:56:28 +0200 Subject: [PATCH] [11.x] Add RequiredIfDeclined validation rule (#51030) --- .../Concerns/ReplacesAttributes.php | 16 ++++++++++++++++ .../Concerns/ValidatesAttributes.php | 19 +++++++++++++++++++ src/Illuminate/Validation/Validator.php | 2 ++ tests/Validation/ValidationValidatorTest.php | 16 ++++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/src/Illuminate/Validation/Concerns/ReplacesAttributes.php b/src/Illuminate/Validation/Concerns/ReplacesAttributes.php index eacbcc67889b..5d420df14029 100644 --- a/src/Illuminate/Validation/Concerns/ReplacesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ReplacesAttributes.php @@ -609,6 +609,22 @@ protected function replaceRequiredIfAccepted($message, $attribute, $rule, $param return str_replace([':other'], $parameters, $message); } + /** + * Replace all place-holders for the required_if_declined rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + public function replaceRequiredIfDeclined($message, $attribute, $rule, $parameters) + { + $parameters[0] = $this->getDisplayableAttribute($parameters[0]); + + return str_replace([':other'], $parameters, $message); + } + /** * Replace all place-holders for the required_unless rule. * diff --git a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php index 374ae72dee19..d0f5335e29a4 100644 --- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php @@ -1961,6 +1961,25 @@ public function validateRequiredIfAccepted($attribute, $value, $parameters) return true; } + /** + * Validate that an attribute exists when another attribute was "declined". + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + public function validateRequiredIfDeclined($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'required_if_declined'); + + if ($this->validateDeclined($parameters[0], $this->getValue($parameters[0]))) { + return $this->validateRequired($attribute, $value); + } + + return true; + } + /** * Validate that an attribute does not exist or is an empty string. * diff --git a/src/Illuminate/Validation/Validator.php b/src/Illuminate/Validation/Validator.php index 838cd2ebceb8..2dff098c11a2 100755 --- a/src/Illuminate/Validation/Validator.php +++ b/src/Illuminate/Validation/Validator.php @@ -221,6 +221,7 @@ class Validator implements ValidatorContract 'Required', 'RequiredIf', 'RequiredIfAccepted', + 'RequiredIfDeclined', 'RequiredUnless', 'RequiredWith', 'RequiredWithAll', @@ -252,6 +253,7 @@ class Validator implements ValidatorContract 'DeclinedIf', 'RequiredIf', 'RequiredIfAccepted', + 'RequiredIfDeclined', 'RequiredUnless', 'RequiredWith', 'RequiredWithAll', diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index 25be6e5c2a56..7127efd2c659 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -2447,6 +2447,22 @@ public function testValidateAcceptedIf() $this->assertSame('The foo field must be accepted when bar is true.', $v->messages()->first('foo')); } + public function testValidateRequiredIfDeclined() + { + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['foo' => 'yes', 'bar' => 'baz'], ['bar' => 'required_if_declined:foo']); + $this->assertTrue($v->passes()); + + $v = new Validator($trans, ['foo' => 'no', 'bar' => 'baz'], ['bar' => 'required_if_declined:foo']); + $this->assertTrue($v->passes()); + + $v = new Validator($trans, ['foo' => 'yes', 'bar' => ''], ['bar' => 'required_if_declined:foo']); + $this->assertTrue($v->passes()); + + $v = new Validator($trans, ['foo' => 'no', 'bar' => ''], ['bar' => 'required_if_declined:foo']); + $this->assertFalse($v->passes()); + } + public function testValidateDeclined() { $trans = $this->getIlluminateArrayTranslator();