Skip to content

Commit

Permalink
[8.x] Add ValidatorAwareRule interface (#37442)
Browse files Browse the repository at this point in the history
* Add ValidatorAwareRule interface

* Update Validator.php

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
bastien-phi and taylorotwell committed May 21, 2021
1 parent c2204de commit f80e1e5
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/Illuminate/Contracts/Validation/ValidatorAwareRule.php
@@ -0,0 +1,14 @@
<?php

namespace Illuminate\Contracts\Validation;

interface ValidatorAwareRule
{
/**
* Set the current validator.
*
* @param \Illuminate\Validation\Validator $validator
* @return $this
*/
public function setValidator($validator);
}
5 changes: 5 additions & 0 deletions src/Illuminate/Validation/Validator.php
Expand Up @@ -9,6 +9,7 @@
use Illuminate\Contracts\Validation\ImplicitRule;
use Illuminate\Contracts\Validation\Rule as RuleContract;
use Illuminate\Contracts\Validation\Validator as ValidatorContract;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Illuminate\Support\Arr;
use Illuminate\Support\Fluent;
use Illuminate\Support\MessageBag;
Expand Down Expand Up @@ -749,6 +750,10 @@ protected function validateUsingCustomRule($attribute, $value, $rule)

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

if ($rule instanceof ValidatorAwareRule) {
$rule->setValidator($this);
}

if ($rule instanceof DataAwareRule) {
$rule->setData($this->data);
}
Expand Down
113 changes: 113 additions & 0 deletions tests/Validation/ValidationValidatorTest.php
Expand Up @@ -13,6 +13,7 @@
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ImplicitRule;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
Expand Down Expand Up @@ -5357,6 +5358,118 @@ public function message()

$this->assertTrue($v->fails());
$this->assertSame('The password confirmation does not match.', $v->errors()->get('password')[0]);

// Test access to the validator
$v = new Validator(
$this->getIlluminateArrayTranslator(),
['base' => 21, 'double' => 42],
[
'base' => ['integer'],
'double' => [
'integer',
new class implements Rule, ValidatorAwareRule
{
protected $validator;

public function setValidator($validator)
{
$this->validator = $validator;
}

public function passes($attribute, $value)
{
if ($this->validator->errors()->hasAny(['base', $attribute])) {
return true;
}

return $value === 2 * $this->validator->getData()['base'];
}

public function message()
{
return ['The :attribute must be the double of base.'];
}
},
],
]
);

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

$v = new Validator(
$this->getIlluminateArrayTranslator(),
['base' => 21, 'double' => 10],
[
'base' => ['integer'],
'double' => [
'integer',
new class implements Rule, ValidatorAwareRule
{
protected $validator;

public function setValidator($validator)
{
$this->validator = $validator;
}

public function passes($attribute, $value)
{
if ($this->validator->errors()->hasAny(['base', $attribute])) {
return true;
}

return $value === 2 * $this->validator->getData()['base'];
}

public function message()
{
return ['The :attribute must be the double of base.'];
}
},
],
]
);

$this->assertTrue($v->fails());
$this->assertSame('The double must be the double of base.', $v->errors()->get('double')[0]);

$v = new Validator(
$this->getIlluminateArrayTranslator(),
['base' => 21, 'double' => 'foo'],
[
'base' => ['integer'],
'double' => [
'integer',
new class implements Rule, ValidatorAwareRule
{
protected $validator;

public function setValidator($validator)
{
$this->validator = $validator;
}

public function passes($attribute, $value)
{
if ($this->validator->errors()->hasAny(['base', $attribute])) {
return true;
}

return $value === 2 * $this->validator->getData()['base'];
}

public function message()
{
return ['The :attribute must be the double of base.'];
}
},
],
]
);

$this->assertTrue($v->fails());
$this->assertCount(1, $v->errors()->get('double'));
$this->assertSame('validation.integer', $v->errors()->get('double')[0]);
}

public function testCustomValidationObjectWithDotKeysIsCorrectlyPassedValue()
Expand Down

0 comments on commit f80e1e5

Please sign in to comment.