diff --git a/src/Illuminate/Contracts/Validation/ValidatorAwareRule.php b/src/Illuminate/Contracts/Validation/ValidatorAwareRule.php new file mode 100644 index 000000000000..053f4fa8b676 --- /dev/null +++ b/src/Illuminate/Contracts/Validation/ValidatorAwareRule.php @@ -0,0 +1,14 @@ +replacePlaceholders($value) : $value; + if ($rule instanceof ValidatorAwareRule) { + $rule->setValidator($this); + } + if ($rule instanceof DataAwareRule) { $rule->setData($this->data); } diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index 31d55c1488d5..0e2f22b1fdcc 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -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; @@ -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()