Image validation rule not working as expected - laravel

Here's my validation rule:
public function rules() {
$channel_id = Auth::user()->channels->first()->id;
return [
'name' => 'required|max:30|unique:channel,name,' . $channel_id,
'slug' => 'required|max:30|alpha_num|unique:channel,slug,' . $channel_id,
'description' => 'max:1000',
'channelImage' => 'image',
];
}
public function messages() {
return [
'slug.unique' => 'That unique URL has already been taken.',
'channelImage.image' => 'Only jpeg, jpg, png, bmp, gif and svg formats are supported.',
];
}
Although, is it not mandatory to upload channel image while filling the form, the image validation rule for channelImage works as if it's mandatory i.e. I need to upload an image every time I submit the request.
Why is working like that?? I did not mention required rule for channelImage, still why it is validating channelImage when I am not uploading any image?

Try using nullable:
'channelImage' => 'nullable|image',

Related

Why image validation accpet text file laravel postman?

I am using laravel 8 and i am uploading file from postman. I have also write validation rules for png, jpeg and jpg. But when i select any other file its also upload it.
Form data in postman is
enter image description here
and my resource file for validation is
public function rules()
{
return [
'invoice_id' => ['required', 'string'],
'invoice_date' => ['required', 'date'],
'invoice_photo_url' => ['required','image','mimes:jpeg,png,jpg'],
'invoice_net_total' => ['required','regex:/^\d*(\.\d{1,2})?$/'],
];
}
and my controller method is
public function upload(InvoiceUploadRequest $request)
{
try {
return $this->responseWithSuccess(true,"Invoice successfully uploaded!",
$this->invoiceInterface->uploadInvoice($request), Response::HTTP_OK);
}catch (\Exception $exception){
return $this->responseWithError($exception->getMessage(), Response::HTTP_OK);
}
}
how can is solve this.
thanks

How to validate files in Laravel?

It seems like some ios Devices (newer ones I believe, iPhones and iPads) and versions aren't able to validate files properly.
I'm trying to validate an image, a resume and 3 videos.
I keep getting one of these two errors:
"resume_id": [
"The resume id must be a file of type: doc, docx, pdf."
]
And I always upload a .doc or pdf file.
Or
"video_one_id": [
"The video one id must be a file of type: avi ,mpeg, mpeg4, mov."
]
"video_two_id": [
"The video two id must be a file of type: avi ,mpeg, mpeg4, mov."
]
"video_three_id": [
"The video three id must be a file of type: avi ,mpeg, mpeg4, mov."
]
And I always upload .mov files. I find usually this happens when I take a video on my iphone and upload it. My client also tried the same thing on his brand new iPad and also had no success.
Here is my code.
CandidateProfileRequest.php:
public function rules()
{
return [
'date_of_birth' => 'required',
'experience' => [
'required',
new MaxWordsRule(),
],
'skills' => [
'required',
new MaxWordsRule(350),
],
'job_title' => 'required',
'resume_id' => 'required|file|mimes:doc,docx,pdf',
];
}
CandidateProfileController.php:
public function store(CandidateProfileRequest $request)
{
if ($request->hasFile('video_one_id')
&& $request->hasFile('video_two_id')
&& $request->hasFile('video_three_id')
&& $request->hasFile('photo_id')) {
$request->validate([
'video_one_id' => 'file|mimes:avi ,mpeg, mpeg4, mov|max:30720',
'video_two_id' => 'file|mimes:avi ,mpeg, mpeg4, mov|max:30720',
'video_three_id' => 'file|mimes:avi ,mpeg, mpeg4, mov|max:30720',
'photo_id' => 'image|mimes:jpeg, png, jpg|max:5120'
]);
}
}
I also tried using mimetypes instead of mimes in my validation rules, but still I get the errors above.
On my Macbook Pro Laptop everything works, it's just on my iPhone and my clients iPad.
What am I doing wrong?
you can validate file like this way
$validator = Validator::make([ 'pdf' => $request->file('pdf'), 'extension' => strtolower($request->file('pdf')->getClientOriginalExtension()),
], ['pdf' => 'required', 'extension' => 'required|in:pdf,html,txt', ], ['pdf.required' => 'This field is required', 'extension.required' => 'This field is required','extension.in' => 'This field only accept pdf,html,txt extension',]);

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.2 Validate File Array

I have a form with three fields: title, body and photo[]. I'm trying to validate it so that at least one item is filled in, but I can't seem to get it to work. If I upload a file I still receive an error for title and body.
public function rules()
{
return [
'title' => 'required_without_all:body,photo.*',
'body' => 'required_without_all:title,photo.*',
'photo.*' => 'required_without_all:title,body',
'photo.*' => 'mimes:jpeg,gif,png',
];
}
Update: Jonathan pointed out that I had my rules wrong. I've fixed them and am now using this. It's still not working; when I try to upload a photo I get the error message that the other fields are required.
public function rules()
{
return [
'title' => 'required_without:body,photo.*',
'body' => 'required_without:title,photo.*',
'photo.*' => 'required_without:title,body|mimes:jpeg,gif,png',
];
}
If you're looking to ensure the photo field is an array then you need 'photo' => 'array' and then you can use 'photo.*' => '' for the other validations of the array's children.
The rules are separated by a pipe character | so if you were going to combine the two in your example it would be 'photo.*' => 'required_without_all:title,body|mimes:jpeg,gif,png',. I don't see you using the pipe to separate rules so I can't be sure you are aware of it.
This may have been where you were going wrong in the first place (two keys in the associative array that are identical) and some kind of precedence taking affect negating one of the rules.
You could try something like this (for the record I think you were on the right track to begin with using required_without_all as this stipulates the need to be required if all of the given fields are missing):
public function rules()
{
return [
'title' => 'required_without_all:body,photo',
'body' => 'required_without_all:title,photo',
'photo' => 'array',
'photo.*' => 'required_without_all:title,body|mimes:jpeg,gif,png',
];
}
Reference

Laravel 5.2 required_without_all Request Issue

I'm having an issue with required_without_all. I have three elements, and at least one should be filled. My file input's name is image[]. Adding an image but leaving title and body empty still results in a validation error, even though it shouldn't.
Any thoughts on what I'm doing wrong?
public function rules()
{
return [
'title' => 'required_without_all:body,image.*',
'body' => 'required_without_all:title,image.*',
'image.*' => 'required_without_all:body,title',
];
}
public function messages()
{
return [
'title.required_without_all' => 'At least one field is required',
'body.required_without_all' => 'At least one field is required',
'image.*.required_without_all' => 'At least one field is required',
];
}
Answered here: https://stackoverflow.com/a/39089295/2101328
Basically, add image as an array and remove the * from the rules.
There was also a bug in Laravel 5.3 that prevented similar from working; see this thread: https://github.com/laravel/framework/issues/15044#issuecomment-244364706
public function rules()
{
return [
'title' => 'required_without_all:body,image',
'body' => 'required_without_all:title,image',
'image' => 'array',
'image.*' => 'required_without_all:body,title',
];
}

Resources