Skip to content

Commit 5b604e1

Browse files
authored
[6.x] Fix nullable values for required_if (#37128)
* Fix nullable values for required_if * Reword null value
1 parent 8c61f6c commit 5b604e1

File tree

3 files changed

+101
-18
lines changed

3 files changed

+101
-18
lines changed

src/Illuminate/Validation/Concerns/FormatsMessages.php

+4
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ public function getDisplayableValue($attribute, $value)
336336
return $value ? 'true' : 'false';
337337
}
338338

339+
if (is_null($value)) {
340+
return 'empty';
341+
}
342+
339343
return $value;
340344
}
341345

src/Illuminate/Validation/Concerns/ValidatesAttributes.php

+65-17
Original file line numberDiff line numberDiff line change
@@ -1420,9 +1420,13 @@ public function validateRequiredIf($attribute, $value, $parameters)
14201420
{
14211421
$this->requireParameterCount(2, $parameters, 'required_if');
14221422

1423+
if (! Arr::has($this->data, $parameters[0])) {
1424+
return true;
1425+
}
1426+
14231427
[$values, $other] = $this->prepareValuesAndOther($parameters);
14241428

1425-
if (in_array($other, $values, is_bool($other))) {
1429+
if (in_array($other, $values, is_bool($other) || is_null($other))) {
14261430
return $this->validateRequired($attribute, $value);
14271431
}
14281432

@@ -1441,9 +1445,13 @@ public function validateExcludeIf($attribute, $value, $parameters)
14411445
{
14421446
$this->requireParameterCount(2, $parameters, 'exclude_if');
14431447

1448+
if (! Arr::has($this->data, $parameters[0])) {
1449+
return true;
1450+
}
1451+
14441452
[$values, $other] = $this->prepareValuesAndOther($parameters);
14451453

1446-
return ! in_array($other, $values, is_bool($other));
1454+
return ! in_array($other, $values, is_bool($other) || is_null($other));
14471455
}
14481456

14491457
/**
@@ -1458,9 +1466,38 @@ public function validateExcludeUnless($attribute, $value, $parameters)
14581466
{
14591467
$this->requireParameterCount(2, $parameters, 'exclude_unless');
14601468

1469+
if (! Arr::has($this->data, $parameters[0])) {
1470+
return true;
1471+
}
1472+
14611473
[$values, $other] = $this->prepareValuesAndOther($parameters);
14621474

1463-
return in_array($other, $values, is_bool($other));
1475+
return in_array($other, $values, is_bool($other) || is_null($other));
1476+
}
1477+
1478+
/**
1479+
* Validate that an attribute exists when another attribute does not have a given value.
1480+
*
1481+
* @param string $attribute
1482+
* @param mixed $value
1483+
* @param mixed $parameters
1484+
* @return bool
1485+
*/
1486+
public function validateRequiredUnless($attribute, $value, $parameters)
1487+
{
1488+
$this->requireParameterCount(2, $parameters, 'required_unless');
1489+
1490+
if (! Arr::has($this->data, $parameters[0])) {
1491+
return true;
1492+
}
1493+
1494+
[$values, $other] = $this->prepareValuesAndOther($parameters);
1495+
1496+
if (! in_array($other, $values, is_bool($other) || is_null($other))) {
1497+
return $this->validateRequired($attribute, $value);
1498+
}
1499+
1500+
return true;
14641501
}
14651502

14661503
/**
@@ -1479,6 +1516,10 @@ protected function prepareValuesAndOther($parameters)
14791516
$values = $this->convertValuesToBoolean($values);
14801517
}
14811518

1519+
if ($this->shouldConvertToNull($parameters[0]) || is_null($other)) {
1520+
$values = $this->convertValuesToNull($values);
1521+
}
1522+
14821523
return [$values, $other];
14831524
}
14841525

@@ -1493,6 +1534,17 @@ protected function shouldConvertToBoolean($parameter)
14931534
return in_array('boolean', Arr::get($this->rules, $parameter, []));
14941535
}
14951536

1537+
/**
1538+
* Check if parameter should be converted to null.
1539+
*
1540+
* @param string $parameter
1541+
* @return bool
1542+
*/
1543+
protected function shouldConvertToNull($parameter)
1544+
{
1545+
return in_array('nullable', Arr::get($this->rules, $parameter, []));
1546+
}
1547+
14961548
/**
14971549
* Convert the given values to boolean if they are string "true" / "false".
14981550
*
@@ -1513,24 +1565,20 @@ protected function convertValuesToBoolean($values)
15131565
}
15141566

15151567
/**
1516-
* Validate that an attribute exists when another attribute does not have a given value.
1568+
* Convert the given values to null if they are string "null".
15171569
*
1518-
* @param string $attribute
1519-
* @param mixed $value
1520-
* @param mixed $parameters
1521-
* @return bool
1570+
* @param array $values
1571+
* @return array
15221572
*/
1523-
public function validateRequiredUnless($attribute, $value, $parameters)
1573+
protected function convertValuesToNull($values)
15241574
{
1525-
$this->requireParameterCount(2, $parameters, 'required_unless');
1526-
1527-
[$values, $other] = $this->prepareValuesAndOther($parameters);
1528-
1529-
if (! in_array($other, $values, is_bool($other))) {
1530-
return $this->validateRequired($attribute, $value);
1531-
}
1575+
return array_map(function ($value) {
1576+
if ($value === 'null') {
1577+
return null;
1578+
}
15321579

1533-
return true;
1580+
return $value;
1581+
}, $values);
15341582
}
15351583

15361584
/**

tests/Validation/ValidationValidatorTest.php

+32-1
Original file line numberDiff line numberDiff line change
@@ -1094,13 +1094,44 @@ public function testRequiredIf()
10941094
$trans = $this->getIlluminateArrayTranslator();
10951095
$trans->addLines(['validation.required_if' => 'The :attribute field is required when :other is :value.'], 'en');
10961096
$v = new Validator($trans, ['foo' => 0], [
1097-
'foo' => 'required|boolean',
1097+
'foo' => 'nullable|required|boolean',
10981098
'bar' => 'required_if:foo,true',
10991099
'baz' => 'required_if:foo,false',
11001100
]);
11011101
$this->assertTrue($v->fails());
11021102
$this->assertCount(1, $v->messages());
11031103
$this->assertSame('The baz field is required when foo is 0.', $v->messages()->first('baz'));
1104+
1105+
$trans = $this->getIlluminateArrayTranslator();
1106+
$v = new Validator($trans, [], [
1107+
'foo' => 'nullable|boolean',
1108+
'baz' => 'nullable|required_if:foo,false',
1109+
]);
1110+
$this->assertTrue($v->passes());
1111+
1112+
$trans = $this->getIlluminateArrayTranslator();
1113+
$v = new Validator($trans, ['foo' => null], [
1114+
'foo' => 'nullable|boolean',
1115+
'baz' => 'nullable|required_if:foo,false',
1116+
]);
1117+
$this->assertTrue($v->passes());
1118+
1119+
$trans = $this->getIlluminateArrayTranslator();
1120+
$v = new Validator($trans, [], [
1121+
'foo' => 'nullable|boolean',
1122+
'baz' => 'nullable|required_if:foo,null',
1123+
]);
1124+
$this->assertTrue($v->passes());
1125+
1126+
$trans = $this->getIlluminateArrayTranslator();
1127+
$trans->addLines(['validation.required_if' => 'The :attribute field is required when :other is :value.'], 'en');
1128+
$v = new Validator($trans, ['foo' => null], [
1129+
'foo' => 'nullable|boolean',
1130+
'baz' => 'nullable|required_if:foo,null',
1131+
]);
1132+
$this->assertTrue($v->fails());
1133+
$this->assertCount(1, $v->messages());
1134+
$this->assertSame('The baz field is required when foo is empty.', $v->messages()->first('baz'));
11041135
}
11051136

11061137
public function testRequiredUnless()

0 commit comments

Comments
 (0)