Skip to content

Commit a670753

Browse files
committed
Allow custom messages to be registered when using Validator::extend
1 parent 2682001 commit a670753

5 files changed

Lines changed: 89 additions & 13 deletions

File tree

src/Illuminate/Foundation/changes.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
{"message": "Added assertHasOldInput test assertion.", "backport": null},
5757
{"message": "Added slick new 'sometimes' method to Validator for conditionally adding rules.", "backport": null},
5858
{"message": "Added new '--sleep' option to queue:listen command to control time between jobs.", "backport": null},
59-
{"message": "Allow Blade processing on echos to be escaped using the @ sign.", "backport": null}
59+
{"message": "Allow Blade processing on echos to be escaped using the @ sign.", "backport": null},
60+
{"message": "Allow custom messages to be registered when using Validator::extend.", "backport": null}
6061
]
6162
}

src/Illuminate/Validation/Factory.php

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ class Factory {
4141
*/
4242
protected $implicitExtensions = array();
4343

44+
/**
45+
* All of the fallback messages for custom rules.
46+
*
47+
* @var array
48+
*/
49+
protected $fallbackMessages = array();
50+
4451
/**
4552
* The Validator resolver instance.
4653
*
@@ -89,6 +96,19 @@ public function make(array $data, array $rules, array $messages = array())
8996
$validator->setContainer($this->container);
9097
}
9198

99+
$this->addExtensions($validator);
100+
101+
return $validator;
102+
}
103+
104+
/**
105+
* Add the extensions to a validator instance.
106+
*
107+
* @param \Illuminate\Validation\Validator $validator
108+
* @return void
109+
*/
110+
protected function addExtensions($validator)
111+
{
92112
$validator->addExtensions($this->extensions);
93113

94114
// Next, we will add the implicit extensions, which are similar to the required
@@ -98,7 +118,7 @@ public function make(array $data, array $rules, array $messages = array())
98118

99119
$validator->addImplicitExtensions($implicit);
100120

101-
return $validator;
121+
$validator->setFallbackMessages($this->fallbackMessages);
102122
}
103123

104124
/**
@@ -126,23 +146,29 @@ protected function resolve($data, $rules, $messages)
126146
*
127147
* @param string $rule
128148
* @param Closure|string $extension
149+
* @param string $message
129150
* @return void
130151
*/
131-
public function extend($rule, $extension)
152+
public function extend($rule, $extension, $message = null)
132153
{
133154
$this->extensions[$rule] = $extension;
155+
156+
if ($message) $this->fallbackMessages[strtolower(snake_case($rule))] = $message;
134157
}
135158

136159
/**
137160
* Register a custom implicit validator extension.
138161
*
139162
* @param string $rule
140163
* @param Closure $extension
164+
* @param string $message
141165
* @return void
142166
*/
143-
public function extendImplicit($rule, Closure $extension)
167+
public function extendImplicit($rule, Closure $extension, $message = null)
144168
{
145169
$this->implicitExtensions[$rule] = $extension;
170+
171+
if ($message) $this->fallbackMessages[strtolower(snake_case($rule))] = $message;
146172
}
147173

148174
/**

src/Illuminate/Validation/Validator.php

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ class Validator implements MessageProviderInterface {
6868
*/
6969
protected $customMessages = array();
7070

71+
/**
72+
* The array of fallback error messages.
73+
*
74+
* @var array
75+
*/
76+
protected $fallbackMessages = array();
77+
7178
/**
7279
* The array of custom attribute names.
7380
*
@@ -1094,34 +1101,38 @@ protected function getMessage($attribute, $rule)
10941101
// Finally, if no developer specified messages have been set, and no other
10951102
// special messages apply for this rule, we will just pull the default
10961103
// messages out of the translator service for this validation rule.
1097-
else
1098-
{
1099-
$key = "validation.{$lowerRule}";
1104+
$key = "validation.{$lowerRule}";
11001105

1101-
return $this->translator->trans($key);
1106+
if ($key != ($value = $this->translator->trans($key)))
1107+
{
1108+
return $value;
11021109
}
1110+
1111+
return $this->getInlineMessage(
1112+
$attribute, $lowerRule, $this->fallbackMessages
1113+
) ?: $key;
11031114
}
11041115

11051116
/**
11061117
* Get the inline message for a rule if it exists.
11071118
*
11081119
* @param string $attribute
11091120
* @param string $lowerRule
1121+
* @param array $source
11101122
* @return string
11111123
*/
1112-
protected function getInlineMessage($attribute, $lowerRule)
1124+
protected function getInlineMessage($attribute, $lowerRule, $source = null)
11131125
{
1126+
$source = $source ?: $this->customMessages;
1127+
11141128
$keys = array("{$attribute}.{$lowerRule}", $lowerRule);
11151129

11161130
// First we will check for a custom message for an attribute specific rule
11171131
// message for the fields, then we will check for a general custom line
11181132
// that is not attribute specific. If we find either we'll return it.
11191133
foreach ($keys as $key)
11201134
{
1121-
if (isset($this->customMessages[$key]))
1122-
{
1123-
return $this->customMessages[$key];
1124-
}
1135+
if (isset($source[$key])) return $source[$key];
11251136
}
11261137
}
11271138

@@ -1764,6 +1775,27 @@ public function setCustomMessages(array $messages)
17641775
$this->customMessages = array_merge($this->customMessages, $messages);
17651776
}
17661777

