Laravel multi file validation fails - php

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

Related

Invalid argument supplied for foreach() in Form and Multi Image upload in Laravel

The Form upload and the product image as featured image and other other images using the store function of laravel
use App\Productimage;
use App\Products;
public function store(Request $request)
{
$featured = $request->featured_image->store('products_featured');
$product = Products::create([ //uploading successfully
'name'=>$request->name,
'featured_image' => $featured,
]);
foreach ($request->photos as $photo) { //error
$filename = $photo->store('product_images');
Productimage::create([
'product_id' => $product->id,
'image_name' => $filename,
]);
}
return back();
}
Make sure $request->photos is an array and your form is a multipart/form-data.
You need to send your files from your blade (or wherever your are sending them from) in photos[], e.g.
<input type="file" name="photos[]"/>
P.S - In your controller method, you should access $request->photos like this $request->file('photos'). - This is not the cause of your error but if you don't do this, you'll get a JSON object instead of file content.
you form should have enctype="multipart/form-data" and input type file is array
foreach ($request->file('photos') as $photo) { //error
$filename = $photo->store('product_images');
Productimage::create([
'product_id' => $product->id,
'image_name' => $filename,
]);
}
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="photos[]"/>

how to validate multiple file upload field editing the "validateBread" method in the default Voyager BREAD controller

I'm overwriting the default Voyager BREAD Controller. I copied the VoyagerBreadController.php file in app\Http\Controllers\VoyagerMoviesController.php and I modified the validateBread method as below. It almost works; it validates correctly other sort of field, but it doesn'work properly for upload file field (which we know is a multiple file upload field). The field name is "nomefile". I suspect a syntax error in my code, could you please help me?
public function validateBread($request, $data, $name = null, $id = null) {
//Start my modification
//dd($request);
$rules = [
'sottotitolo' => 'required',
'nomefile.*' => 'mimes:jpg,png' //this is what won't work
];
$messages = [
'sottotitolo.required' => '... we need this value, please.'
];
//end of my modification
//$rules = []; of course these two lines were uncommented
//$messages = [];
$customAttributes = [];
$is_update = $name && $id;
$fieldsWithValidationRules = $this->getFieldsWithValidationRules($data);
foreach ($fieldsWithValidationRules as $field) {
$fieldRules = $field->details->validation->rule;
$fieldName = $field->field;
jpg is not a valid mimetype.
Instead use jpeg.
See https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types for all mimetypes.

where should i add specify extension for mime types in laravel?

$photo = Input::file('photo');
if($photo) {
$size = $photo->getSize();
$mime = $photo->getMimeType();
$orignalname = $photo->getClientOriginalName();
$orignalextension = $photo->getClientOriginalExtension();
$destination = "Documents/edifile/";
$filename = time().str_replace(' ', '_', $orignalname);
$photo->move($destination,$filename);
where i have add this line 'file' => 'required|max:10000|mimes:edi,jpeg' i want to upload this extension file only.?
You should add this in your form validation. See Laravel form Validation for how to use.
And here is a code sample.
//Assume photo is your controller method
public function photo(Request $request) {
$this->validate($request, [
'photo' => 'required|max:10000|mimes:edi,jpeg', //add your validation
]);
}
You need to add validation logic inside your controller.
Check the official documentation here, it is very simple.

Laravel 5 custom validation rule for existing tags

I'm searching for a cleaner way to validate tags when storing a Post.
All of the input validation takes place within my custom request StorePostRequest. The problem is that I need to check whether the given tags exist in the database, only existing tags are allowed. The function $request->input('tags') returns a string with comma seperated values, for example: Tag1,Tag2,Tag3.
Here is the code:
/**
* Store a newly created resource in storage.
*
* #param StorePostRequest $request
* #return Response
*/
public function store(StorePostRequest $request)
{
//THIS PIECE OF CODE
$tags = explode(',', $request->input('tags'));
$tags = Tag::whereIn('title', $tags)->lists('id');
if(count($tags) < 1)
{
return redirect()->back()->withInput()->withErrors([ trans('tags.min') ]);
}
else if(count($tags) > 5)
{
return redirect()->back()->withInput()->withErrors([ trans('tags.max') ]);
}
//TILL HERE
$post = $request->user()->posts()->create([
'slug' => unique_slug('Post', $request->input('title')),
'title' => $request->input('title'),
'description' => $request->input('description'),
'summary' => $request->input('summary'),
]);
$post->tags()->attach($tags);
return redirect(route('theme.post.show', [$theme->slug, $post->slug]))->with(['success', trans('messages.post.store')]);
}
The code is a little sloppy and redundant when using it in multiple controllers.
In order to solve this, I've created a ValidationServiceProvider to extend the core validator rules. Something like this:
$this->app['validator']->extend('tags', function ($attribute, $value, $parameters)
{
$tags = explode(',', $value);
$tags = Tag::whereIn('title', $tags)->lists('id');
if(count($tags) < 1 || count($tags) > 5))
{
return false;
}
});
Pretty neat. The thing is I still need to be able to access the $tags variable within the controller (because of ->attach($tags)).
Is there a better way of tackling this problem? Or should I stop thinking and just use (and repeat) the code I have?
Thanks in advance, hope it makes some sence.
I am assuming that you understand the use of this class because I have seen that you have defined StorePostRequest class. So, just for clarify, the rules method could looks like:
public function rules()
{
return [
'tags' => ['required', 'tags'] //kb
];
}
Finally, with all the tools in correct place, you only make manipulate the data in your controllers like this:
public function store(StorePostRequest $request)
{
// at this point, the tags are already validated, so we, proceed get them:
$tags = explode(',', $$request->get('tags'));
$post = $request->user()->posts()->create([
'slug' => unique_slug('Post', $request->input('title')),
'title' => $request->input('title'),
'description' => $request->input('description'),
'summary' => $request->input('summary'),
]);
$post->tags()->attach($tags);
return redirect(route('theme.post.show', [$theme->slug, $post->slug]))->with(['success', trans('messages.post.store')]);
}
Keep in mind that inyecting StorePostRequeststore in the controller's function it is already validating and running the rules.
That is enough if you really has defined the StorePostRequest's rules correctly.
foreach($request->tags as $k=>$tags){
$this->validate($request, [
'tags.'.$k => 'required|string|max:20'
]);
}

validator function doesn't work in laravel

i want to validate the file input field, am new in laravel so i cant figure out what am missing.
here is my code:
public function postUploadS(){
$file = array(Input::file('file'));
$rule = array('file' => 'required');
$validate = Validator::make($file,$rule);
if($validate->fails()){
var_dump($file); exit();
}
else{
return View::make('admin.uploadStaff'); }
}
I i cant get to the uploadStaff view even if i choose the file, any help please
It looks like your problem is that the $file array isn't associative, meaning the validator doesn't see any input to compare the file rule in $rule against.
Change: $file = array(Input::file('file'));
to: $file = array('file' => Input::file('file'));
...and the validator now knows what input to run against your rule.

Categories