laravel 5 validation custom error message not appear - laravel

I want to show the custom validation error message if user upload an image size of more than 4 MB. However, once submitted with an image of like above 4MB, it shows the default error message : "The file name failed to upload.". Below is my code in the controller:
$messages = [
'fileName' => 'Image maximum size exceed. ',
];
$validator = Validator::make($request->all(), [
'fileName' => 'max:4096',
], $messages);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator->errors());
}
Here is the HTML code in the blade file:
<input type="file" name="fileName">

I know this is an old question but I have to post this answer here. This was what worked for me
$messages = [
'fileName.uploaded' => 'Image maximum size exceed. ',
];

I used this line:
return redirect()->back()->withErrors($validator->customMessages);
and it solved the problem.

Related

Laravel validation messages contain "validation." instead of custom error message

I have a function that does some validation. Instead of $errors->get(key) returning the custom error messages I've defined, I'm getting the validation rule name. For example, if I use an email that's not unique:
$messages = [
'new_email.required' => 'Your new email address is required.',
'new_email:unique' => 'That email is already in use.',
'current_password|required' => 'Your current password must be provided.'
];
$rules = [
'new_email' => 'required|email|unique:users,email,' . $user->id,
'current_password' => 'required',
];
$validator = Validator::make($request->all(), $rules, $messages); // <-- custom error messages passed in here
if ($validator->fails()) {
$errors = $validator->errors();
if ($errors->has('new_email')) {
$msg = $errors->get('new_email'); // $msg contains ['validation.unique'] instead of ['That email is already in use.']
...
}
}
$errors->get('new_email') returns ['validation.unique'] instead of the custom error message in the array that's passed as the 3rd parameter to Validator::make. How can I get the custom error message instead of the validation rule that has been broken by the request?
There are some similar questions to this, but all the answers seem to focus on the resource/lang/xx/validation.php file missing or something like that. I'm not using those localization features at all.
Based on the documentation you should set your message with a string between property and validation rule.
$messages = [
'new_email.unique' => 'That email is already in use.',
];

Laravel array validation: use field index in error message

I'm trying to validate a field array, and I'd like to point out which field is wrong in the validation errors.
I have a form to upload multiple images. For each image, there must be a caption and the alt attribute for HTML. If I try to upload 3 images and miss the fields for two of them, I'll get an error message like the following:
The field 'image file' is required.
The field 'image caption' is required.
The field 'image alt' is required.
The field 'image caption' is required.
The field 'image alt' is required.
The field 'image file' is required.
The problem is that the :attribute is repeated and if the user wants to update multiple images he/she will have to check all of them to find which field is missing!
What I want is this:
The field 'image file (item 1)' is required.
The field 'image caption (item 1)' is required.
The field 'image alt (item 1)' is required.
The field 'image caption (item 3)' is required.
The field 'image alt (item 3)' is required.
The field 'image file (item 1)' is required.
So the user can know where to fix the problem.
First, I tried this:
$attributes = [
'img.*.file' => 'Image file (item :* )',
'img.*.alt' => 'Image alt (item :* )',
'img.*.caption' => 'Image caption (item :* )',
];
//
$this->validate($request, $rules, [], $attributes);
I supposed that the :* would be replaced by the index of the field (1, 2, 3, 4, etc) as the same way :attribute is replaced by the attribute. However, the :* is not replaced by the index of the fields; instead, it is displayed as plain text.
It worths to note that I designed the code in such way that the HTML name attribute is indexed sequentially for all fields (img[1][alt], [img][2][alt], etc, img[1][caption], [img][2][caption], etc), so each field has the right index. Having that in mind, I suppose there is a way to get the index and use to create custom attributes in the error messages.
I searched for this problem and found the same question here Validation on fields using index position, but it uses angular, not laravel.
How can I get the index and put it in the attribute?If that is not possible, is there any other way to accomplish the desirable result without having to set up the error messages?
I would like to change the attributes and keep the default error messages that laravel provides
Try this example
$input = Request::all();
$rules = array(
'name' => 'required',
'location' => 'required',
'capacity' => 'required',
'description' => 'required',
'image' => 'required|array'
);
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
$messages = $validator->messages();
return Redirect::to('venue-add')
->withErrors($messages);
}
$imageRules = array(
'image' => 'image|max:2000'
);
foreach($input['image'] as $image)
{
$image = array('image' => $image);
$imageValidator = Validator::make($image, $imageRules);
if ($imageValidator->fails()) {
$messages = $imageValidator->messages();
return Redirect::to('venue-add')
->withErrors($messages);
}
}
Thanks to the user sss S, I could implement his/her ideas to solve the problem.
Here is the code for the store method. It replaces (item) with (item $i) in the error message, where $i is the index of the field. Therefore the user can know exactly where is the error.
public function store(Request $request)
{
$rules = $this->rules();
$attributes = $this->attributes();
$validator = Validator::make($request->all(), $rules, [], $attributes);
$errors = [];
if ($validator->fails()) {
$errors = $validator->errors()->all();
}
$imgRules = [
'file' => 'required|image|mimes:jpeg,jpg,webp,png|max:1999',
'alt' => 'required|string|max:100|min:5',
'caption' => 'required|string|max:100|min:5',
];
$imgAttributes = [
'alt' => 'HTML alt attribute (item)',
'caption' => 'Caption(item)',
'file' => 'image file (item)',
];
foreach($request->img as $i => $img) {
$imgValidator = Validator::make($img, $imgRules, [], $imgAttributes);
$imgErrors = [];
if($imgValidator->fails()) {
$imgErrors = $imgValidator->errors()->all();
}
foreach($imgErrors as $k => $v) {
$imgErrors[$k] = str_replace('(item)', "(item $i)", $v);
}
$errors = array_merge($errors, $imgErrors);
}
if(count($errors) > 0) {
return response()->json(['success' => false, 'errors' => $errors]);
}
// here is the code store the new resource
// ...
// then return success message
}