1778+
/**
1779+
* Get the fallback messages for the validator.
1780+
*
1781+
* @return void
1782+
*/
1783+
public function getFallbackMessages()
1784+
{
1785+
return $this->fallbackMessages;
1786+
}
1787+
1788+
/**
1789+
* Set the fallback messages for the validator.
1790+
*
1791+
* @param array $messages
1792+
* @return void
1793+
*/
1794+
public function setFallbackMessages(array $messages)
1795+
{
1796+
$this->fallbackMessages = $messages;
1797+
}
1798+
17671799
/**
17681800
* Get the failed validation rules.
17691801
*

tests/Validation/ValidationFactoryTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ public function testMakeMethodCreatesValidValidator()
2727
$validator = $factory->make(array(), array());
2828
$this->assertEquals(array('foo' => function() {}, 'implicit' => function() {}), $validator->getExtensions());
2929
$this->assertEquals($presence, $validator->getPresenceVerifier());
30+
31+
$presence = m::mock('Illuminate\Validation\PresenceVerifierInterface');
32+
$factory->extend('foo', function() {}, 'foo!');
33+
$factory->extendImplicit('implicit', function() {}, 'implicit!');
34+
$factory->setPresenceVerifier($presence);
35+
$validator = $factory->make(array(), array());
36+
$this->assertEquals(array('foo' => function() {}, 'implicit' => function() {}), $validator->getExtensions());
37+
$this->assertEquals(array('foo' => 'foo!', 'implicit' => 'implicit!'), $validator->getFallbackMessages());
38+
$this->assertEquals($presence, $validator->getPresenceVerifier());
3039
}
3140

3241

tests/Validation/ValidationValidatorTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,14 @@ public function testCustomValidators()
795795
$this->assertFalse($v->passes());
796796
$v->messages()->setFormat(':message');
797797
$this->assertEquals('foo!', $v->messages()->first('name'));
798+
799+
$trans = $this->getRealTranslator();
800+
$v = new Validator($trans, array('name' => 'taylor'), array('name' => 'foo_bar'));
801+
$v->addExtension('FooBar', function() { return false; });
802+
$v->setFallbackMessages(array('foo_bar' => 'foo!'));
803+
$this->assertFalse($v->passes());
804+
$v->messages()->setFormat(':message');
805+
$this->assertEquals('foo!', $v->messages()->first('name'));
798806
}
799807

800808

0 commit comments

Comments
 (0)