Limit number of files that can be uploaded - laravel

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.

Related

Custom rule Laravel Livewire

In Laravel Livewire I added a custom youtube video validation rule. It works very well, the problem is that I need it to be nullable and if I add in the validate nullable it gives me an error and I can't find how to solve this problem.
Input:
<input wire:model="video" class="form-control" type="text" placeholder="Url youtube">
Rule:
public function passes($attribute, $value)
{
return (bool) preg_match('/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=|\?v=)([^#\&\?]*).*/',$value);
}
Validate:
'video' => 'nullable', new RuleYoutube,
Removing nullable works fine, but the field is not required. And with the nullable property I get the following error:
No property found for validation: [0]
Any suggestion? Thank you very much for spending time in my consultation
Either you can have the validation in a single string pipe separated or in an array.
'video' => ['nullable', new RuleYoutube],
Check out livewire validation docs.
The way I solved this issue was to utilise Livewire's validateOnly method with an invokable validation Rule.
public function updated($propertyName)
{
if($propertyName == 'enquiry.contact_email'){
$this->validateOnly('enquiry.contact_email', [
'enquiry.contact_email' => [new DelimitedEmail, 'required']
]);
}
}
Invokable rule:
php artisan make:rule DelimitedEmail --invokable
Code:
class DelimitedEmail implements InvokableRule
{
public function __invoke($attribute, $value, $fail)
{
$func = function(string $value): string {
return trim($value);
};
if(str_contains($value, ',')) {
$emails = array_map($func,explode(',',$value));
foreach($emails as $email) {
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) $fail('This field has an invalid email address.');
}
} else {
if(!filter_var($value, FILTER_VALIDATE_EMAIL)) $fail('That is an invalid email address.');
}
}
}

Validation for form not checking partly

I have a Laravel program that saves form data and uploads a few pictures. In the validation, there are two rules. The image is required and it has to be of image type (jpg, jpeg, png). However, the validation only checks for the filetype and does not check for 'required'. Even if there is no image, it allows the user to submit. Why?
public function updateImages(Request $request, $id)
{
$validatedData = $request->validate([
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg|max:2048',
],
[
'image.*.image' => 'Format Error: Please uplaod image in a png or jpg format',
]);
$item = Post::find($id);
$existing_count = Photo::where('post', $item->id)->count();
$countrequest = sizeof($request->file('image'));
$count = $existing_count + $countrequest;
if ($count >= 6) {
return back()
->withInput()
->withErrors(['Only 5 images can be uploaded!']);
}
$upload = $this->imageUpload($item, $request);
return redirect()->back()->with('message', 'Image Updated');
}
Apply require with image.*. Eg.-
image.*' => 'require|image|mimes:jpeg,png,jpg|max:2048',
Try this solution. It will work.
You can use Laravel Request Validation
To create a form request class
php artisan make:request ImageUpdateRequest
Go to app/Http/Requests add the rules
public function authorize()
{
return true;
}
public function rules()
{
return [
'image' => 'required|image|mimes:jpeg,png,jpg|max:2048'
];
}
On your controller
use App\Http\Request\ImageUpdateRequest;
public function updateImages(ImageUpdateRequest $request, $id)
{
$item = Post::find($id);
$existing_count = Photo::where('post',$item->id)->count();
$countrequest = sizeof($request->file('image'));
$count= $existing_count+$countrequest;
if ($count >= 6 ){
return back()
->withInput()
->withErrors(['Only 5 images can be uploaded!']);
}
$upload = $this->imageUpload($item, $request);
return redirect()->back()->with('message', 'Image Updated');
}

Laravel 5.3 - overriding default validation for a delete

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

Is there any way to return the value of request field from request class instead of checking validations in laravel 5

I am using laravel 5. If the validation of any field fails, I want to get the value of a particular field from the request class which I have created and it can be displayed in the view class like displaying error messages. Does anyone knows how to code for that?
above photo, for the id part how to make the syntax to return the value?
Controller :
public function edit(Requests\EventRequest1 $request){
$date=$_POST['eventDate'];
$title=$_POST['title'];
$id=$_POST['id'];
$events=EventCal::findOrFail($id);
$events->update($request->all());
DB::table('event_cals')
->where('id',$id)
->update(['title' => $title,'eventDate' => $date]);
return redirect('/dcalendar');
}
Model :
class EventCal extends Model {
protected $fillable = [
'title',
'eventDate',
];
}
View :
#if($errors->has('title') )
<td><ul class="alert alert-danger" style="width: 250px;height: 40px"> {{$id}}</ul></td>
#endif
#if($errors->has('eventDate'))
<td><ul class="alert alert-danger" style="width: 250px;height: 40px"> {{$errors->first('eventDate')}}</ul></td>
#endif
EventRequest1(Request Class) :
public function rules()
{
return [
'title' => 'required',
'eventDate' => 'required|date|after:yesterday',
'id' => Request::get('id')
];
}
public function messages(){
return [
'title.required' => 'Title is required.',
'eventDate.after' => 'Event Date is passed.',
'eventDate.required' => 'Event Date is required.',
];
}
I want to return the id for view page. In the view page {{$id}} should print the id value.Is there any way? I'm not sure how to return the value of id from request. That's the only thing I needed to know.
Inside of your request class you must override the response() function:
public function response(array $errors)
{
return $this->redirector->back()
->withInput($this->except($this->dontFlash))
->withErrors($errors)
->with('id', $this->get('id'));
}

laravel array validation only one required

Hello i have a form for image upload
<input type="file" name="ad_image[]">
i want only one image to be required and others to be optional.
This is my validation rule and is not working:
'ad_image.*' => 'required|min:1|mimes:png,gif,jpeg,jpg|max:300',
i have tryed this:
'ad_image' => 'required|array|min:1|mimes:png,gif,jpeg,jpg|max:300',
also not working, when i upload jpg file there is error "The ad image must be a file of type: png, gif, jpeg, jpg."
please help with this issue
You can try:
public function rules()
{
$rules = [
'ad_image0'=> 'image|required|mimes:png,gif,jpeg,jpg|max:300'
];
$nbr = count($this->input('ad_image')) - 1;
foreach(range(0, $nbr) as $index) {
$rules['ad_image.' . $index] ='image|mimes:png,gif,jpeg,jpg|max:300';
}
return $rules;
}
I have decided to make my own custom validation rule:
This code is in boot method of the AppServiceProvider
public function boot()
{
Validator::extend('require_one_of_array', function($attribute, $value, $parameters, $validator) {
if(!is_array($value)){
return false;
}
foreach ($value as $k => $v){
if(!empty($v)){
return true;
}
}
return false;
});
}
The validation message is manualy added as third parameter of the validator
$messages = [
'require_one_of_array' => 'You need to upload at least one pic.',
];
And this is how is used to make sure at lease one image is uploaded (this is in rules array):
'ad_image' => 'require_one_of_array',
'ad_image.*' => 'mimes:jpeg,bmp,png|max:300',

Resources