Structure Laravel 4 Custom Validation with Namespaces

Published on by Safeer

In Laravel 4 there are multiple ways to add your own validation rules, one of which is to extend the Validation Class, now this can be done without Namespaces but as using Namespaces will be less likely to cause naming collisions in the future, we’ll do it with Namespaces.

The Setup

First and foremost you’ll need to have Laravel 4 setup, more information can be found on the Laravel 4 website.

Registering your own Namespace with the autoloader has been covered in the old blogpost I did on structuring your Laravel App with Namespaces posted a few months ago. However I’ll go through it again as it’s very simple and quick.

Start by picking a Namespace, keep it unique enough to avoid clashes, for this article we’ll be using the namespace FooExample, though you can call it whatever you wish.

Next we need to add the Namespace mapping to Composer, we can do this by updating your composer.json file like:

      "autoload": {
        "psr-0": { 
          "FooExample": "src/"
        }
      }

then run composer dump-autoload, this will update the autoload mappings. Once this is done, if you haven’t aready, create the src/FooExample folder. Then we can move onto creating our first Custom Validation rule.

Simple Custom Validation Rule

The first way of extending the Validation capabilities of Laravel 4 via Classes is best suited if you only need a few extra Validation rules. Let’s start by creating the Validation Class, the exmaple will demonstrate how to do this and we’ll keep the validation rule simple by checking if a number is divisible by 2.

So let’s create a new folder for the Validators and put this under src/FooExample, after this create a Class in src/FooExample/Validators/ called Numeric.php, in this file copy and paste the following code:

    <?php

    // Replace FooExample with your namespace
    namespace FooExample\Validator;

    class Numeric
    {
        public function divisibleByTwo($attribute, $value, $parameters)
        {
            return ($value % 2) === 0;
        }
    }

Once this is done we need to register this new Validator method, this can be done by calling the following:

      Validator::extend('divisible_by_two', '\FooExample\Validator\Numeric@divisibleByTwo');

This can be called anywhere as long as it’s before the use of the Validation rule.

It’s worth noting that if we wanted to add more we could by adding more methods to the class and then registering the extra rules. However I’ll be discussing later on in this article a better way to add multiple custom validation rules.

Using the new Validation Rule

To ensure that this validation method works let’s create a simple route that will check and print out if the supplied number is divisible by two. To do this just create a simple route in route.php like:

    Route::get('divisibleByTwo/{number}', function($number)
    {
        Validator::extend('divisible_by_two', '\FooExample\Validator\Numeric@divisibleByTwo');

        $input      = ['number' => $number];
        $rule       = ['number' => 'divisible_by_two'];
        $messages   = ['divisible_by_two' => 'The :attribute must be divisible by two.'];

        $validator = Validator::make($input, $rule, $messages);

        if ($validator->fails()) {
            return $validator->messages()->first('number');
        }

        return $number . ' is divisible by two.';
    });

Now when you call the route: divisibleByTwo/2, it will output an error message or if it’s divisible by 2 a success message.

Error Messages

In the above Route we pass the error message through to the Validator, but this could also be placed in app/lang/en/validation.php, todo this just add the following line in that file:

    'divisible_by_two' => 'The :attribute must be divisible by two.',

Then you no longer need to pass in the message via Validator::make, unless you wish to override the message for a specific case.

Extending the Validator Class

Okay, so now we have one simple validaton method which is great but what if we wanted to add more than one new validation rule without needing to register each individual rule? Well in this case we can extend the Validation Class, to do this let’s go back to the original Numeric.php Class and change it to the following:

    <?php

    // Replace FooExample with your namespace
    namespace FooExample\Validator;

    class Numeric extends \Illuminate\Validation\Validator 
    {
        public function validateDivisibleByTwo($attribute, $value, $parameters)
        {
            return ($value % 2) === 0;
        }
    }

Then we need to change the way we register the new Validation, so let’s go back to the divisibleByTwo route, and replace the following:

    Validator::extend('divisible_by_two', '\FooExample\Validator\Numeric@divisibleByTwo');

with

    Validator::resolver(function($translator, $data, $rules, $messages)
    {
        return new \FooExample\Validator\Numeric($translator, $data, $rules, $messages);
    });

and that should be enough to switch over to adding Validation Rules by extending the Laravel 4 Validator Class.

Other ways to register Validation Rules

So far we’ve only looked at placing the registration of custom validation rules in the route, however it’ll probably be better to move this elsewhere. Now depending on the type of Validation Class you may want to put this in a before hook for a Model or Controller or even place it in start.php, again this really depends on what you’re aiming for.