When my validation fails, I get a statusText in English in the response: Unprocessable Entity. How to get the translated version (according to my config.app.locale) ?
public function update(Request $request)
{
$attributes = [
'last_name' => ['integer'],
'first_name' => ['email']
];
$validator = Validator::make($request->user, $attributes);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
}
You can find all the strings in different languages inside the resources/lang folder. Inside each language folder, there are a few files with the message of each topic. For example, validation messages are inside validation.php.
To have the messages in your language you just need to add the proper set up in the locale key inside the config/app.php file. After that create the validation.php file inside your language folder in resources/lang.
For more info check the Official Documentation
Related
I have a form that using ajax for update data client. In that form there is an input file. Everything is going fine except for updating the file. File is sent, it changed on storage too, but it gives error on validation and didn't change data on database.
Here is the code on the controller :
public function update(Request $request, Client $client)
{
$validatedData = Validator::make($request->all(), [
'name' => 'required|max:255',
'logo'=> 'image|file|max:100',
'level' => 'required|max:1'
]);
$validatedData['user_id'] = auth()->user()->id;
if ($validatedData->fails()){
return response()->json($validatedData->errors());
} else {
if($request->file('logo')){
if($request->oldLogo){
Storage::delete($request->oldLogo);
}
$validatedData['logo'] = $request->file('logo')->store('logo-clients');
}
$validateFix = $validatedData->validate();
Client::where('id', $client->id)->update($validateFix);
return response()->json([
'success' => 'Success!'
]);
}
}
It gives error on line :
$validatedData['logo'] = $request->file('logo')->store('logo-clients');
With message :
"Cannot use object of type Illuminate\Validation\Validator as array"
I use the same code that works on another case, the difference is the other not using ajax or I didn't use Validator::make on file input. I guess it's just wrong syntax but I don't really know where and what it is.
To retrieve the validated input of a Validator, use the validated() function like so:
$validated = $validator->validated();
Docs:
https://laravel.com/docs/9.x/validation#manually-creating-validators
https://laravel.com/api/9.x/Illuminate/Contracts/Validation/Validator.html
$validatedData is an object of type Illuminate\Validation\Validator.
I would say the error is earlier there as well as this line should give an error also:
$validatedData['user_id'] = auth()->user()->id;
As ericmp said, you first need to retrieve the validateddata to an array and then work with it.
I need to make custom request and use its rules. Here's what I have:
public function rules()
{
return [
'name' => 'required|min:2',
'email' => 'required|email|unique:users,email,' . $id,
'password' => 'nullable|min:4'
];
}
The problem is that I can't get $id from url (example.com/users/20), I've tried this as some forums advised:
$this->id
$this->route('id')
$this->input('id')
But all of this returns null, how can I get id from url?
When you are using resources, the route parameter will be named as the singular version of the resource name. Try this.
$this->route('user');
Bonus points
This sound like you are going down the path of doing something similar to this.
User::findOrFail($this->route('user'));
In the context of controllers this is an anti pattern, as Laravels container automatic can resolve these. This is called model binding, which will both handle the 404 case and fetching it from the database.
public function update(Request $request, User $user) {
}
I have a validator set up to check if the document we upload is an XML file
if ($request->input('action') == 'upload_document') {
$validator = Validator::make($request->all(), [
'file' => 'bail|required|mimes:application/xml,xml|max:10000',
]
);
}
But when I do my upload, this validator triggers me an error "File must e of type application/xml,xml" even when I drop a real XML file with a .xml extension.
I have in my php.ini config extension=php_fileinfo.dll of course
Note that mime type validation instruct Laravel to read the content of the file to determine its type, so changing an image extension from .jpg to .xml will not trick it
From the Docs
mimes:foo,bar,...
The file under validation must have a MIME type corresponding to one of the listed extensions.
Basic Usage Of MIME Rule
'photo' => 'mimes:jpeg,bmp,png'
Even though you only need to specify the extensions, this rule actually validates against the MIME type of the file by reading the file's contents and guessing its MIME type.
A full listing of MIME types and their corresponding extensions may be found at the following location: https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
So make sure your file is an actual valid xml file (try this with phpunit.xml) from your Laravel project
Route::post('/', function (Request $request) {
if ($request->input('action') == 'upload_document') {
$validator = Validator::make(
$request->all(),
[
'file' => 'bail|required|mimes:application/xml,xml|max:10000',
]
);
$validator->validate();
dd('the file is valid');
}
});
And a form like this
<form method="post" enctype="multipart/form-data">
#csrf
<input name="action" value="upload_document">
<input type="file" name="file">
<button type="submit">Submit</button>
</form>
#error('file')
{{ $message }}
#enderror
Result:
"the file is valid"
But when testing with image.xml
The file must be a file of type: application/xml, xml.
Alternatively, you can validate by extension
Route::post('/', function (Request $request) {
if ($request->input('action') == 'upload_document') {
$request->validate([
'file' => [
'bail',
'required',
'max:10000',
function ($attribute, $value, $fail) {
if ($value->getClientMimeType() !== 'text/xml') {
$fail($attribute.'\'s extension is invalid.');
}
},
]
]);
dd('the file is valid');
}
});
Now an image file with the xml extension passes the validation
See using closures for custom validation
It seems that the XML provided by an external company is not respecting the proper XML standard.
As it is not on my hands, I won't reformat it and I will have to manage it as text only. So I guess I can't use a validator in my case.
For those who try to pass xml extension on Laravel 5 (like me).
This will work with other additional extensions also.
Since Laravel ExtensionGuesser allows to add custom guesser via method register we do the folowing.
Make new class with own extensions array. I've made it exdending the original one so it corresponds the interface. I've put it to Helpers folder.
<?php
namespace App\Helpers;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser;
/**
* Provides a best-guess mapping of mime type to file extension.
*/
class PriorExtensionGuesser extends MimeTypeExtensionGuesser
{
/**
* Addition to pretty old map of mime types and their default extensions.
*
* #see http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
*/
protected $defaultExtensions = array(
'text/xml' => 'xml',
);
}
In you controller (don't forget use statement):
use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
public function store (Request $request) {
if ($request->hasFile('file')) {
$guesser = ExtensionGuesser::getInstance(); //take the guesser who will guess
$guesser->register(new \App\Helpers\PriorExtensionGuesser()); //add own guesser
$validator = Validator::make($request->all(), [
'file' => 'file|mimes:txt,xls,xlsx,csv,xml|max:32768',
]);
if ($validator->fails()) {
.....
So now guesser checks our array in Prior* class then goes to original one.
Yo! I am working on a form where I attach some image.
Form:
{{ Form::file('attachments[]', array('multiple')) }}
Validation:
$this->validate($response, array(
'attachments' => 'required | mimes:jpeg,jpg,png',
));
I have also tried 'image' as validator rule but whenever I post the form with jpg image I get back errors:
The attachments must be a file of type: jpeg, jpg, png.
Working with Laravel 5.3
Since you defined an input name of attachments[], attachments will be an array containing your file. If you only need to upload one file, you might want to rename your input name to be attachments, without the [] (or attachment would make more sense in that case). If you need to be able to upload multiple, you can build an iterator inside your Request-extending class that returns a set of rules covering each entry inside attachments[]
protected function attachments()
{
$rules = [];
$postedValues = $this->request->get('attachments');
if(null == $postedValues) {
return $rules;
}
// Let's create some rules!
foreach($postedValues as $index => $value) {
$rules["attachments.$index"] = 'required|mimes:jpeg,jpg,png';
}
/* Let's imagine we've uploaded 2 images. $rules would look like this:
[
'attachments.0' => 'required|mimes:jpeg,jpg,png',
'attachments.1' => 'required|mimes:jpeg,jpg,png'
];
*/
return $rules;
}
Then, you can just call that function inside rules() to merge the array returned from attachments with any other rules you might want to specify for that request:
public function rules()
{
return array_merge($this->attachments(), [
// Create any additional rules for your request here...
]);
}
If you do not yet have a dedicated Request-extending class for your form, you can create one with the artisan cli by entering: php artisan make:request MyRequestName. A new request class will be created inside app\Http\Requests. That is the file where you would put the code above in. Next, you may just typehint this class inside the function signature of your controller endpoint:
public function myControllerEndpoint(MyRequestName $request)
{
// Do your logic... (if your code gets here, all rules inside MyRequestName are met, yay!)
}
I am trying to create a custom validation to check if a file was uploaded in a form.
I looked at the custom errors docs but couldn't make it work.
I found this tutorial: Custom Error
In my controller I do this:
if($request->hasFile('file'))
$has_file = 1;
else
$has_file = 0;
$this->validate($request, ['file' => 'isuploaded']);
In App/ServiceProvider I added this:
Validator::extend('isuploaded', function($attribute, $value, $parameters, $validator) {
return ?;
});
What should I return here? How do I send the $has_file to the validator?
If the file field is required the validate will check it for you.
Assuming that your form file input has name="file", just:
$this->validate($request, [
'file' => 'required
]);
In this way if there is no file the validation will fail.
If this is not your case and you want to create the custom rules in Validator::extend you should write your own business logic to check if the file exists and just return true/false.