From 86d9657f4a004564b3dbd241b26487b9a1ed2742 Mon Sep 17 00:00:00 2001 From: Jess Archer Date: Tue, 9 Mar 2021 14:59:36 +1000 Subject: [PATCH] Add prohibited_if and prohibited_unless validation rules --- .../Concerns/ReplacesAttributes.php | 40 +++++++++++ .../Concerns/ValidatesAttributes.php | 42 +++++++++++ src/Illuminate/Validation/Validator.php | 2 + tests/Validation/ValidationValidatorTest.php | 72 +++++++++++++++++++ 4 files changed, 156 insertions(+) diff --git a/src/Illuminate/Validation/Concerns/ReplacesAttributes.php b/src/Illuminate/Validation/Concerns/ReplacesAttributes.php index d645dbd6d5a6..d4a47af146c4 100644 --- a/src/Illuminate/Validation/Concerns/ReplacesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ReplacesAttributes.php @@ -374,6 +374,46 @@ protected function replaceRequiredUnless($message, $attribute, $rule, $parameter return str_replace([':other', ':values'], [$other, implode(', ', $values)], $message); } + /** + * Replace all place-holders for the prohibited_if rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceProhibitedIf($message, $attribute, $rule, $parameters) + { + $parameters[1] = $this->getDisplayableValue($parameters[0], Arr::get($this->data, $parameters[0])); + + $parameters[0] = $this->getDisplayableAttribute($parameters[0]); + + return str_replace([':other', ':value'], $parameters, $message); + } + + /** + * Replace all place-holders for the prohibited_unless rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replaceProhibitedUnless($message, $attribute, $rule, $parameters) + { + $other = $this->getDisplayableAttribute($parameters[0]); + + $values = []; + + foreach (array_slice($parameters, 1) as $value) { + $values[] = $this->getDisplayableValue($parameters[0], $value); + } + + return str_replace([':other', ':values'], [$other, implode(', ', $values)], $message); + } + /** * Replace all place-holders for the same rule. * diff --git a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php index bba094dd61f6..2f1dcf6a2157 100644 --- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php @@ -1434,6 +1434,48 @@ public function validateRequiredIf($attribute, $value, $parameters) return true; } + /** + * Validate that an attribute does not exist when another attribute has a given value. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + public function validateProhibitedIf($attribute, $value, $parameters) + { + $this->requireParameterCount(2, $parameters, 'prohibited_if'); + + [$values, $other] = $this->parseDependentRuleParameters($parameters); + + if (in_array($other, $values, is_bool($other))) { + return ! $this->validateRequired($attribute, $value); + } + + return true; + } + + /** + * Validate that an attribute does not exist unless another attribute has a given value. + * + * @param string $attribute + * @param mixed $value + * @param mixed $parameters + * @return bool + */ + public function validateProhibitedUnless($attribute, $value, $parameters) + { + $this->requireParameterCount(2, $parameters, 'prohibited_unless'); + + [$values, $other] = $this->parseDependentRuleParameters($parameters); + + if (! in_array($other, $values, is_bool($other))) { + return ! $this->validateRequired($attribute, $value); + } + + return true; + } + /** * Indicate that an attribute should be excluded when another attribute has a given value. * diff --git a/src/Illuminate/Validation/Validator.php b/src/Illuminate/Validation/Validator.php index 48d9946386d6..0aa44d6c197e 100755 --- a/src/Illuminate/Validation/Validator.php +++ b/src/Illuminate/Validation/Validator.php @@ -227,6 +227,8 @@ class Validator implements ValidatorContract 'RequiredWithAll', 'RequiredWithout', 'RequiredWithoutAll', + 'ProhibitedIf', + 'ProhibitedUnless', 'Same', 'Unique', ]; diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index a60b93b9abf4..7f21e4ba1688 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -1146,6 +1146,78 @@ public function testRequiredUnless() $this->assertSame('The last field is required unless first is in taylor, sven.', $v->messages()->first('last')); } + public function testProhibitedIf() + { + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['first' => 'taylor', 'last' => 'otwell'], ['last' => 'prohibited_if:first,taylor']); + $this->assertTrue($v->fails()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['first' => 'taylor'], ['last' => 'prohibited_if:first,taylor']); + $this->assertTrue($v->passes()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['first' => 'taylor', 'last' => 'otwell'], ['last' => 'prohibited_if:first,taylor,jess']); + $this->assertTrue($v->fails()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['first' => 'taylor'], ['last' => 'prohibited_if:first,taylor,jess']); + $this->assertTrue($v->passes()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['foo' => true, 'bar' => 'baz'], ['bar' => 'prohibited_if:foo,false']); + $this->assertTrue($v->passes()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['foo' => true, 'bar' => 'baz'], ['bar' => 'prohibited_if:foo,true']); + $this->assertTrue($v->fails()); + + // error message when passed multiple values (prohibited_if:foo,bar,baz) + $trans = $this->getIlluminateArrayTranslator(); + $trans->addLines(['validation.prohibited_if' => 'The :attribute field is prohibited when :other is :value.'], 'en'); + $v = new Validator($trans, ['first' => 'jess', 'last' => 'archer'], ['last' => 'prohibited_if:first,taylor,jess']); + $this->assertFalse($v->passes()); + $this->assertSame('The last field is prohibited when first is jess.', $v->messages()->first('last')); + } + + public function testProhibitedUnless() + { + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['first' => 'jess', 'last' => 'archer'], ['last' => 'prohibited_unless:first,taylor']); + $this->assertTrue($v->fails()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['first' => 'taylor', 'last' => 'otwell'], ['last' => 'prohibited_unless:first,taylor']); + $this->assertTrue($v->passes()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['first' => 'jess'], ['last' => 'prohibited_unless:first,taylor']); + $this->assertTrue($v->passes()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['first' => 'taylor', 'last' => 'otwell'], ['last' => 'prohibited_unless:first,taylor,jess']); + $this->assertTrue($v->passes()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['first' => 'jess', 'last' => 'archer'], ['last' => 'prohibited_unless:first,taylor,jess']); + $this->assertTrue($v->passes()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['foo' => false, 'bar' => 'baz'], ['bar' => 'prohibited_unless:foo,false']); + $this->assertTrue($v->passes()); + + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['foo' => false, 'bar' => 'baz'], ['bar' => 'prohibited_unless:foo,true']); + $this->assertTrue($v->fails()); + + // error message when passed multiple values (prohibited_unless:foo,bar,baz) + $trans = $this->getIlluminateArrayTranslator(); + $trans->addLines(['validation.prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.'], 'en'); + $v = new Validator($trans, ['first' => 'tim', 'last' => 'macdonald'], ['last' => 'prohibitedUnless:first,taylor,jess']); + $this->assertFalse($v->passes()); + $this->assertSame('The last field is prohibited unless first is in taylor, jess.', $v->messages()->first('last')); + } + public function testFailedFileUploads() { $trans = $this->getIlluminateArrayTranslator();