Skip to content

Commit

Permalink
fix problems with dots in validator
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed Sep 10, 2020
1 parent 1b8f0fd commit 8723739
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 16 deletions.
45 changes: 29 additions & 16 deletions src/Illuminate/Validation/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -314,22 +314,29 @@ protected function replacePlaceholders($data)
$originalData = [];

foreach ($data as $key => $value) {
if (is_array($value)) {
$value = $this->replacePlaceholders($value);
}

$key = str_replace(
[$this->dotPlaceholder, '__asterisk__'],
['.', '*'],
$key
);

$originalData[$key] = $value;
$originalData[$this->replacePlaceholderInString($key)] = is_array($value)
? $this->replacePlaceholders($value)
: $value;
}

return $originalData;
}

/**
* Replace the placeholders in the given string.
*
* @param string $value
* @return string
*/
protected function replacePlaceholderInString(string $value)
{
return str_replace(
[$this->dotPlaceholder, '__asterisk__'],
['.', '*'],
$value
);
}

/**
* Add an after validation callback.
*
Expand Down Expand Up @@ -722,6 +729,10 @@ protected function hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute)
*/
protected function validateUsingCustomRule($attribute, $value, $rule)
{
$attribute = $this->replacePlaceholderInString($attribute);

$value = is_array($value) ? $this->replacePlaceholders($value) : $value;

if (! $rule->passes($attribute, $value)) {
$this->failedRules[$attribute][get_class($rule)] = [];

Expand All @@ -745,21 +756,23 @@ protected function validateUsingCustomRule($attribute, $value, $rule)
*/
protected function shouldStopValidating($attribute)
{
$cleanedAttribute = $this->replacePlaceholderInString($attribute);

if ($this->hasRule($attribute, ['Bail'])) {
return $this->messages->has($attribute);
return $this->messages->has($cleanedAttribute);
}

if (isset($this->failedRules[$attribute]) &&
array_key_exists('uploaded', $this->failedRules[$attribute])) {
if (isset($this->failedRules[$cleanedAttribute]) &&
array_key_exists('uploaded', $this->failedRules[$cleanedAttribute])) {
return true;
}

// In case the attribute has any rule that indicates that the field is required
// and that rule already failed then we should stop validation at this point
// as now there is no point in calling other rules with this field empty.
return $this->hasRule($attribute, $this->implicitRules) &&
isset($this->failedRules[$attribute]) &&
array_intersect(array_keys($this->failedRules[$attribute]), $this->implicitRules);
isset($this->failedRules[$cleanedAttribute]) &&
array_intersect(array_keys($this->failedRules[$cleanedAttribute]), $this->implicitRules);
}

/**
Expand Down
45 changes: 45 additions & 0 deletions tests/Validation/ValidationValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4932,6 +4932,51 @@ public function message()
$this->assertSame('validation.string', $v->errors()->get('name')[2]);
}

public function testCustomValidationObjectWithDotKeysIsCorrectlyPassedValue()
{
$v = new Validator(
$this->getIlluminateArrayTranslator(),
['foo' => ['foo.bar' => 'baz']],
[
'foo' => new class implements Rule {
public function passes($attribute, $value)
{
return $value === ['foo.bar' => 'baz'];
}

public function message()
{
return ':attribute must be baz';
}
},
]
);

$this->assertTrue($v->passes());

// Test failed attributes contains proper entries
$v = new Validator(
$this->getIlluminateArrayTranslator(),
['foo' => ['foo.bar' => 'baz']],
[
'foo.foo\.bar' => new class implements Rule {
public function passes($attribute, $value)
{
return false;
}

public function message()
{
return ':attribute must be baz';
}
},
]
);

$this->assertFalse($v->passes());
$this->assertTrue(is_array($v->failed()['foo.foo.bar']));
}

public function testImplicitCustomValidationObjects()
{
// Test passing case...
Expand Down

0 comments on commit 8723739

Please sign in to comment.