Laravel validator does'nt correctly validate file mime type - laravel

I send multiple files to my server with postman
And these files are uploaded correctly but they are not properly validated before uploading
this is my controller
public function store(Request $request)
{
// دریافت دایرکتوری مطالبه مربوطه : $demand=Demand::find(72)->files->first()->file_directoryس
//{"title":"this is test title","demandContent":"this is test content "} send as form-data request
//------------------------------------------- Valid Uploaded File ---------------------------------
$rules = array(
'file' => 'required',
'file.' => 'mimes:doc,pdf,docx,zip,jpg,jpeg,rar'
);
$error = Validator::make($request->all(), $rules);
if($error->fails())
return response()->json(['errors' => $error->errors()->all()]);
//-------------------------------------------- Valid Uploaded File -------------------------------
$request->data=json_decode($request->data); //دریافت به صورت جیسون و تبدیل به شی
$demand=new Demand(['title' => $request->data->title,'content'=>$request->data->demandContent,'user_id'=>auth('api')->user()->id]);
if($demand->save()) //اگر درخواست در دیتابیس قبت شد
{
//----------------------------File Upload Scope---------------------------------------
if($request->hasfile('file'))
{
$path='public/demands/'.$demand->id.'/files';
foreach($request->file('file') as $file)
{
$filename=$file->getClientOriginalName();
$file->move($path, $filename);
}
$demand->files()->save(new File(['file_directory'=>$path]));
}
//----------------------------File Upload Scope---------------------------------------
return response()->json(['demand'=>new DemandResource($demand)],200);
}
return response()->json(['state'=>'false']);
}

In your validation rules you have forgotten * like:
$rules = [
'file' => 'required',
'file.*' => 'required|file|mimes:doc,pdf,docx,zip,jpg,jpeg,rar',
];

Related

How to put validatedWithBag() within custom Request in laravel

I made a custom request with laravel, but I want to validate with bag's name "limit", so that I can use to display the modal. If without a custom request then I managed to use validationWithBag("limit", $rules,$message), But if I made a custom request, it didn't work.
the code below doesn't work, controller:
public function limit(LimitRequest $request, $id)
{
$request->validatedWithBag('limit');
$dataArrayUpdate =[
'limit_quiz' => $request->limitquiz,
];
return (new QuizGuruService())->update($dataArrayUpdate,base64_decode($id));
}
view:
#if($errors->hasbag('limit'))
openModal($('#modalEditLimit'));
#endif
previously I used the following code and it worked:
public function limit(Request $request, $id)
{
if ($request->routeIs('guru.*')) {
$rules = [
'limitquiz' => 'required|numeric|min:0|max:300',
];
$message = [
'limitquiz.required' => "Nilai maksimal jumlah soal harus diisi!",
'limitquiz.numeric' => "Format nilai maksimal soal harus berupa angka!",
'limitquiz.min' => "Jumlah soal tidak boleh kurang dari nol!",
'limitquiz.max' => "Maksimal jumlah soal yang diperbolehkan saat ujian adalah 300 soal!",
];
$request->validateWithBag('limit', $rules, $message);
$dataArrayUpdate =[
'limit_quiz' => $request->limitquiz,
];
return (new QuizGuruService())->update($dataArrayUpdate,base64_decode($id));
} else {
return abort("404", "NOT FOUND");
}
}

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

Seeking to understand how this error "Illuminate\Http\Exceptions\PostTooLargeException" comes about

