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.
Tweet Follow @tntstudiohrcomments powered by Disqus