-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[8.x] Fixes array to string conversion exception when using custom validation messages for size rules #36885
[8.x] Fixes array to string conversion exception when using custom validation messages for size rules #36885
Conversation
Hmm, I don 't get the array conversion but the entire array for `between is returned instead which indeed seems wrong. I'd expect just one of them to be returned. 'custom' => [
'email' => [
'between' => [
'numeric' => 'The :attribute must be between :min and :max.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'string' => 'Some custom message here',
'array' => 'The :attribute must have between :min and :max items.',
],
],
], Route::get('/test', function () {
return Validator::make(['email' => 50], ['email' => 'between:10,30'])->errors();
})->name('test'); |
The array to string conversion comes from the line 269 on framework/src/Illuminate/Support/MessageBag.php Lines 262 to 271 in a106b93
|
@mateusjatenee why don't I get that error? |
I think you are not getting the error because, with return Validator::make(['email' => 50], ['email' => 'between:10,30'])->errors(); it does not enter the code where the exception is thrown (the line 269 of
But, if you have your views and try to register a user, for example, with this custom validation message for the email field,
|
@driesvints I think a better solution for this would be, instead of adding a new $customMessage = $this->getCustomMessageFromTranslator(
$customKey = "validation.custom.{$attribute}.{$lowerRule}"
); by this ones: $customKey = in_array($rule, $this->sizeRules)
? "validation.custom.{$attribute}.{$lowerRule}.{$this->getAttributeType($attribute)}"
: "validation.custom.{$attribute}.{$lowerRule}";
$customMessage = $this->getCustomMessageFromTranslator($customKey); I personally like this solution more because i don't have to add new methods to the class. Will change the code in a minute. |
Possible to add tests? |
@taylorotwell I'll look into it. |
@taylorotwell done. |
@taylorotwell check if you agree with me here: i think it could be a potential breaking change. Consider this code as an api validating requests and doing some stuff: Route::get('/test', function (Request $request) {
$validator = Validator::make(['email' => request('email')], ['email' => 'between:20,40']);
if ($validator->fails()) {
return response()->json($validator->errors());
} else {
// some logic here
}
}); since this exception is thrown only when you try to use the validation message in blade views, it returns a wrong validation message to the user, containing all {
"email":[
{
"numeric":"Test message for numeric",
"file":"Test message for file",
"string":"Test message for string",
"array":"Test message for array"
}
]
} if the user uses this response in his code, he will get the correct message with something like this: $response['email'][0]['string'] This PR will change the return of this validation to this: {
"email": [
"Test message for string"
]
} Now, the user can't get the validation message as before. What do you think about it? |
I honestly don't see a problem at all. Just define your custom rules like so: There would typically be no need to define one for each type for the same attribute name. An |
@taylorotwell Sorry but i do think it is a problem. I agree with you that an Better examples: if your field is called Giving the field another name in the frontend solves this problem, but i think that, since the framework allows the developer to use the same rule name for each field type with it's default messages, the custom messages should also be available that way, and renaming the field is just a workaround for solving the bug. Any chance that you reconsider this PR? |
This PR fixes a Array to string conversion exception when using custom validation messages for size rules.
When using laravel validation, you can specify custom validation messages for attributes using the convention "attribute.rule" to name the lines:
The problem is: when using size rules, such as
Between
, if you define your custom message as something like this (i used theemail
field for this test:it will cause an exception:
This occurs because the actual custom message for size rules is returned before checking if the rule being validated is a size rule or not. So, the message passed to the
Illuminate\Support\MessageBag
transform
method is this one:This PR fixes this error by adding a check for size rules before returning the custom validation message to the MessageBag class, and, if it actually is a size rule, get the message for the correct attribute type:
With this fix, the validation returns the correct message, which, in this case is
Some custom message here
.