I am building a form which uploads multiple files ,its working fine but the problem is my validation message ,my validation is checking the mime type of the file .
suppose the uploaded file with name filename
The validation message :
The file.0 must be a file of type: pdf, doc, docx, jpeg, jpg, png, bnp.
i want to change it to
The filename must be a file of type: pdf, doc, docx, jpeg, jpg, png, bnp.
My form :
{!! Form::open(['route' => ['file.store'], 'method'=> 'POST', 'id' => 'file_form','files' => 'true']) !!}
{!!Form::FILE('file[]', ['id' => 'file','multiple' =>true])!!}
<button type="submit" name="submit">save</button>
{!! Form::close() !!}
my formRequest validation
foreach ($this->file as $key => $val)
{
$rules['file.' . $key] = 'mimes:pdf,doc,docx,jpeg,jpg,png,bnp|extension|max:10240'
}
return rules;
Hi if u are using the FormRequest to validate.
Thats how i achieved it.
Here is an example.
public function messages()
{
$messages = [];
foreach($this->request->get('items') as $key => $val)
{
$messages['items.'.$key.'.max'] = 'The field labeled "Book Title '.$key.'" must be less than :max characters.';
}
return $messages;
}
Use custom validation message
Add this line in custom array in validation.php inside resource/lang/en/ folder
'custom' => [
.........
'file.*' => [
'mimes' => 'The filename must be a file of type: :values.',
],
I recommend, rename file to unique_name to not conflict with name
I appropriate all of you for your answers,i have found another way that fits to my project. I have created custom validation called custom_mimes to validate file type based on mime type ,and adding custom replacer (:filename) to this validation.
\Validator::extend('custom_mimes', function ($attribute, $file, $parameters, $validator)
{
$validator->addReplacer('custom_mimes', function ($message, $attribute, $rule, $parameters) use ($file)
{
$values=implode(',',$parameters);
return str_replace([':filename',':values'], [$file->getClientOriginalName(),$values], $message);
});
$mime_type =$file->guessExtension();
return in_array($mime_type,$parameters);
});
and in validation.php
'custom_mimes' => 'The :filename must be a file of type: :values.',
so my key and values will be :
:filename => uploaded filename
:values =>'jpg,png,doc,docx'
Inside an Form Request you can simply use it like below:
public function messages()
{
$messages = [];
foreach($this->request->get('files') as $key => $val)
{
$messages['files.'.$key. ". max"] = 'The file field cannot be greater then 10M';
}
return $messages;
}
Related
Laravel version: 8.82.0
I am uploading an image with inertiajs by making a post request with form.post method. An image data is received in controller as depicted in an image below:
My simplified controller:
public function store(){
Request()->validate([
'thumbnail' => 'required|mimes:png,jpeg,jpg|max:2048'
// Also tried, still fails.
// 'thumbnail' => 'required|image|mimes:png,jpeg,jpg|max:2048'
]);
return Redirect::route('showcases.index');
}
Upon ariving header content-type is application/json, I tried changing it to multipart/form-data but to no avail, image validation still fails.
The error I get is: The thumbnail must be a file of type: png, jpeg, jpg
you are trying to validate a base64 string instead of a file.
in the string format laravel validation cant validate the mime type.
so you may try to extend the validation rules and try a better way.
Inside the AppServiceProvider put the custom validation(there are many other cleaner ways)
public function boot()
{
Validator::extend('image64', function ($attribute, $value, $parameters, $validator) {
$type = explode('/', explode(':', substr($value, 0, strpos($value, ';')))[1])[1];
if (in_array($type, $parameters)) {
return true;
}
return false;
});
Validator::replacer('image64', function($message, $attribute, $rule, $parameters) {
return str_replace(':values',join(",",$parameters),$message);
});
}
now you can do :
'thumbnail' => 'required|image64:jpeg,jpg,png'
I have a multiple file input field:
<input type="file" id="documents" name="documents[]" multiple>
In my ProjectRequest class, I have the following rules applied:
$documents = count($this->input('documents'));
foreach(range(0, $documents) as $index) {
$rules['documents.' . $index] = 'mimes:doc,pdf,jpeg,bmp,png|max:20000';
}
But when I try to upload a png or pdf I get the following validation error:
The documents.0 must be a file of type: doc, pdf, jpeg, bmp, png.
Update:
As suggested in the answers, instead of looping through the array, I directly added the documents.* rule in the $rules array. However I still get the same error.
In ProjecRequest:
$rules = [
'documents.*' => 'mimes:doc,pdf,jpeg,bmp,png|max:20000',
];
return $rules;
In ProjectController#store:
public function store(ProjectRequest $request)
{
$project = Project::create([
/*key=>value removed to keep the question clean*/
]);
foreach ($request->documents as $document) {
$filename = $document->store('documents');
Document::create([
'project_id' => $project->id,
'filepath' => $filename
]);
}
return redirect()->back();
}
You don't need to loop through the array, rather use *.
$rules['documents.*'] = 'mimes:doc,pdf,jpeg,bmp,png|max:20000';
Read Laravel Official doc for better understanding.
You can validate arrays with:
'documents.*' => 'mimes:doc,pdf,jpeg,bmp,png|max:20000'
https://laravel.com/docs/5.5/validation#validating-arrays
I am giving the validation rule for image file types is:
array('employeedetails_photo', 'file', 'types' => 'jpg,gif,png', 'allowEmpty' => true,'on' => 'insert', 'on' => 'update'),
But, the problem is that if extension of .doc file is changed to .docx.jpg and upload this as employee photo is also accepted. How to give validation for this issue in yii ?
The best way to validate pictures is to recreate them using GD imagecreatefrom* (or Imagick) and save/replace the processed image. The most simple example
public function rules(){
return array(
array( 'employeedetails_photo', 'validateImage' )
);
}
public function validateImage( $attribute ){
$file = CUploadedFile::getInstance($this, $attribute);
if ( !$file ) {
return;
}
// http://php.net/manual/en/function.imagecreatefromstring.php
// These types will be automatically detected if your build of PHP supports them: JPEG, PNG, GIF, WBMP, and GD2
$gd = #imagecreatefromstring(file_get_contents($file->getTempName()));
if ($gd === false) {
$this->addError($attribute, 'Image is corrupted');
}
}
You must check file type with file mimetype. Php should made it for you. use mime-content-type function
I want to validate alpha_dash(Alphabets and Spaces) and the code below works fine
Validator::extend('alpha_spaces', function($attribute, $value)
{
return preg_match("/^[a-z0-9 .\-]+$/i", $value);
});
but the error it gives is not user friendly :
validation.alpha_spaces
How can change this message?
This is the method where it is posts
public function create(Request $request)
{
$this->validate($request, [
'title' => 'required|alpha_spaces|max:255',
]);
}
Thanks!
Just add your custom error message as an array element to resources/lang/xx/validation.php:
'alpha_spaces' => 'The :attribute may only contain letters, numbers and spaces.',
Read more: http://laravel.com/docs/5.0/validation#custom-error-messages
I'm trying to learn to an process image form that uploads images to a database and lets users view the image on the website, this is done using Laravel 4. I must have some sort of bug, because the view doesn't have any errors, but when I select an image to upload and hit the "save" button on my form, nothing happens other than it looks like the form has been refreshed because the file is gone.
Routes
// This is for the get event of the index page
Route::get('/', array(
'as' => 'index_page',
'uses' => 'ImageController#getIndex'
));
// This is for the post event of the index page
Route::post('/', array(
'as' => 'index_page_post',
'before' => 'csrf',
'uses' => 'ImageController#postIndex'
));
ImageController.php
class ImageController extends BaseController {
public function getIndex()
{
// Let's first load the form view
return View::make('tpl.index');
}
public function postIndex()
{
// Let's validate the form first with the rules which are set at the model
$input = Input::all();
$rules = Photo::$upload_rules;
$validation = Validator::make($input, $rules);
// If the validation fails, we redirect the user to the index page, with errors
if ($validation->passes()) {
// If the validation passes, we upload the image to the database and process it
$image = Input::file('image');
// This is the original uploaded client name of the image
$filename = $image->getClientOriginalName();
// Because Symfony API does not provide filename
// without extension, we will be using raw PHP here
$filename = pathinfo($filename, PATHINFO_FILENAME);
// We should salt and make an url-friendly version of the file
$fullname = Str::slug(Str::random(8) . $filename) . '.' .
$image->getClientOriginalExtension();
// We upload the image first to the upload folder, then
// get make a thumbnail from the uploaded image
$upload = $image->move
(Config::get('image.upload_folder'), $fullname);
Image::make(Config::get('image.thumb_folder').'/'.$fullname)
->resize(Config::get('image.thumb_width'), null, true)
->save(Config::get('image.thumb_folder').'/'.$fullname);
// If the file is now uploaded we show a success message
// otherwise, we show an error
if ($upload) {
// image is now uploaded, we first need to add column to the database
$insert_id = DB::table('photos')->insertGetId(
array(
'title' => Input::get('title'),
'image' => $fullname
)
);
// Now we redirect to the image's permalink
return Redirect::to(URL::to('snatch/'.$insert_id))
->with('success', 'Your image is uploaded successfully!');
}
else {
// Image cannot be uploaded
return Redirect::to('/')->withInput()
->with('error', 'Sorry, the image could not be uploaded.');
}
}
else {
return Redirect::to('/')
->withInput()
->withErrors($validation);
}
}
Image Model
class Photo extends Eloquent {
// the variable that sets the table name
protected $table = 'photos';
// the variable that sets the table name
protected $fillable = array('title', 'image');
// the timestamps enabled
public $timestamps = true;
// Rules of the image upload form
public static $upload_rules = array(
'title' => 'required|min:3',
'image' => 'required|image'
);
}
The view for the form
#extends('frontend_master')
#section('content')
{{ Form::open(array('url' => '/', 'files' => true )) }}
{{ Form::text('title', '', array(
'placeholder' => 'Please insert your title here')) }}
{{ Form::file('image') }}
{{ Form::submit('save', array('name' => 'send')) }}
{{ Form::close() }}
#stop
Let me know if you can find any bugs, I'm pretty sure something must be going wrong in my ImageController#postIndex
Thanks for any insights
2 things you need to check out.
1st off, once you updated your composer.json to include the Intervention/Image package. you should run composer dump-autoload to refresh the autoload file.
2ndly, there's a logical error in your controller.
Image::make(Config::get('image.thumb_folder').'/'.$fullname)
->resize(Config::get('image.thumb_width'), null, true)
->save(Config::get('image.thumb_folder').'/'.$fullname);
should be
Image::make(Config::get('image.image_folder').'/'.$fullname)
->resize(Config::get('image.thumb_width'), null, true)
->save(Config::get('image.thumb_folder').'/'.$fullname);
because you've already moved the image file to image_folder with the code below:
$upload = $image->move
(Config::get('image.upload_folder'), $fullname);
Hope this helps.