2

I am submitting an array of file fields to Laravel and I want to run validation on each file to check that it is the correct mime type (only PNG, JPG and GIF should be allowed) However if I upload a TIF image file the validation passes. Here is what I am submitting:

Request URL:http://local.website.com/upload
Request Method:POST
Status Code:200 OK
Remote Address:127.0.0.1:80
Response Headers
view source
Connection:Keep-Alive
Content-Length:6
Content-Type:text/html; charset=UTF-8
Date:Mon, 02 May 2016 19:05:18 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.6.3
X-Powered-By:PHP/5.6.3
Request Headers
view source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:19912006
Content-Type:multipart/form-data; boundary=----WebKitFormBoundarypWGUvcecHBZlzNcP
Cookie:__utma=252126427.1839499577.1452033482.1452033483.1452072866.2; __utmz=252126427.1452033483.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _gat=1; _ga=GA1.2.1839499577.1452033482; laravel_session=eyJpdiI6InVxazdLSFwvNWNRUnl2eDQrRmFhdUpBPT0iLCJ2YWx1ZSI6IlJRXC9mRk9EYXBUWUpQMHpFMms3Mm9hYkRiekNjUlJHTDlBS0hpYkk2R091RmFYQzVsM1JWcEdMdmFzRjl3Q3BoaEZHQUM3VFc5ZE5Oak5KdHowaU0zdz09IiwibWFjIjoiZTYxM2U3MmVhNzU4NmFiZDNmYWFhNjdiZDE3NDczM2IxN2RmYWFhYWZlMzhiNTBiM2IwZjEyYWQwNThhMTk1MyJ9
Host:local.website.com
Origin:http://local.website.com
Pragma:no-cache
Referer:http://local.website.com/
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
X-Requested-With:XMLHttpRequest
Request Payload
------WebKitFormBoundarypWGUvcecHBZlzNcP
Content-Disposition: form-data; name="files[]"; filename="eye design.png"
Content-Type: image/png


------WebKitFormBoundarypWGUvcecHBZlzNcP
Content-Disposition: form-data; name="files[]"; filename="hd flamingo.tif"
Content-Type: image/tiff


------WebKitFormBoundarypWGUvcecHBZlzNcP
Content-Disposition: form-data; name="files[]"; filename="Picture 3.tif"
Content-Type: image/tiff


------WebKitFormBoundarypWGUvcecHBZlzNcP
Content-Disposition: form-data; name="files[]"; filename="Picture 16.tif"
Content-Type: image/tiff


------WebKitFormBoundarypWGUvcecHBZlzNcP
Content-Disposition: form-data; name="files[]"; filename="Picture 23.tif"
Content-Type: image/tiff


------WebKitFormBoundarypWGUvcecHBZlzNcP--

Here is are the contents of my request:

<?php namespace App\Http\Requests;

use Response;
use Illuminate\Foundation\Http\FormRequest;

class UploadRequest extends FormRequest
{
    public function rules()
    {
        $rules = [
            'files' => 'required'
        ];
        foreach($this->files as $key => $file) {
            $rules['files.'.$key] = 'image|mimes:jpeg,png,gif';
        }
        return $rules;
    }

    public function messages()
    {
        $messages = [
            'files.required' => 'You must upload a file.'
        ];

        foreach($this->files as $key => $file) {
            $messages['files.'.$key.'.image'] = 'The upload file must be an image.';
            $messages['files.'.$key.'.mimes'] = 'The image must be one of the following types: JPEG, PNG, or GIF.';
        }
        return $messages;
    }

    public function authorize()
    {
        return true;
    }
}

This is my route for the form being submitted:

Route::post('upload', ['uses' => 'UploadController@index', 'as' => 'upload.post']);

This is my UploadController file:

<?php namespace App\Http\Controllers;

use Response;
use Illuminate\Http\Request;
use Input;
use Image;
use Session;
use App\Http\Requests\UploadRequest;
use Auth;
use App\Setting;
use App\Discount;
use App\User_credit;
use App\Customer_group_discount;
use Event;
use App\Events\ImagesUpdated;

class UploadController extends Controller {

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {

    }

    /**
     * Handles the uploading of images
     *
     * @return Response json
     */
    public function index(UploadRequest $request)
    {
        // validation has passed do stuff
    }
}

The request is definitely being run but it just isn't failing when it should do. What am I doing wrong?

2
  • First, seeing your routes.php set up would help a lot, and secondly, nowhere in this file do you use $this->validate($request, $rules); Commented May 2, 2016 at 19:15
  • I've added the route and controller to show how the validation is being called Commented May 2, 2016 at 19:18

3 Answers 3

2

I solved it in the end, here is my request now:

<?php namespace App\Http\Requests;

use Response;
use Illuminate\Foundation\Http\FormRequest;

class UploadRequest extends FormRequest
{
    public function rules()
    {
        $request = $this->instance()->all();
        $images = $request['files'];

        $rules = [
            'files' => 'required'
        ];
        foreach($images as $key => $file) {
            $rules['files.'.$key] = 'image|mimes:jpeg,png,gif';
        }
        return $rules;
    }

    public function messages()
    {
        $request = $this->instance()->all();
        $images = $request['files'];

        $messages = [
            'files.required' => 'You must upload a file.'
        ];

        foreach($images as $key => $file) {
            $messages['files.'.$key.'.image'] = 'The upload file must be an image.';
            $messages['files.'.$key.'.mimes'] = 'The image must be one of the following types: JPEG, PNG, or GIF.';
        }
        return $messages;
    }

    public function authorize()
    {
        return true;
    }

    public function response(array $errors)
    {
        $request = $this->instance()->all();
        $images = $request['files'];
        $image = $images[0];

        $error_string = '';
        foreach($errors['files.0'] as $error) {
            $error_string.= ' '.$error;
        }

        $json = array('files' => array(
            array(
                'name' => $image->getClientOriginalName(),
                "size" => $image->getClientSize(),
                'error' => $error_string
            )
        ));

        return Response::json($json);
    }

}
Sign up to request clarification or add additional context in comments.

Comments

0

When using custom requests to perform validation, for some reasons, Laravel doesn't include uploaded files. The first way to solve this problem is to use manual validators, as in Laravel 4.

The other way is to include the uploaded files in the request. Inside your extended request class, add this:

// 'massage' data so that files get in as well
protected function getValidatorInstance()
{
    $data = $this->all();
    $data['logo'] = $this->file('project_logo'); 
    $data['banner'] = $this->file('project_banner');
    $this->getInputSource()->replace($data);

    return parent::getValidatorInstance();
}

What the code does is to override the getValidatorInstance() method of the request, and manually placing your files into it. In this case, I have two files which I needed to be validated and their name in the HTML form are project_logo and project_banner respectively.

Comments

0

This is not an exact solution but a simple hack to check files.

if($request->file('docs')) {

$extensions_allowed = ['pdf', 'docx'];

foreach ($request->file('docs') as $file) {

   if(in_array($file->getClientOriginalExtension('docs'), $extensions_allowed)){

        return "yes----";

    }else {

       return "No-----";
    }
  }
}

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.