[英]Laravel custom messages for array validation
I am having a form and I have an array of input fields for video urls, now when I validate form if I have multiple invalid fields with video urls, I get the same message for each of the invalid field, since I made my own custom messages. I don't want for each input field the same error message and I don't want the default Laravel error messages for arrays where the name of the field is shown with the error message, instead of that, I would like to have error messages with the value, in this case url written from the user. How to do that?
This is my request file with messages and rules:
public function messages(){
$messages = [
'title.required' => 'Du må ha tittel.',
'type.required' => 'Du må velge artikkeltype.',
'category.required' => 'Du må velge kategori.',
'summary.required' => 'Du må ha inngress.',
'text.required' => 'Du må ha artikkeltekst.',
'active_url' => 'Du må ha gyldig url.',
];
}
public function rules(){
$rules = [
'external_media.*' => 'active_url',
'title' => 'required',
'type' => 'required',
'category' => 'required',
'summary' => 'required',
'text' => 'required',
//'image' => 'required|image|max:20000',
];
return $rules;
}
Updated code to make the question clearer
When I have my request file like this:
public function messages(){
$messages = [
'title.required' => 'Du må ha tittel.',
'type.required' => 'Du må velge artikkeltype.',
'category.required' => 'Du må velge kategori.',
'summary.required' => 'Du må ha inngress.',
'text.required' => 'Du må ha artikkeltekst.',
'external_media.active_url' => 'Du må ha gyldig url.',
];
return $messages;
}
public function rules(){
$rules = [
'external_media.*' => 'active_url',
'title' => 'required',
'type' => 'required',
'category' => 'required',
'summary' => 'required',
'text' => 'required',
//'image' => 'required|image|max:20000',
];
return $rules;
}
I get the output:
The external_media.0 is not a valid URL.
The external_media.1 is not a valid URL.
The external_media.2 is not a valid URL.
Instead of that kind of output I would like to take the value for each of those inputs and have something like:
The htt:/asdfas.com is not a valid URL.
public function messages() {
$messages = [
'title.required' => 'Du må ha tittel.',
'type.required' => 'Du må velge artikkeltype.',
'category.required' => 'Du må velge kategori.',
'summary.required' => 'Du må ha inngress.',
'text.required' => 'Du må ha artikkeltekst.',
];
foreach ($this->get('external_media') as $key => $val) {
$messages["external_media.$key.active_url"] = "$val is not a valid active url";
}
return $messages;
}
To use a custom messages from outside the validation language file, you can use it this way:
$messages = ['username.required' => 'customeError'];
$validator = \Validator::make(
$data,
['username' => 'required'],
messages
);
You can just pass an array of your custom messages as the third parameter as I have used it above. Hope this helps.
For laravel 7.x, I have found the following solution. You can basically use 'field.rule' => 'message'
public function rules()
{
return [
'user.*.firstname' => 'string|required',
];
}
And then in the messages (I use a FormRequest for all requests):
public function messages()
{
'user.*.firstname.required' => 'Firstname of the user is required',
}
You can also pass a translation string like 'passwords.user'
to the message.
I think this will help you if you are using "name=location[]" this in your view page.
for ($i = 0; $i <= sizeof($location); $i++) {
$this->validate($request,
[
// set the rules
'location.'.$i => 'required',
'contact_no.'.$i => 'required',
'email.'.$i => 'required|email',
],
[
// set your custom error messages here
'location.'.$i.'.'.'required' => 'Contact no. is required',
'contact_no.'.$i.'.'.'required' => 'Contact no. is required',
'email.'.$i.'.'.'required' => 'Email is required',
'email.'.$i.'.'.'email' => 'Please enter valid email address'
]);
}
public function messages()
{
$messages = [];
foreach ($this->request->get('external_media') as $key => $val) {
$messages['external_media.' . $key . '.active_url'] = 'The '.$val .' is not a valid URL.'
}
return $messages;
}
'external_media.*.required' => 'active_url',
Edit with potential solution
After some digging around, I've had a look at the Validator
class and how it is adding it's error messages to see if it has any available placeholders.
In the Illuminate\Validation\Validator
the function that I think is run to validate a request is validate
, which runs each of the rules in turn and adds error messages. The piece of code related to adding an error message is this one, at the end of the function:
$value = $this->getValue($attribute);
$validatable = $this->isValidatable($rule, $attribute, $value);
$method = "validate{$rule}";
if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) {
$this->addFailure($attribute, $rule, $parameters);
}
As you can see, it's not actually passing the value of the field that was validated through when it's adding a failure, which in turn adds an error message.
I've managed to get something working to achieve what you're after. If you add these two methods into your base Request
class which is usually at App\Http\Requests\Request
:
protected function formatErrors(Validator $validator)
{
$errors = parent::formatErrors($validator);
foreach ($errors as $attribute => $eachError) {
foreach ($eachError as $key => $error) {
if (strpos($error, ':value') !== false) {
$errors[$attribute][$key] = str_replace(':value', $this->getValueByAttribute($attribute), $error);
}
}
}
return $errors;
}
protected function getValueByAttribute($attribute)
{
if (($dotPosition = strpos($attribute, '.')) !== false) {
$name = substr($attribute, 0, $dotPosition);
$index = substr($attribute, $dotPosition + 1);
return $this->get($name)[$index];
}
return $this->get($attribute);
}
Then in your validation messages you should be able to put the :value
replacer, which should be replaced with the actual value that was validated, like this:
public function messages()
{
return [
'external_media.*.active_url' => 'The URL :value is not valid'
];
}
I've noticed a couple of problems with your code:
messages
function you've provided a message for active_url
which is the name of the rule, rather than the name of the field. This should be external_media
.$messages
variable from your messages
function. You need to add return $messages;
to the end.With regards to your question however, the class in which you write this code is an instance of Illuminate\Http\Request
and you should be able to access the actual values provided to that request when generating your error messages. For example, you could do something like this:
public function messages()
{
return [
'external_media' => 'The following URL is invalid: ' . $this->get('external_media')
];
}
public function rules()
{
return [
'external_media' => 'active_url'
];
}
Which would include the value provided to external_media
in the error message. Hope this helps.
You can using Customizing The Error Format
protected function formatErrors(Validator $validator)
{
$results = [];
$flag = false;
$messages = $validator->errors()->messages();
foreach ($messages as $key => $value) {
if (!str_contains($key, 'external_media') || !$flag) {
$results[] = $value[0];
}
if (str_contains($key, 'external_media') && !$flag) {
$flag = true;
}
}
return $results;
}
This works fine for me in laravel 5.5
$request->validate([
'files.*' => 'required|mimes:jpeg,png,jpg,gif,pdf,doc|max:10000'
],
[
'files.*.mimes' => 'Los archivos solo pueden estar con formato: jpeg, png, jpg, gif, pdf, doc.',
]
);
You can use as
$messages = [
'title.required' => 'Du må ha tittel.',
'type.required' => 'Du må velge artikkeltype.',
'category.required' => 'Du må velge kategori.',
'summary.required' => 'Du må ha inngress.',
'text.required' => 'Du må ha artikkeltekst.',
'active_url' => 'Du må ha gyldig url.',
];
$validator = Validator::make($data, [
'external_media.*' => 'active_url',
'title' => 'required',
'type' => 'required',
'category' => 'required',
'summary' => 'required',
'text' => 'required',
//'image' => 'required|image|max:20000'
], $messages);
if ($validator->fails()){
// handle validation error
} else {
// no validation error found
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.