Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel file upload required validation firing even when file is present

I have a form, one field is for a file named attachment, in my request the validation for this field requires it to be present when another field named requestType is set to the value of sick by using the required_if validation rule.

The issue I'm facing is that even when I upload a file for the input field in question the validation rule from the request class still gets triggered: The attachment field is required when request type is sick.

Here's my code:

Please note that the html required attribute on the attachment field is not what is causing the issue, on the page load it's set to disabled and when requestType is set to sick the disabled attribute is removed.

View

{!! Form::open(['route' => 'employee.request.store', 'class' => 'form-horizontal', 'id' => '', 'files' => 'true']) !!}

            <div class="form-group {{ $errors->first('requestType', 'has-error') }}">
                <label for="" class="col-sm-2 control-label"> {{ Lang::get('employee_request_contractor_create.request_type') }} *</label>
                <div class="col-sm-3">
                    {!! 
                        Form::select('requestType', 
                            ['' => 'Select', 'normal' => 'Normal', 'emergency' => 'Emergency', 'sick' => 'Sick'], 
                            '', 
                            ['class' => 'form-control', 'id' => 'requestType', 'required' => 'required']
                        ) 
                    !!}
                </div>
                {!! $errors->first('requestType', '<label class="col-sm-3 control-label" for="">:message</label>') !!}
            </div>

            <div class="form-group {{ $errors->first('attachment', 'has-error') }}" id="attachmentFormGroup">
                <label for="" class="col-sm-2 control-label"> {{ Lang::get('employee_request_contractor_create.attachment') }} <small>(Sick only)</small> </label>
                <div class="col-sm-3">
                    <input type="file" name="attachment" id="attachment" required="required">
                    <label>(Please provide HR with original copy)</label>
                </div>
                {!! $errors->first('attachment', '<label class="col-sm-3 control-label" for="">:message</label>') !!}
            </div>
    <!-- other form inputs and submit button -->
{!! Form::close() !!}

Request

public function rules()
{
    return [
        'requestType'   => 'required|max:255',
        'attachment'    => 'required_if:requestType,sick|mimes:pdf,jpg,png,gif,jpeg|max:512',
        /* other rules */
    ];

}

If I remove required_if:requestType the attachment uploads just fine and if I output in my controller:

if(\Input::hasFile('attachment') echo 'true';

I will see true.

When I dd($request) in my controller store method I see the following (relevant parts):

+request: ParameterBag {#227 ▼
    #parameters: array:10 [▼
      "_token" => "XkQwP608M5WQ4qtHCYN0dIVETDeqzL0E5ZI99iSf"
      "requestType" => "sick"
      "manager" => "2"
      "dateFrom" => "01-06-2015"
      "dateFromHijri" => "1436-08-14"
      "dateTo" => "02-06-2015"
      "dateToHijri" => "1436-08-15"
      "noOfDays" => "2"
      "location" => "London"
      "contactNumber" => "123456"
    ]
}

and...

+files: FileBag {#221 ▼
    #parameters: array:1 [▼
      "attachment" => UploadedFile {#27 ▼
        -test: false
        -originalName: "test_doc.pdf"
        -mimeType: "application/pdf"
        -size: 82584
        -error: 0
      }
    ]
  }

Is the rule getting fired because attachment is not showing up along with the other request attributes?

Update: Error messages:

["errors"]=>
  object(Illuminate\Support\ViewErrorBag)#178 (1) {
    ["bags":protected]=>
    array(1) {
      ["default"]=>
      object(Illuminate\Support\MessageBag)#179 (2) {
        ["messages":protected]=>
        array(1) {
          ["attachment"]=>
          array(1) {
            [0]=>
            string(59) "The attachment field is required when request type is sick."
          }
        }
        ["format":protected]=>
        string(8) ":message"
      }
    }
  }

Any help would be much appreciated. Thanks!

like image 953
haakym Avatar asked May 08 '15 08:05

haakym


1 Answers

Since the input is disabled when the requestType is not set to sick, the attachment is not included in the POST request sent to server. That is why Laravel's Request validation file triggers, because it doesn't even see the value in the POST data. To solve that, just add sometimes in the validation string for the attachment filed. The code should look like this:

public function rules()
{
    return [
        'requestType'   => 'required|max:255',
        'attachment'    => 'sometimes|required_if:requestType,sick|mimes:pdf,jpg,png,gif,jpeg|max:512',
        /* other rules */
    ];

} 

Here is an excerpt from the Laravel docs regarding this issue:

In some situations, you may wish to run validation checks against a field only if that field is present in the data being validated. To quickly accomplish this, add the sometimes rule to your rule list:

$v = Validator::make($data, [

   'email' => 'sometimes|required|email',

]);

In the example above, the email field will only be validated if it is present in the $data array.

like image 86
Ivica Pesovski Avatar answered Nov 14 '22 21:11

Ivica Pesovski