Skip to content

Commit fb9dae5

Browse files
authored
Allow validator message placeholers to be capitalized (#57556)
1 parent da484d3 commit fb9dae5

File tree

2 files changed

+216
-11
lines changed

2 files changed

+216
-11
lines changed

src/Illuminate/Validation/Concerns/ReplacesAttributes.php

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Illuminate\Validation\Concerns;
44

55
use Illuminate\Support\Arr;
6+
use Illuminate\Support\Str;
67

78
trait ReplacesAttributes
89
{
@@ -21,7 +22,11 @@ protected function replaceAcceptedIf($message, $attribute, $rule, $parameters)
2122

2223
$parameters[0] = $this->getDisplayableAttribute($parameters[0]);
2324

24-
return str_replace([':other', ':value'], $parameters, $message);
25+
return str_replace(
26+
[':other', ':OTHER', ':Other', ':value', ':VALUE', ':Value'],
27+
[$parameters[0], Str::upper($parameters[0]), Str::ucfirst($parameters[0]), $parameters[1], Str::upper($parameters[1]), Str::ucfirst($parameters[1])],
28+
$message
29+
);
2530
}
2631

2732
/**
@@ -240,7 +245,15 @@ protected function replaceMissingUnless($message, $attribute, $rule, $parameters
240245
*/
241246
protected function replaceMissingWith($message, $attribute, $rule, $parameters)
242247
{
243-
return str_replace(':values', implode(' / ', $this->getAttributeList($parameters)), $message);
248+
return str_replace(
249+
[':values', ':VALUES', ':Values'],
250+
[
251+
implode(' / ', $this->getAttributeList($parameters)),
252+
Str::upper(implode(' / ', $this->getAttributeList($parameters))),
253+
implode(' / ', array_map(Str::ucfirst(...), $this->getAttributeList($parameters))),
254+
],
255+
$message
256+
);
244257
}
245258

246259
/**
@@ -286,7 +299,15 @@ protected function replaceIn($message, $attribute, $rule, $parameters)
286299
$parameter = $this->getDisplayableValue($attribute, $parameter);
287300
}
288301

289-
return str_replace(':values', implode(', ', $parameters), $message);
302+
return str_replace(
303+
[':values', ':VALUES', ':Values'],
304+
[
305+
implode(', ', $parameters),
306+
Str::upper(implode(', ', $parameters)),
307+
implode(', ', array_map(Str::ucfirst(...), $parameters)),
308+
],
309+
$message,
310+
);
290311
}
291312

292313
/**
@@ -314,7 +335,13 @@ protected function replaceNotIn($message, $attribute, $rule, $parameters)
314335
*/
315336
protected function replaceInArray($message, $attribute, $rule, $parameters)
316337
{
317-
return str_replace(':other', $this->getDisplayableAttribute($parameters[0]), $message);
338+
$value = $this->getDisplayableAttribute($parameters[0]);
339+
340+
return str_replace(
341+
[':other', ':OTHER', ':Other'],
342+
[$value, Str::upper($value), Str::ucfirst($value)],
343+
$message
344+
);
318345
}
319346

320347
/**
@@ -412,7 +439,15 @@ protected function replacePresentUnless($message, $attribute, $rule, $parameters
412439
*/
413440
protected function replacePresentWith($message, $attribute, $rule, $parameters)
414441
{
415-
return str_replace(':values', implode(' / ', $this->getAttributeList($parameters)), $message);
442+
return str_replace(
443+
[':values', ':VALUES', ':Values'],
444+
[
445+
implode(' / ', $this->getAttributeList($parameters)),
446+
Str::upper(implode(' / ', $this->getAttributeList($parameters))),
447+
implode(' / ', array_map(Str::ucfirst(...), $this->getAttributeList($parameters))),
448+
],
449+
$message,
450+
);
416451
}
417452

418453
/**
@@ -440,7 +475,15 @@ protected function replacePresentWithAll($message, $attribute, $rule, $parameter
440475
*/
441476
protected function replaceRequiredWith($message, $attribute, $rule, $parameters)
442477
{
443-
return str_replace(':values', implode(' / ', $this->getAttributeList($parameters)), $message);
478+
return str_replace(
479+
[':values', ':VALUES', ':Values'],
480+
[
481+
implode(' / ', $this->getAttributeList($parameters)),
482+
Str::upper(implode(' / ', $this->getAttributeList($parameters))),
483+
implode(' / ', array_map(Str::ucfirst(...), $this->getAttributeList($parameters))),
484+
],
485+
$message,
486+
);
444487
}
445488

446489
/**
@@ -584,9 +627,13 @@ protected function replaceRequiredIf($message, $attribute, $rule, $parameters)
584627
*/
585628
protected function replaceRequiredIfAccepted($message, $attribute, $rule, $parameters)
586629
{
587-
$parameters[0] = $this->getDisplayableAttribute($parameters[0]);
630+
$value = $this->getDisplayableAttribute($parameters[0]);
588631

589-
return str_replace([':other'], $parameters, $message);
632+
return str_replace(
633+
[':other', ':OTHER', ':Other'],
634+
[$value, Str::upper($value), Str::ucfirst($value)],
635+
$message
636+
);
590637
}
591638

592639
/**
@@ -622,7 +669,18 @@ protected function replaceRequiredUnless($message, $attribute, $rule, $parameter
622669
$values[] = $this->getDisplayableValue($parameters[0], $value);
623670
}
624671

625-
return str_replace([':other', ':values'], [$other, implode(', ', $values)], $message);
672+
return str_replace(
673+
[':other', ':OTHER', ':Other', ':values', ':VALUES', ':Values'],
674+
[
675+
$other,
676+
Str::upper($other),
677+
Str::ucfirst($other),
678+
implode(', ', $values),
679+
Str::upper(implode(', ', $values)),
680+
implode(', ', array_map(Str::ucfirst(...), $values)),
681+
],
682+
$message
683+
);
626684
}
627685

628686
/**
@@ -692,7 +750,15 @@ protected function replaceProhibitedUnless($message, $attribute, $rule, $paramet
692750
*/
693751
protected function replaceProhibits($message, $attribute, $rule, $parameters)
694752
{
695-
return str_replace(':other', implode(' / ', $this->getAttributeList($parameters)), $message);
753+
return str_replace(
754+
[':other', ':OTHER', ':Other'],
755+
[
756+
implode(' / ', $this->getAttributeList($parameters)),
757+
Str::upper(implode(' / ', $this->getAttributeList($parameters))),
758+
implode(' / ', array_map(Str::ucfirst(...), $this->getAttributeList($parameters))),
759+
],
760+
$message
761+
);
696762
}
697763

698764
/**
@@ -706,7 +772,13 @@ protected function replaceProhibits($message, $attribute, $rule, $parameters)
706772
*/
707773
protected function replaceSame($message, $attribute, $rule, $parameters)
708774
{
709-
return str_replace(':other', $this->getDisplayableAttribute($parameters[0]), $message);
775+
$value = $this->getDisplayableAttribute($parameters[0]);
776+
777+
return str_replace(
778+
[':other', ':OTHER', ':Other'],
779+
[$value, Str::upper($value), Str::ucfirst($value)],
780+
$message
781+
);
710782
}
711783

712784
/**

tests/Validation/ValidationValidatorTest.php

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,139 @@ public function testInputIsReplaced()
622622
$this->assertSame('empty is not a valid email', $v->messages()->first('email'));
623623
}
624624

625+
public function testCapitalizedDisplayableValuesAreReplaced()
626+
{
627+
// accepted_if
628+
$trans = $this->getIlluminateArrayTranslator();
629+
$trans->addLines(['validation.accepted_if' => 'The :attribute field must be accepted when :Other is :Value.'], 'en');
630+
$v = new Validator($trans, ['foo' => 'no', 'bar' => 'aaa'], ['foo' => 'accepted_if:bar,aaa']);
631+
$this->assertFalse($v->passes());
632+
$v->messages()->setFormat(':message');
633+
$this->assertSame('The foo field must be accepted when Bar is Aaa.', $v->messages()->first('foo'));
634+
635+
$trans = $this->getIlluminateArrayTranslator();
636+
$trans->addLines(['validation.accepted_if' => 'The :attribute field must be accepted when :OTHER is :VALUE.'], 'en');
637+
$v = new Validator($trans, ['foo' => 'no', 'bar' => 'aaa'], ['foo' => 'accepted_if:bar,aaa']);
638+
$this->assertFalse($v->passes());
639+
$v->messages()->setFormat(':message');
640+
$this->assertSame('The foo field must be accepted when BAR is AAA.', $v->messages()->first('foo'));
641+
642+
// in_array
643+
$trans = $this->getIlluminateArrayTranslator();
644+
$trans->addLines(['validation.in_array' => 'The value of :attribute does not exist in :Other.'], 'en');
645+
$v = new Validator($trans, ['foo' => [1, 2, 3], 'bar' => [1, 2]], ['foo.*' => 'in_array:bar.*']);
646+
$this->assertSame('The value of foo.2 does not exist in Bar.*.', $v->messages()->first('foo.2'));
647+
648+
$trans = $this->getIlluminateArrayTranslator();
649+
$trans->addLines(['validation.in_array' => 'The value of :attribute does not exist in :OTHER.'], 'en');
650+
$v = new Validator($trans, ['foo' => [1, 2, 3], 'bar' => [1, 2]], ['foo.*' => 'in_array:bar.*']);
651+
$this->assertSame('The value of foo.2 does not exist in BAR.*.', $v->messages()->first('foo.2'));
652+
653+
// missing_with
654+
$trans = $this->getIlluminateArrayTranslator();
655+
$trans->addLines(['validation.missing_with' => 'The :attribute field must be missing when :Values is present.'], 'en');
656+
$v = new Validator($trans, ['foo' => [], 'bar' => '2'], ['foo' => 'missing_with:baz,bar']);
657+
$this->assertFalse($v->passes());
658+
$this->assertSame('The foo field must be missing when Baz / Bar is present.', $v->errors()->first('foo'));
659+
660+
$trans = $this->getIlluminateArrayTranslator();
661+
$trans->addLines(['validation.missing_with' => 'The :attribute field must be missing when :VALUES is present.'], 'en');
662+
$v = new Validator($trans, ['foo' => [], 'bar' => '2'], ['foo' => 'missing_with:baz,bar']);
663+
$this->assertFalse($v->passes());
664+
$this->assertSame('The foo field must be missing when BAZ / BAR is present.', $v->errors()->first('foo'));
665+
666+
// present_with
667+
$trans = $this->getIlluminateArrayTranslator();
668+
$trans->addLines(['validation.present_with' => 'The :attribute field must be present when :Values is present.'], 'en');
669+
$v = new Validator($trans, ['bar' => 2, 'baz' => 2], ['foo' => 'present_with:bar,baz']);
670+
$this->assertFalse($v->passes());
671+
$this->assertSame('The foo field must be present when Bar / Baz is present.', $v->errors()->first('foo'));
672+
673+
$trans = $this->getIlluminateArrayTranslator();
674+
$trans->addLines(['validation.present_with' => 'The :attribute field must be present when :VALUES is present.'], 'en');
675+
$v = new Validator($trans, ['bar' => 2, 'baz' => 2], ['foo' => 'present_with:bar,baz']);
676+
$this->assertFalse($v->passes());
677+
$this->assertSame('The foo field must be present when BAR / BAZ is present.', $v->errors()->first('foo'));
678+
679+
// prohibits
680+
$trans = $this->getIlluminateArrayTranslator();
681+
$trans->addLines(['validation.prohibits' => 'The :attribute field prohibits :Other being present.'], 'en');
682+
$v = new Validator($trans, ['email' => 'foo', 'emails' => 'bar', 'email_address' => 'baz'], ['email' => 'prohibits:emails,email_address']);
683+
$this->assertFalse($v->passes());
684+
$this->assertSame('The email field prohibits Emails / Email address being present.', $v->messages()->first('email'));
685+
686+
$trans = $this->getIlluminateArrayTranslator();
687+
$trans->addLines(['validation.prohibits' => 'The :attribute field prohibits :OTHER being present.'], 'en');
688+
$v = new Validator($trans, ['email' => 'foo', 'emails' => 'bar', 'email_address' => 'baz'], ['email' => 'prohibits:emails,email_address']);
689+
$this->assertFalse($v->passes());
690+
$this->assertSame('The email field prohibits EMAILS / EMAIL ADDRESS being present.', $v->messages()->first('email'));
691+
692+
// required_if_accepted
693+
$trans = $this->getIlluminateArrayTranslator();
694+
$trans->addLines(['validation.required_if_accepted' => 'The :attribute field is required when :Other is accepted.'], 'en');
695+
$v = new Validator($trans, ['foo' => 'yes', 'bar' => ''], ['bar' => 'required_if_accepted:foo']);
696+
$this->assertFalse($v->passes());
697+
$this->assertSame('The bar field is required when Foo is accepted.', $v->messages()->first('bar'));
698+
699+
$trans = $this->getIlluminateArrayTranslator();
700+
$trans->addLines(['validation.required_if_accepted' => 'The :attribute field is required when :OTHER is accepted.'], 'en');
701+
$v = new Validator($trans, ['foo' => 'yes', 'bar' => ''], ['bar' => 'required_if_accepted:foo']);
702+
$this->assertFalse($v->passes());
703+
$this->assertSame('The bar field is required when FOO is accepted.', $v->messages()->first('bar'));
704+
705+
// required_unless
706+
$trans = $this->getIlluminateArrayTranslator();
707+
$trans->addLines(['validation.required_unless' => 'The :attribute field is required unless :Other is in :Values.'], 'en');
708+
$v = new Validator($trans, ['first' => 'dayle', 'last' => ''], ['last' => 'RequiredUnless:first,taylor,sven']);
709+
$this->assertFalse($v->passes());
710+
$this->assertSame('The last field is required unless First is in Taylor, Sven.', $v->messages()->first('last'));
711+
712+
$trans = $this->getIlluminateArrayTranslator();
713+
$trans->addLines(['validation.required_unless' => 'The :attribute field is required unless :OTHER is in :VALUES.'], 'en');
714+
$v = new Validator($trans, ['first' => 'dayle', 'last' => ''], ['last' => 'RequiredUnless:first,taylor,sven']);
715+
$this->assertFalse($v->passes());
716+
$this->assertSame('The last field is required unless FIRST is in TAYLOR, SVEN.', $v->messages()->first('last'));
717+
718+
// required_with
719+
$trans = $this->getIlluminateArrayTranslator();
720+
$trans->addLines(['validation.required_with' => 'The :attribute field is required when :Values is present.'], 'en');
721+
$v = new Validator($trans, ['first' => 'Taylor', 'last' => ''], ['last' => 'required_with:first']);
722+
$this->assertFalse($v->passes());
723+
$this->assertSame('The last field is required when First is present.', $v->messages()->first('last'));
724+
725+
$trans = $this->getIlluminateArrayTranslator();
726+
$trans->addLines(['validation.required_with' => 'The :attribute field is required when :VALUES is present.'], 'en');
727+
$v = new Validator($trans, ['first' => 'Taylor', 'last' => ''], ['last' => 'required_with:first']);
728+
$this->assertFalse($v->passes());
729+
$this->assertSame('The last field is required when FIRST is present.', $v->messages()->first('last'));
730+
731+
// same
732+
$trans = $this->getIlluminateArrayTranslator();
733+
$trans->addLines(['validation.same' => 'The :attribute field must match :Other.'], 'en');
734+
$v = new Validator($trans, ['foo' => 'bar', 'baz' => 'boom'], ['foo' => 'Same:baz']);
735+
$this->assertFalse($v->passes());
736+
$this->assertSame('The foo field must match Baz.', $v->messages()->first('foo'));
737+
738+
$trans = $this->getIlluminateArrayTranslator();
739+
$trans->addLines(['validation.same' => 'The :attribute field must match :OTHER.'], 'en');
740+
$v = new Validator($trans, ['foo' => 'bar', 'baz' => 'boom'], ['foo' => 'Same:baz']);
741+
$this->assertFalse($v->passes());
742+
$this->assertSame('The foo field must match BAZ.', $v->messages()->first('foo'));
743+
744+
// starts_with
745+
$trans = $this->getIlluminateArrayTranslator();
746+
$trans->addLines(['validation.starts_with' => 'The :attribute must start with one of the following values :Values'], 'en');
747+
$v = new Validator($trans, ['url' => 'laravel.com'], ['url' => 'starts_with:http,https']);
748+
$this->assertFalse($v->passes());
749+
$this->assertSame('The url must start with one of the following values Http, Https', $v->messages()->first('url'));
750+
751+
$trans = $this->getIlluminateArrayTranslator();
752+
$trans->addLines(['validation.starts_with' => 'The :attribute must start with one of the following values :VALUES'], 'en');
753+
$v = new Validator($trans, ['url' => 'laravel.com'], ['url' => 'starts_with:http,https']);
754+
$this->assertFalse($v->passes());
755+
$this->assertSame('The url must start with one of the following values HTTP, HTTPS', $v->messages()->first('url'));
756+
}
757+
625758
public function testInputIsReplacedByItsDisplayableValue()
626759
{
627760
$frameworks = [

0 commit comments

Comments
 (0)