0

I'm new in laravel, im using laravel 5.6 to build a contact form who send email, with some fields and file attachmend .

The Form is working, and it send all the fields, but only when i left the attach input empty, throws a error.

Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR)
Call to a member function isValid() on null

I need the file field to be able to be empty
'file' => 'sometimes'

Controller:

    <?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Http\Requests\ContactFormRequest;

class ContactController extends Controller
{
    public function show()
    {
        return view('contact.show');
    }

    public function send(ContactFormRequest $request)
    {
        // upload photo file
        $filePath = $this->upload($request->file('file'));

        $fullName = $request->get('firstname');

        \Mail::send('emails.contact', array(
                'fullName' => $request->get('firstname'),
                'email' => $request->get('email'),
                'body' => $request->get('message'),
                'file' => $filePath,
                'company' =>$request->get('company'),
                'insta' =>$request->get('insta'),
                'web' =>$request->get('web'),
                'description' =>$request->get('description'),
                'phone' =>$request->get('phone'),



            ), function($message) 
            {
                $message->from('my@mail.cl');
                $message->to('my@mail.cl', 'Nombre')->subject('Tienes un nuevo registro de !');
            }
        );

        return \Redirect::route('contact_show', array('locale' => \Lang::getLocale()))
            ->with('message', 'Gracias por inscribirte!\' nos pondremos en contacto contigo lo antes posible!');
    }

    protected function upload($file)
    {
        if ($file->isValid()) {
            $fileName = (new \DateTime())->format('d.m.Y-hsi').'.'.$file->guessExtension();
            $file->move(storage_path() . '/uploads', $fileName);
            return storage_path() . '/uploads/' . $fileName;
        } else {
            return \Redirect::route('contact_show')
                ->with('message', 'El Archivo no es valido!');
        }        
    }
}

Request:

<?php

namespace App\Http\Requests;

use App\Http\Requests\Request;

class ContactFormRequest extends Request
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'firstname' => 'required',
            'email' => 'required|email',
            'message' => 'sometimes',
            'company' => 'sometimes',
            'phone' => 'required',
            'insta' => 'sometimes',
            'web' => 'sometimes',
            'description' => 'required',
            'file' => 'sometimes'

        ];
    }
}

Form:

@extends('base')

@section('content')

    @if (Session::has('message'))
        <div class="alert alert-info">
            {{ Session::get('message') }}
        </div>
    @endif

    <h1>{{ trans('contact.contact_us') }}</h1>
    <ul>
        @foreach($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>

    {!! Form::open(array('route' => 'contact_send', 'class' => 'form', 'files' => true)) !!}

    <div class="form-group">
        {!! Form::label(Lang::get('first name')) !!}
        {!! Form::text('firstname', null, array('required', 'class' => 'form-control')) !!}
    </div>

    <div class="form-group">
        {!! Form::label(Lang::get('Empresa')) !!}
        {!! Form::text('company', null, array('class' => 'form-control')) !!}
    </div>
    <div class="form-group">
        {!! Form::label(Lang::get('insta')) !!}
        {!! Form::text('insta', null, array( 'class' => 'form-control')) !!}
    </div>
        <div class="form-group">
        {!! Form::label(Lang::get('web')) !!}
        {!! Form::text('web', null, array( 'class' => 'form-control')) !!}
    </div>
    <div class="form-group">
        {!! Form::label(Lang::get('email')) !!}
        {!! Form::text('email', null, array('required', 'class' => 'form-control')) !!}
    </div>
    <div class="form-group">
        {!! Form::label(Lang::get('phone')) !!}
        {!! Form::text('phone', null, array('required','class' => 'form-control')) !!}
    </div>
        <div class="form-group">
        {!! Form::label(Lang::get('description')) !!}
        {!! Form::text('description', null, array('required','class' => 'form-control')) !!}
    </div>
    <div class="form-group">
        {!! Form::label(Lang::get('photo')) !!}
        {!! Form::file('file', null, array('class' => 'form-control')) !!}
    </div>

    <div class="form-group">
        {!! Form::label(Lang::get('message')) !!}
        {!! Form::textarea('message', null, array('class' => 'form-control')) !!}
    </div>

    <div class="form-group">
        {!! Form::submit(Lang::get('send'), array('class' => 'btn btn-primary')) !!}
    </div>
    {!! Form::close() !!}

@endsection

3 Answers3

0

You are using the sometimes validation rule incorrectly.

As per the docs you use that validation rule if you want to apply other validation rules when the value is present in the array you pass.

https://laravel.com/docs/5.6/validation#conditionally-adding-rules

Your validation array should look like this:

return [
    'firstname' => 'required|string',
    'email' => 'required|email',
    'message' => 'string',
    'company' => 'string',
    'phone' => 'required',
    'insta' => 'string',
    'web' => 'url',
    'description' => 'required|string',
    'file' => 'file'
];

Also I recommend that you don't use the form builder. Even though it's still in Laravel it has been removed from the laravel docs for some time, building the html is just as easy.

I'm not sure if this will directly solve your problem but hopefully it will be related :).

Tom Headifen
  • 1,885
  • 1
  • 18
  • 35
0

First thing is to correct validation rule from 'file' => 'sometimes' to 'file' => 'file' and then make little bit changes in function upload() before checking $file->isValid(), you must check is it null or empty.

  • To check is it null use is_null($file)
  • To check variable is not set !isset($file)

For more details here is a link check if variable empty

Ammar Ali
  • 692
  • 6
  • 20
0

i fixed the problem sending a default img, if the form file is empty

my controller

    public function upload($file)
    {
    if (is_null($file)) {

     return storage_path() . '/uploads/' . '1.png';

   }   
   else {
               if ($file->isValid()) {
            $fileName = (new \DateTime())->format('d.m.Y-hsi').'.'.$file->guessExtension();
            $file->move(storage_path() . '/uploads', $fileName);
            return storage_path() . '/uploads/' . $fileName;
        } else {
            return \Redirect::route('contact_show')
                ->with('message', 'El Archivo no es valido!');
        }     
   }   
    }

my request

    return [
'firstname' => 'required',
'email' => 'required|email',
'message' => 'nullable',
'company' => 'nullable',
'phone' => 'required',
'insta' => 'nullable',
'web' => 'nullable',
'description' => 'required',
'file' => 'mimes:jpeg,bmp,png,mp4s,doc,dot,pdf,docx,cgm,gif,jpg,jpe,svg,txt,mp4,mov',

    ];

mimes is the validation who works for my file upload