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.
Related
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
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 have a table Languages with a language field and an image field. the CRU of CRUD is fine but the delete is firing the default validation. I have defined two validation files in Requests. One is AddNewLanguageRequest which contains:
public function rules()
{
return [
'language' => 'required|max:255|min:5',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048'
}
and the other is EditLanguageRequest which contains
public function rules()
{
return [
'language' => 'required|max:255|min:5',
'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
];
}
I have a form which shows the language and the image to be deleted and as confirm button and so this form calls a route:
{!! Form::open( array('url'=>'deletelanguage/'.$lang->id)) !!}
The route calls the LanguageController
public function delete(Requests\EditLanguageRequest $request){
//is there an image? If so delete it
$lang = Language::find($request->id);
if (isset($lang->image))
{
if (Storage::exists($lang->image) )
{Storage::delete($lang->image);}
}
$lang->delete();
}
When I try it out I get a validation failure from the EditLanguageRequest.
How can I "turn off" validation for the delete action?
The problem was in this line:
public function delete(Requests\EditLanguageRequest $request
It was of course calling the request so changing it to
public function delete(Request $request)
solved it
I tried googling and saw other questions posted at this forum but could not find any solution for my issue. I am using Jquery ajaxForm method to submit form. My form contains one file field too in the form that can be used to upload a picture. I have defined the validation in my model. But the issue is even i am uploading a correct jpg file, still i am getting error message that
Argument 1 passed to Illuminate\\Validation\\Factory::make() must be of the type array, object given.
Javascript Code
$('#create_form').ajaxForm({
dataType:'JSON',
success: function(response){
alert(response);
}
}).submit();
Controllder Code
if ($file = Input::file('picture')) {
$validator = Validator::make($file, User::$file_rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all(':message') as $message) {
echo $message; exit;
}
return Response::json(array('message'=>$response, 'status'=>'failure'));
} else {
// do rest
}
}
Model Code
public static $file_rules = array(
'picture' => 'required|max:2048|mimes:jpeg,jpg,bmp,png,gif'
);
POST Request
I know that my validation defined in the model expects an array. But by passing $file in the validator, an object is passed. Then i changed the code like:
$validator = Validator::make(array('picture' => $file->getClientOriginalName()), User::$file_rules);
Now i am getting error:
The picture must be a file of type: jpg, JPEG, png,gif.
The problem is you pass file object directly to validate. Validator::make() method takes all four parameters as array. Moreover, you need to pass the whole file object as value so that Validator can validate mime type, size, etc. That's why your code should be like that.
$input = array('picture' => Input::file('picture'));
$validator = Validator::make($input, User::$file_rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all(':message') as $message) {
echo $message; exit;
}
return Response::json(array('message'=>$response, 'status'=>'failure'));
} else {
// do rest
}
Hope it will be useful for you.
Try rule like this.
$rules = array(
'picture' => 'image|mimes:jpeg,jpg,bmp,png,gif'
);
or try removing 'mimes'
How can I limit the number of files that can be uploaded?
The max validation seems to apply to the size of the image (in kilobytes). How can I make a validation for the maximum number of files allowed to be uploaded (for example, only 10 files can be uploaded from a single input)?
How I did in laravel 7.x
Create a new form request class with the following command
php artisan make:request UploadImageRequest
use Illuminate\Foundation\Http\FormRequest;
use App\Http\Requests\BaseFormRequest;
class UploadImageRequest extends BaseFormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'coverImage.*' => 'image|mimes:png,jpg,jpeg,gif,svg|max:2048',
'coverImage' => 'max:5',
];
}
public function messages() {
return [
'coverImage.*.max' => 'Image size should be less than 2mb',
'coverImage.*.mimes' => 'Only jpeg, png, bmp,tiff files are allowed.',
'coverImage.max' => 'Only 5 images are allowed'
];
}
in View.blade.php
<input type="file" id="coverImage" name="coverImage[]"
class="form-control-file #error('coverImage') is-invalid #enderror" multiple>
#error('coverImage')
<span class="text-danger">{{ $message }}</span>
#enderror
in controller
public function store(UploadImageRequest $request)
{
//code
}
In laravel, there is no built-in validation rule for that. But you can create custom-validation rule to handle this.
Here is a simple custom-validation rule for it.
Create customValidator.php in app/ directory.
Validator::extend('upload_count', function($attribute, $value, $parameters)
{
$files = Input::file($parameters[0]);
return (count($files) <= $parameters[1]) ? true : false;
});
Don't forget to add it to app/start/global.php
require app_path().'/customValidator.php';
In your validation setting,
$messages = array(
'upload_count' => 'The :attribute field cannot be more than 3.',
);
$validator = Validator::make(
Input::all(),
array('file' => array('upload_count:file,3')), // first param is field name and second is max count
$messages
);
if ($validator->fails()) {
// show validation error
}
Hope it will be useful for you.