I've got the following code and it's working just well as expected when uploading images but I noticed when I try to upload a video I get the error Illuminate\Http\Exceptions\PostTooLargeException. I was expecting to get an error on browser "The make field should be an image" just as the other validations are working. Could someone kindly explain what's happening here, shouldn't validation stop immediately the uploaded file is found to be not an image? Is the validation checking for size first and yet that's not what I've provided in validation?
public function store(Request $request)
{
$this->validate($request, [
'condition' => 'required',
'make' => 'required | alpha',
'model' => 'required | alpha_dash',
'filenames' => 'required | image',
'filenames.*' => 'image',
]);
$files = [];
if($request->hasfile('filenames'))
{
foreach($request->file('filenames') as $file)
{
$name = time().rand(1,100).'.'.$file->extension();
$file->move(public_path('files'), $name);
$files[] = $name;
}
}
$vehicle = new Vehicle;
$vehicle->condition = $request->condition;
$vehicle->make = $request->make;
$vehicle->model = $request->model;
$vehicle->filenames= $files;
$vehicle->save();
return redirect(route('vehicles.create'))->with('flash', 'Vehicle Post Created
Successfully');}

How to image upload into databae using laravel?

I am trying to upload an image into the database but unfortunately not inserting an image into the database how to fix it, please help me thanks.
database table
https://ibb.co/3sT7C2N
controller
public function Add_slider(Request $request)
{
$this->validate($request, [
'select_image' => 'required'
]);
$content = new Sliders;
if($request->file('select_image')) {
$content->slider_image = Storage::disk('')->putFile('slider', $request->select_image);
}
$check = Sliders::create(
$request->only(['slider_image' => $content])
);
return back()
->with('success', 'Image Uploaded Successfully')
->with('path', $check);
}
You should do with the following way:
public function Add_slider(Request $request)
{
$this->validate($request, [
'select_image' => 'required'
]);
$image = $request->file('select_image');
$extension = $image->getClientOriginalExtension();
Storage::disk('public')->put($image->getFilename().'.'.$extension, File::get($image));
$content = new Sliders;
if($request->file('select_image'))
{
$content->slider_image = $image->getFilename().'.'.$extension;;
$content->save();
$check = Sliders::where('id', $content->id)->select('slider_image')->get();
return back()->with('success', 'Image Uploaded Successfully')->with('path',$check);
}
}
And in view blade file:
<img src="{{url($path[0]->slider_image)}}" alt="{{$path[0]->slider_image}}">
This returns only the filename:
Storage::disk('')->putFile('slider', $request->select_image);
Use this instead:
Sliders::create([
'slider_image' => $request->file('select_image')->get(),
]);
Make sure the column type from database is binary/blob.

Better way for testing validation errors

I'm testing a form where user must introduce some text between let's say 100 and 500 characters.
I use to emulate the user input:
$this->actingAs($user)
->visit('myweb/create')
->type($this->faker->text(1000),'description')
->press('Save')
->see('greater than');
Here I'm looking for the greater than piece of text in the response... It depends on the translation specified for that validation error.
How could do the same test without having to depend on the text of the validation error and do it depending only on the error itself?
Controller:
public function store(Request $request)
{
$success = doStuff($request);
if ($success){
Flash::success('Created');
} else {
Flash::error('Fail');
}
return Redirect::back():
}
dd(Session::all()):
`array:3 [
"_token" => "ONoTlU2w7Ii2Npbr27dH5WSXolw6qpQncavQn72e"
"_sf2_meta" => array:3 [
"u" => 1453141086
"c" => 1453141086
"l" => "0"
]
"flash" => array:2 [
"old" => []
"new" => []
]
]
you can do it like so -
$this->assertSessionHas('flash_notification.level', 'danger'); if you are looking for a particular error or success key.
or use
$this->assertSessionHasErrors();
I think there is more clear way to get an exact error message from session.
/** #var ViewErrorBag $errors */
$errors = request()->session()->get('errors');
/** #var array $messages */
$messages = $errors->getBag('default')->getMessages();
$emailErrorMessage = array_shift($messages['email']);
$this->assertEquals('Already in use', $emailErrorMessage);
Pre-requirements: code was tested on Laravel Framework 5.5.14
get the MessageBag object from from session erros and get all the validation error names using $errors->get('name')
$errors = session('errors');
$this->assertSessionHasErrors();
$this->assertEquals($errors->get('name')[0],"The title field is required.");
This works for Laravel 5 +
Your test doesn't have a post call. Here is an example using Jeffery Way's flash package
Controller:
public function store(Request $request, Post $post)
{
$post->fill($request->all());
$post->user_id = $request->user()->id;
$created = false;
try {
$created = $post->save();
} catch (ValidationException $e) {
flash()->error($e->getErrors()->all());
}
if ($created) {
flash()->success('New post has been created.');
}
return back();
}
Test:
public function testStoreSuccess()
{
$data = [
'title' => 'A dog is fit',
'status' => 'active',
'excerpt' => 'Farm dog',
'content' => 'blah blah blah',
];
$this->call('POST', 'post', $data);
$this->assertTrue(Post::where($data)->exists());
$this->assertResponseStatus(302);
$this->assertSessionHas('flash_notification.level', 'success');
$this->assertSessionHas('flash_notification.message', 'New post has been created.');
}
try to split your tests into units, say if you testing a controller function
you may catch valication exception, like so:
} catch (ValidationException $ex) {
if it was generated manually, this is how it should be generated:
throw ValidationException::withMessages([
'abc' => ['my message'],
])->status(400);
you can assert it liks so
$this->assertSame('my message', $ex->errors()['abc'][0]);
if you cannot catch it, but prefer testing routs like so:
$response = $this->json('POST', route('user-post'), [
'name' => $faker->name,
'email' => $faker->email,
]);
then you use $response to assert that the validation has happened, like so
$this->assertSame($response->errors->{'name'}[0], 'The name field is required.');
PS
in the example I used
$faker = \Faker\Factory::create();
ValidationException is used liks this
use Illuminate\Validation\ValidationException;
just remind you that you don't have to generate exceptions manually, use validate method for common cases:
$request->validate(['name' => [
'required',
],
]);
my current laravel version is 5.7

Resources