Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] Added declined and declined_if validation rules #39579

Merged
merged 1 commit into from
Nov 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/Illuminate/Validation/Concerns/ReplacesAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ protected function replaceAcceptedIf($message, $attribute, $rule, $parameters)
return str_replace([':other', ':value'], $parameters, $message);
}

/**
* Replace all place-holders for the declined_if rule.
*
* @param string $message
* @param string $attribute
* @param string $rule
* @param array $parameters
* @return string
*/
protected function replaceDeclinedIf($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 between rule.
*
Expand Down
39 changes: 39 additions & 0 deletions src/Illuminate/Validation/Concerns/ValidatesAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,45 @@ public function validateAcceptedIf($attribute, $value, $parameters)
return true;
}

/**
* Validate that an attribute was "declined".
*
* This validation rule implies the attribute is "required".
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function validateDeclined($attribute, $value)
{
$acceptable = ['no', 'off', '0', 0, false, 'false'];

return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true);
}

/**
* Validate that an attribute was "declined" when another attribute has a given value.
*
* @param string $attribute
* @param mixed $value
* @param mixed $parameters
* @return bool
*/
public function validateDeclinedIf($attribute, $value, $parameters)
{
$acceptable = ['no', 'off', '0', 0, false, 'false'];

$this->requireParameterCount(2, $parameters, 'declined_if');

[$values, $other] = $this->parseDependentRuleParameters($parameters);

if (in_array($other, $values, is_bool($other) || is_null($other))) {
return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true);
}

return true;
}

/**
* Validate that an attribute is an active URL.
*
Expand Down
3 changes: 3 additions & 0 deletions src/Illuminate/Validation/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ class Validator implements ValidatorContract
protected $implicitRules = [
'Accepted',
'AcceptedIf',
'Declined',
'DeclinedIf',
'Filled',
'Present',
'Required',
Expand Down Expand Up @@ -235,6 +237,7 @@ class Validator implements ValidatorContract
'Lt',
'Lte',
'AcceptedIf',
'DeclinedIf',
'RequiredIf',
'RequiredUnless',
'RequiredWith',
Expand Down
132 changes: 132 additions & 0 deletions tests/Validation/ValidationValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1806,6 +1806,9 @@ public function testValidateAccepted()
$v = new Validator($trans, ['foo' => 'no'], ['foo' => 'Accepted']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 'off'], ['foo' => 'Accepted']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => null], ['foo' => 'Accepted']);
$this->assertFalse($v->passes());

Expand All @@ -1815,6 +1818,9 @@ public function testValidateAccepted()
$v = new Validator($trans, ['foo' => 0], ['foo' => 'Accepted']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => '0'], ['foo' => 'Accepted']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => false], ['foo' => 'Accepted']);
$this->assertFalse($v->passes());

Expand Down Expand Up @@ -1846,12 +1852,18 @@ public function testValidateAcceptedIf()
$v = new Validator($trans, ['foo' => 'no', 'bar' => 'aaa'], ['foo' => 'accepted_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 'off', 'bar' => 'aaa'], ['foo' => 'accepted_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => null, 'bar' => 'aaa'], ['foo' => 'accepted_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 0, 'bar' => 'aaa'], ['foo' => 'accepted_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => '0', 'bar' => 'aaa'], ['foo' => 'accepted_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => false, 'bar' => 'aaa'], ['foo' => 'accepted_if:bar,aaa']);
$this->assertFalse($v->passes());

Expand Down Expand Up @@ -1908,6 +1920,126 @@ public function testValidateAcceptedIf()
$this->assertSame('The foo field must be accepted when bar is true.', $v->messages()->first('foo'));
}

public function testValidateDeclined()
{
$trans = $this->getIlluminateArrayTranslator();
$v = new Validator($trans, ['foo' => 'yes'], ['foo' => 'Declined']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 'on'], ['foo' => 'Declined']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => null], ['foo' => 'Declined']);
$this->assertFalse($v->passes());

$v = new Validator($trans, [], ['foo' => 'Declined']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 1], ['foo' => 'Declined']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => '1'], ['foo' => 'Declined']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => true], ['foo' => 'Declined']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 'true'], ['foo' => 'Declined']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 'no'], ['foo' => 'Declined']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => 'off'], ['foo' => 'Declined']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => '0'], ['foo' => 'Declined']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => 0], ['foo' => 'Declined']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => false], ['foo' => 'Declined']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => 'false'], ['foo' => 'Declined']);
$this->assertTrue($v->passes());
}

public function testValidateDeclinedIf()
{
$trans = $this->getIlluminateArrayTranslator();
$v = new Validator($trans, ['foo' => 'yes', 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 'on', 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => null, 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 1, 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => '1', 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => true, 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 'true', 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertFalse($v->passes());

$v = new Validator($trans, ['foo' => 'no', 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => 'off', 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => 0, 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => '0', 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => false, 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertTrue($v->passes());

$v = new Validator($trans, ['foo' => 'false', 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertTrue($v->passes());

// declined_if:bar,aaa
$trans = $this->getIlluminateArrayTranslator();
$trans->addLines(['validation.declined_if' => 'The :attribute field must be declined when :other is :value.'], 'en');
$v = new Validator($trans, ['foo' => 'yes', 'bar' => 'aaa'], ['foo' => 'declined_if:bar,aaa']);
$this->assertFalse($v->passes());
$v->messages()->setFormat(':message');
$this->assertSame('The foo field must be declined when bar is aaa.', $v->messages()->first('foo'));

// declined_if:bar,aaa,...
$trans = $this->getIlluminateArrayTranslator();
$trans->addLines(['validation.declined_if' => 'The :attribute field must be declined when :other is :value.'], 'en');
$v = new Validator($trans, ['foo' => 'yes', 'bar' => 'abc'], ['foo' => 'declined_if:bar,aaa,bbb,abc']);
$this->assertFalse($v->passes());
$v->messages()->setFormat(':message');
$this->assertSame('The foo field must be declined when bar is abc.', $v->messages()->first('foo'));

// declined_if:bar,boolean
$trans = $this->getIlluminateArrayTranslator();
$trans->addLines(['validation.declined_if' => 'The :attribute field must be declined when :other is :value.'], 'en');
$v = new Validator($trans, ['foo' => 'yes', 'bar' => false], ['foo' => 'declined_if:bar,false']);
$this->assertFalse($v->passes());
$v->messages()->setFormat(':message');
$this->assertSame('The foo field must be declined when bar is false.', $v->messages()->first('foo'));

$trans = $this->getIlluminateArrayTranslator();
$trans->addLines(['validation.declined_if' => 'The :attribute field must be declined when :other is :value.'], 'en');
$v = new Validator($trans, ['foo' => 'yes', 'bar' => true], ['foo' => 'declined_if:bar,true']);
$this->assertFalse($v->passes());
$v->messages()->setFormat(':message');
$this->assertSame('The foo field must be declined when bar is true.', $v->messages()->first('foo'));
}

public function testValidateEndsWith()
{
$trans = $this->getIlluminateArrayTranslator();
Expand Down