Laravel 5.4 upload multiple images with validation rules

I'm using following code to upload multiple images but I need to add some validation rules like file should be an image with mentioned extensions and file size. Currently it upload everything.
This is my html view code:
<input required="" type="file" name="photos[]" id="photos" multiple="" directory="" webkitdirectory="" mozdirectory="">
This is my controller code:
foreach ($request->photos as $photo) {
$filename = $photo->store('photos');
$data['photoName'] = $filename;
PhotosModel::SavePhotos($data);
$message = "Photos Added Successfully";
}
I've added below code inside foreach loop and before that loop to but it's giving error that photos must be an image and of mentioned types.
$this->validate($request, [
'photos' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048'
]);
I want to upload all images and stop other files from being uploaded. Thanks!
Try this (before your foreach):
$this->validate($request, [
'photos' => 'required',
'photos.*' => 'image|mimes:jpeg,png,jpg,gif|max:2048'
]);

Laravel mimes validation rule not working for some file extensions

I'm trying to use mimes validation rule to validate uploading file.
'attachment' => 'required|file|max:1024|mimes:png,gif,jpg,txt,pdf,doc,docx,zip,rar'
It's working for some files with extensions like php but It's not working for extensions like js apk ovpn ....
Any idea?
Your messages error look like what before your validation. They should look like this
$messages = [
"attachment.required" => "error required",
"attachment.mimes" => "error mines",
];
$validator = Validator::make($data, [
'attachment' => 'required|mimes:csv,txt',
], $messages);
if ($validator->fails()) {
return redirect('/home')
->withErrors($validator)
->withInput();
} else {
// your code here
}
can you detail your file little more

How can I do this better without checking getClientOriginalName() on uploaded files?

$input = Input::all();
$input['resim'] = Input::file('resim')->getClientOriginalName();
$rules = array(
'resim' => 'required|max:3000|image|mimes:jpg,gif,png',
);
$validation = Validator::make($input, $rules);
if($validation->fails())
{
return View::make('theme-admin.slider_add')
->nest('message_area', 'theme-admin.error', array('message' => $validation->messages()->first()));
}
...
The issue is, Input::file('resim')->getClientOriginalName(); throw exception when the image is not uploaded. (e.g when I directly click on submit button on HTML form)
However, required|max:3000|image|mimes:jpg,gif,png this rule does not work if I erase that line. Whether if I upload a valid image or not, it doesn't pass mimes:jpg,gif,png control.
How can I do this without relying on Input::file('resim')->getClientOriginalName();? I want required control to handle what's necessary.
//Input has file with name attribute as 'resim'
$rules = array('resim' => 'required|max:3000|image|mimes:jpg,gif,png');
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
return Redirect::to('...')->withErrors($validator);
}
...
The problem lied in the images I'm trying to upload. For some reason, some of my JPG files couldn't pass the mimetype check whereas others can.
They all passed with getClientOriginalName() though.

Resources