Skip to content

Commit 3f1b0a2

Browse files
nshirotaylorotwell
andauthored
[9.x] Allow invokable rules to specify custom messsages (#43925)
* [9.x] Allow invokable rules to specify custom messsages * StyleCI * Update InvokableValidationRule.php Co-authored-by: Taylor Otwell <[email protected]>
1 parent e07e005 commit 3f1b0a2

File tree

3 files changed

+98
-4
lines changed

3 files changed

+98
-4
lines changed

src/Illuminate/Validation/InvokableValidationRule.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ public function passes($attribute, $value)
103103
return ! $this->failed;
104104
}
105105

106+
/**
107+
* Get the underlying invokable rule.
108+
*
109+
* @return \Illuminate\Contracts\Validation\InvokableRule
110+
*/
111+
public function invokable()
112+
{
113+
return $this->invokable;
114+
}
115+
106116
/**
107117
* Get the validation error messages.
108118
*

src/Illuminate/Validation/Validator.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -810,17 +810,21 @@ protected function validateUsingCustomRule($attribute, $value, $rule)
810810
}
811811

812812
if (! $rule->passes($attribute, $value)) {
813-
$this->failedRules[$attribute][get_class($rule)] = [];
813+
$ruleClass = $rule instanceof InvokableValidationRule ?
814+
get_class($rule->invokable()) :
815+
get_class($rule);
814816

815-
$messages = $this->getFromLocalArray($attribute, get_class($rule)) ?? $rule->message();
817+
$this->failedRules[$attribute][$ruleClass] = [];
816818

817-
$messages = $messages ? (array) $messages : [get_class($rule)];
819+
$messages = $this->getFromLocalArray($attribute, $ruleClass) ?? $rule->message();
820+
821+
$messages = $messages ? (array) $messages : [$ruleClass];
818822

819823
foreach ($messages as $key => $message) {
820824
$key = is_string($key) ? $key : $attribute;
821825

822826
$this->messages->add($key, $this->makeReplacements(
823-
$message, $key, get_class($rule), []
827+
$message, $key, $ruleClass, []
824828
));
825829
}
826830
}

tests/Validation/ValidationInvokableRuleTest.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Contracts\Validation\ValidatorAwareRule;
88
use Illuminate\Translation\ArrayLoader;
99
use Illuminate\Translation\Translator;
10+
use Illuminate\Validation\InvokableValidationRule;
1011
use Illuminate\Validation\Validator;
1112
use PHPUnit\Framework\TestCase;
1213

@@ -333,6 +334,85 @@ public function __invoke($attribute, $value, $fail)
333334
], $validator->messages()->messages());
334335
}
335336

337+
public function testExplicitRuleCanUseInlineValidationMessages()
338+
{
339+
$trans = $this->getIlluminateArrayTranslator();
340+
$rule = new class() implements InvokableRule
341+
{
342+
public $implicit = false;
343+
344+
public function __invoke($attribute, $value, $fail)
345+
{
346+
$fail('xxxx');
347+
}
348+
};
349+
350+
$validator = new Validator($trans, ['foo' => 'bar'], ['foo' => $rule], [$rule::class => ':attribute custom.']);
351+
352+
$this->assertFalse($validator->passes());
353+
$this->assertSame([
354+
'foo' => [
355+
'foo custom.',
356+
],
357+
], $validator->messages()->messages());
358+
359+
$validator = new Validator($trans, ['foo' => 'bar'], ['foo' => $rule], ['foo.'.$rule::class => ':attribute custom with key.']);
360+
361+
$this->assertFalse($validator->passes());
362+
$this->assertSame([
363+
'foo' => [
364+
'foo custom with key.',
365+
],
366+
], $validator->messages()->messages());
367+
}
368+
369+
public function testImplicitRuleCanUseInlineValidationMessages()
370+
{
371+
$trans = $this->getIlluminateArrayTranslator();
372+
$rule = new class() implements InvokableRule
373+
{
374+
public $implicit = true;
375+
376+
public function __invoke($attribute, $value, $fail)
377+
{
378+
$fail('xxxx');
379+
}
380+
};
381+
382+
$validator = new Validator($trans, ['foo' => ''], ['foo' => $rule], [$rule::class => ':attribute custom.']);
383+
384+
$this->assertFalse($validator->passes());
385+
$this->assertSame([
386+
'foo' => [
387+
'foo custom.',
388+
],
389+
], $validator->messages()->messages());
390+
391+
$validator = new Validator($trans, ['foo' => ''], ['foo' => $rule], ['foo.'.$rule::class => ':attribute custom with key.']);
392+
393+
$this->assertFalse($validator->passes());
394+
$this->assertSame([
395+
'foo' => [
396+
'foo custom with key.',
397+
],
398+
], $validator->messages()->messages());
399+
}
400+
401+
public function testItCanReturnInvokableRule()
402+
{
403+
$rule = new class() implements InvokableRule
404+
{
405+
public function __invoke($attribute, $value, $fail)
406+
{
407+
$fail('xxxx');
408+
}
409+
};
410+
411+
$invokableValidationRule = InvokableValidationRule::make($rule);
412+
413+
$this->assertSame($rule, $invokableValidationRule->invokable());
414+
}
415+
336416
private function getIlluminateArrayTranslator()
337417
{
338418
return new Translator(

0 commit comments

Comments
 (0)