diff --git a/src/Illuminate/Validation/Concerns/ReplacesAttributes.php b/src/Illuminate/Validation/Concerns/ReplacesAttributes.php index f5c3eb00c4e0..414354c7c04f 100644 --- a/src/Illuminate/Validation/Concerns/ReplacesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ReplacesAttributes.php @@ -505,4 +505,32 @@ protected function replaceStartsWith($message, $attribute, $rule, $parameters) return str_replace(':values', implode(', ', $parameters), $message); } + + /** + * Replace all place-holders for the unfilled_if rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceUnfilledIf($message, $attribute, $rule, $parameters) + { + return $this->replaceRequiredIf($message, $attribute, $rule, $parameters); + } + + /** + * Replace all place-holders for the unfilled_with rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceUnfilledWith($message, $attribute, $rule, $parameters) + { + return $this->replaceRequiredWith($message, $attribute, $rule, $parameters); + } } diff --git a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php index fe394a2b0638..132a245bf572 100644 --- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php @@ -1726,6 +1726,46 @@ public function validateTimezone($attribute, $value) return in_array($value, timezone_identifiers_list(), true); } + /** + * Validate that an attribute is unfilled when another attribute has a given value. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + public function validateUnfilledIf($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'unfilled_if'); + + [$values, $other] = $this->prepareValuesAndOther($parameters); + + if (in_array($other, $values)) { + return ! $this->validateRequired($attribute, $value); + } + + return true; + } + + /** + * Validate that an attribute is unfilled when any other attribute exists. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + public function validateUnfilledWith($attribute, $value, $parameters) + { + $this->requireParameterCount(1, $parameters, 'unfilled_with'); + + if (! $this->allFailingRequired($parameters)) { + return ! $this->validateRequired($attribute, $value); + } + + return true; + } + /** * Validate that an attribute is a valid URL. * diff --git a/src/Illuminate/Validation/Validator.php b/src/Illuminate/Validation/Validator.php index 86fbfc8769eb..17e7935818d6 100755 --- a/src/Illuminate/Validation/Validator.php +++ b/src/Illuminate/Validation/Validator.php @@ -221,6 +221,7 @@ class Validator implements ValidatorContract 'RequiredWithout', 'RequiredWithoutAll', 'Same', + 'UnfilledIf', 'Unique', ]; diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index 826aeef296c3..9f99269f29fa 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -5571,6 +5571,80 @@ public function testValidateFailsWithAsterisksAsDataKeys() $this->assertSame(['data.1.date' => ['validation.date'], 'data.*.date' => ['validation.date']], $validator->messages()->toArray()); } + public function testValidateUnfilledIf() + { + $basicUnfilledRules = [ + 'mode' => 'required', + 'full_name' => 'unfilled_if:mode,split', + 'first_name' => 'required_if:mode,split', + 'last_name' => 'required_if:mode,split', + ]; + $v = new Validator($this->getIlluminateArrayTranslator(), ['mode' => 'none'], $basicUnfilledRules); + $this->assertTrue($v->passes()); + + $v = new Validator($this->getIlluminateArrayTranslator(), [ + 'mode' => 'split', + 'first_name' => 'Richard', + 'last_name' => 'Bobby', + ], $basicUnfilledRules); + $this->assertTrue($v->passes()); + + $v = new Validator($this->getIlluminateArrayTranslator(), [ + 'mode' => 'split', + 'full_name' => 'Ricky Bobby', + 'first_name' => 'Richard', + 'last_name' => 'Bobby', + ], $basicUnfilledRules); + $this->assertTrue($v->fails()); + + $v = new Validator($this->getIlluminateArrayTranslator(), [ + 'mode' => 'split', + 'full_name' => 'Ricky Bobby', + 'last_name' => 'Bobby', + ], $basicUnfilledRules); + $this->assertTrue($v->fails()); + + $basicUnfilledRules = [ + 'mode' => 'required', + 'full_name' => 'required_if:mode,single', + 'first_name' => 'unfilled_if:mode,single', + 'last_name' => 'unfilled_if:mode,single', + ]; + $v = new Validator($this->getIlluminateArrayTranslator(), [ + 'mode' => 'single', + 'full_name' => 'Ricky Bobby', + ], $basicUnfilledRules); + $this->assertTrue($v->passes()); + + $v = new Validator($this->getIlluminateArrayTranslator(), [ + 'mode' => 'single', + 'full_name' => 'Ricky Bobby', + 'last_name' => 'Bobby', + ], $basicUnfilledRules); + $this->assertTrue($v->fails()); + } + + public function testValidateUnfilledWith() + { + $v = new Validator($this->getIlluminateArrayTranslator(), [], ['name' => 'unfilled_with:first_name', 'first_name' => 'sometimes']); + $this->assertTrue($v->passes()); + + $v = new Validator($this->getIlluminateArrayTranslator(), ['name' => 'Ricky Bobby'], ['name' => 'unfilled_with:first_name,last_name', 'first_name' => 'sometimes']); + $this->assertTrue($v->passes()); + + $v = new Validator($this->getIlluminateArrayTranslator(), ['name' => 'Ricky Bobby', 'first_name' => 'Richard', 'last_name' => 'Robertson'], ['name' => 'unfilled_with:first_name,last_name', 'first_name' => 'sometimes', 'last_name' => 'sometimes']); + $this->assertTrue($v->fails()); + + $v = new Validator($this->getIlluminateArrayTranslator(), ['name' => 'Ricky Bobby', 'last_name' => 'Robertson'], ['name' => 'unfilled_with:first_name,last_name', 'first_name' => 'sometimes']); + $this->assertTrue($v->fails()); + + $v = new Validator($this->getIlluminateArrayTranslator(), ['name' => 'Ricky Bobby', 'first_name' => 'Richard', 'last_name' => 'Robert'], ['name' => 'sometimes', 'first_name' => 'unfilled_with:name', 'last_name' => 'unfilled_with:name']); + $this->assertTrue($v->fails()); + + $v = new Validator($this->getIlluminateArrayTranslator(), ['first_name' => 'Richard', 'last_name' => 'Robert'], ['name' => 'sometimes', 'first_name' => 'unfilled_with:name', 'last_name' => 'unfilled_with:name']); + $this->assertTrue($v->passes()); + } + protected function getTranslator() { return m::mock(TranslatorContract::class);