Skip to content

Commit

Permalink
Fix #15084. Stop further validation if a "required" rule fails
Browse files Browse the repository at this point in the history
  • Loading branch information
themsaid committed Aug 27, 2016
1 parent e3ed514 commit 5a0eb37
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
13 changes: 9 additions & 4 deletions src/Illuminate/Validation/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -751,18 +751,23 @@ protected function validateBail()
}

/**
* Stop on error if "bail" rule is assigned and attribute has a message.
* Check if we should stop further validations on a given attribute.
*
* @param string $attribute
* @return bool
*/
protected function shouldStopValidating($attribute)
{
if (! $this->hasRule($attribute, ['Bail'])) {
return false;
if ($this->hasRule($attribute, ['Bail'])) {
return $this->messages->has($attribute);
}

return $this->messages->has($attribute);
// 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);
}

/**
Expand Down
21 changes: 21 additions & 0 deletions tests/Validation/ValidationValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,27 @@ public function testValidateFilled()
$this->assertFalse($v->passes());
}

public function testValidationStopsAtFailedPresenceCheck()
{
$trans = $this->getRealTranslator();

$v = new Validator($trans, ['name' => null], ['name' => 'Required|string']);
$v->passes();
$this->assertEquals(['validation.required'], $v->errors()->get('name'));

$v = new Validator($trans, ['name' => null, 'email' => 'email'], ['name' => 'required_with:email|string']);
$v->passes();
$this->assertEquals(['validation.required_with'], $v->errors()->get('name'));

$v = new Validator($trans, ['name' => null, 'email' => ''], ['name' => 'required_with:email|string']);
$v->passes();
$this->assertEquals(['validation.string'], $v->errors()->get('name'));

$v = new Validator($trans, [], ['name' => 'present|string']);
$v->passes();
$this->assertEquals(['validation.present'], $v->errors()->get('name'));
}

public function testValidatePresent()
{
$trans = $this->getRealTranslator();
Expand Down

0 comments on commit 5a0eb37

Please sign in to comment.