4

How do I go about validating an array of uploaded files in Laravel 4? I've set it in the form to allow multiple files, and I've tested that the files exist in the Input::file('files') array. But how do I validate each file?

Here's what I've tried:

$notesData = array(
            'date' => Input::get('date'),
            'files' => Input::file('files')
    );


    // Declare the rules for the form validation.
    $rules = array(
            'date'  => 'Required|date_format:Y-m-d',
            'files'  => 'mimes:jpeg,bmp,png,pdf,doc'
    );

    // Validate the inputs.
    $validator = Validator::make($notesData, $rules);

    // Check if the form validates with success.
    if ($validator->passes())
    {
        // Redirect to homepage
        return Redirect::to('')->with('success', 'Validation passed!');
    }

    // Something went wrong.
    return Redirect::to(URL::previous())->withErrors($validator)->withInput(Input::all());

I expected Validator to complain about passing an array of files inside the data array, but it just passed validation even though the file I sent it was an mp3. When I tried to upload multiple files, it gave an unrelated error that the date field is required (though the date field was autopopulated).

I'm pretty new to Laravel. What could I do to get this working?

UPDATE: I figured out part of the problem was my upload_max_filesize and post_max_size, which I fixed. I've also tried dynamically adding the files to the arrays as so:

$notesData = array(
            'date' => Input::get('date')
    );
    $i=0;
    foreach(\Input::file('files') as $file){
        $notesData['file'.++$i] = $file;
    }

    // Declare the rules for the form validation.
    $rules = array(
            'date'  => 'Required|date_format:Y-m-d'
    );
    for($j=1; $j<=$i; $j++){
        $rules['file'.$j] ='mimes:jpeg,bmp,png,doc'; 
    }

But now I'm getting the following error:

Serialization of 'Symfony\Component\HttpFoundation\File\UploadedFile' is not allowed

And I'm lost. Any idea how to fix this?

4 Answers 4

11

I think, this is basically your initial solution. For anybody who's still confused, here's some code that worked for me…

// Handle upload(s) with input name "files[]" (array) or "files" (single file upload)

if (Input::hasFile('files')) {
    $all_uploads = Input::file('files');

    // Make sure it really is an array
    if (!is_array($all_uploads)) {
        $all_uploads = array($all_uploads);
    }

    $error_messages = array();

    // Loop through all uploaded files
    foreach ($all_uploads as $upload) {
        // Ignore array member if it's not an UploadedFile object, just to be extra safe
        if (!is_a($upload, 'Symfony\Component\HttpFoundation\File\UploadedFile')) {
            continue;
        }

        $validator = Validator::make(
            array('file' => $upload),
            array('file' => 'required|mimes:jpeg,png|image|max:1000')
        );

        if ($validator->passes()) {
            // Do something
        } else {
            // Collect error messages
            $error_messages[] = 'File "' . $upload->getClientOriginalName() . '":' . $validator->messages()->first('file');
        }
    }

    // Redirect, return JSON, whatever...
    return $error_messages;
} else {
    // No files have been uploaded
}
Sign up to request clarification or add additional context in comments.

1 Comment

This worked for me. Don't u guys forget to open the FORM with enctype="multipart/form-data" like {{ Form::open(['files'=>true]) }}
3

Well, I'm not exactly sure what was causing the error, but after playing around a bit with the validator, I figured out that I couldn't just pass all the files at once. Instead, I made a new array that associated each file with keys 'file0', 'file1', etc. Then I passed these to the validator and set rules for each one (using a foreach loop). Then the validator worked as expected. Still, it wasn't flexible enough for my needs and I ended up using a non-laravel solution.

1 Comment

I think I might've figured out what was causing the Serialization error.. If validation fails, I always redirect to the previous page with the input, but apparently the file input can't be serialized, so instead of using "withInput(Input::all())" I have to use "withInput(Input::except('files')"
1

It might not be the direct answer for your question, but you can do a simple validation check on types like this:

$file = Input::file('files');

switch($file->getClientMimeType()){
      case 'application/pdf':
           // upload stuff
      break;
}

1 Comment

Thanks, but not quite what what I was looking for. I ended up writing my own solution instead of using Validator though
0
foreach(Request::file('photos') as $key => $value) {
    $rules['photos.'.$key]="mimes:jpeg,jpg,png,gif|required|max:10000";
    $friendly_names['photos.'.$key]="photos";
}

This worked for me in Laravel 5.2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.