Laravel mimes validation rule not working for some file extensions - laravel

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

Related

Problems with Laravel data validation

I'm having some problems with validations in my api.
I need to send a json array like this:
[
{
"acktime": "2021-09-25 08:45:07",
"temp": 15.6
},
{
"acktime": "2021-09-25 08:45:07",
"temp": 15.6
}
probably more array....
]
I would like to vaidate one by one array and store only the valid data returning error for unvalid data, I have tried a foreach cylce but it convert the array to object but the validate::make want only array.
I have tried this:
$validator = Validator::make($request->all(), [
'*.acktime' => 'required',
'*.temp' => 'required|numeric'
]);
$validatedData = $validator->validated();
var_dump($validatedData);
return response()->json($validatedData);
But If I send wrong data I get only error without having valid data, so I've tried this way:
foreach($datas as $data){
$arr = (array)$data;
$validator = Validator::make($arr, [
'acktime' => 'required',
'temp' => 'required|numeric'
]);
if ($validator->fails()) {
continue;
} else {
$newrawData = new rawData([
'acktime' => $data->acktime,
'temp' => $data->temp,
'synctime' => now()
]);
$newrawData->save();
}
}
return response('OK', 200); //or error if some data are not ok
}
In this way it work, bot I have no idea about get, a probable, validation error..(for the moment there's a continue for continue the cycle) any suggestion?
There are two ways for approaching this kind of validation:
make a custom rule in laravel validation from below and put your validation code in it and this will work:
https://laravel.com/docs/8.x/validation#custom-validation-rules
easier way:
$data = [ 'data' => $requests->all() ];
$validator = Validator::make($data, [
'data.*.name' => 'required|string',
'data.*.' => 'required|string'
]);

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.',
];

Error from Laravel to AJAX fileupload

I have an AJAX upload that sends the uploaded file (image in this case) to a function in Laravel 5.3. There I have this validation check in said function:
...
$validator = Validator::make($request->all(), [
'image' => 'image|mimes:jpeg,png,jpg|max:512',
]);
// If validator fails return this error to AJAX
if($validator->fails()) {
return response()->json('error', 422);
}
...
How would I be able to set the response()->json('error', 422) with a custom error. Now I only get an error that the file upload has failed. I would like more feedback then that.
For example: let the user know his file is to large or let the user know his extension is not allowed.
Thanks
You can get error messages from validator and send it to response, here is example.
if ($validator->fails()) {
return response()->json([
'success' => false,
'error' => $validator->getMessageBag()->toArray()
], 422);
}

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

Error when validating the mimType of file in cakePHP

i want to check the mimeType of an image uploaded, but i have this error :
Cannot validate mimetype for a missing file
and this is my code :
public function validationDefault(Validator $validator)
{
$validator
->add('poster', [
'myRule' => [
'rule' => ['mimeType', ['image/png']],
'message' => 'Just PNG files !'
]
]);
return $validator;
}
I use CakePHP 3.x , thanks for help

Resources