Laravel form validation as a service

Form validation is one of the most common tasks while building web applications and form validation in Laravel is no exception to that rule. What is the exception here is that we have a great arsenal of tools which can help us make life as easy as possible while still keeping our data safe.

We don't intend to start model vs. service validation war here, there are ups and downs to both approaches and for this example we are going to show you how to do basic form validation in laravel as a service rather than model based validation.

As our example we are going to use our own contact form which is very simple and consist of several fields: name, email address and the message field.

You can see it in action if you go to our contact form.

The goal is to makes sure we have a valid email address and that the name and message field are not blank. Ok it's pretty simple so lets get started.

The first thing we want to do is create a library folder in our app directory. We will call it lib and the structure will look like this:

/app
    /commands
    /config
    /controllers
    /database
    /lang
    /lib
    /models
    /start
    /storage
    /tests
    /views
/bootstrap
/public
/vendor

Once we created this directory we need to tell composer to autoload classes from it. This is simply done by editing the composer.json file and adding "app/lib" to it. It should now look like this:

"autoload": {
    "classmap": [
        "app/commands",
        "app/controllers",
        "app/models",
        "app/database/migrations",
        "app/database/seeds",
        "app/tests/TestCase.php",
        "app/lib"
    ]
},

After we added our directory to the autoloader we run

composer dump-autoload

By the way this is something we do in every application in order to have a folder where we can store those files which on the first hand look like no place to put them in. Laravel is pretty neat with allowing you to structure your folders and data the way you want so take advantage of this fact and forget about rigid structures which some other frameworks require.

Inside our lib folder we create another folder called validators.

Firstly we'll create an abstract class called Validator and all of the other validators will extend this class

<?php namespace App\Lib\Validators;

abstract class Validator {

    protected $input;
    public $messages;
    public static $rules;

    public function __construct($input)
    {
        $this->input = $input;
    }

    public function fails()
    {
        $validation = \Validator::make($this->input, static::$rules);

        if ($validation->fails())
        {
            $this->messages = $validation->messages();
            return true;
        }

        return false;
    }

    public function messages()
    {
        return $this->messages;
    }
}

The filename for this class will be Validator.php

It's time to create our contact form validator class that will do the validation once the form is submitted. We'll simply call it ContactFormValidator and save it in validators directory.

<?php namespace App\Lib\Validators;

class ContactFormValidator extends Validator
{
    public static $rules = array(
        'name'     => 'required',
        'email'    => 'required|email',
        'msg'  => 'required'
    );
}

Lets see how this behaves in a controller action. When the form is submitted the sendMail() action will be called

public function sendMail()
{
    $validator = new ContactFormValidator(Input::all());
    if ($validator->fails())
    {
        return Redirect::to('contact')
            ->withInput()
            ->withErrors($validator->messages());
    }

    Mail::send('emails.contact', Input::all(), function($message)
    {
        $message->to('youremail@provider.com', 'Your Name')->subject('Your Subject');
    });

    Session::flash('message', true);
    return View::make('contact');
}

Don't forget to use our newly created namespace use App\Lib\Validators\ContactFormValidator;

To put it simply, we instantiate the ContactFormValidator class and the validation is automatically done. The method above is self explanatory but basically we check if the validation fails, and if so we return back to the contact form with the old input fields and with the errors.

If you get an error that a class name cannot be found run once again

composer dump-autoload

The errors can be accessed inside a view like:

@if($errors->has())
  @foreach($errors->all() as $message)
   <div class="alert alert-danger">{{ trans($message) }}</div>
  @endforeach
@endif

Share your thoughts below and if you really like this article feel free to retweet it.

TopTal



comments powered by Disqus