12
Php

Laravel – 5.1 – Middleware For Input Validation

Actually this article is about form validation using a single middleware. Well, Laravel peovided us many ways for validating our user inputs and my favorite way is using Form Request class which is just awesome. Chexk it here if you are not already aware of that. Using a form request class we can validate the incoming request before the coresponding controller method’s code gets executed and to implement this we need to make/create form request class for each controller as per method basis and we declare only one method in that form request class which is the rules() to declare validation rules for validating the incoming request.

Well, nothing bad in it but I just want to keep my validation rules inside my model and also want to use only a single class for validating all of my models. So, to achieve this, I’ve replaced the form request class using a single middleware and here is how I did it.

At first let’s create the middleware:
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\JsonResponse;

class InputValidator
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $fullyQualifiedNameOfModel)
    {
		$model = app($fullyQualifiedNameOfModel);
		
		$validator = app('validator')->make($request->input(), $model->rules($request));
		
		if ($validator->fails()) {
		    
			return $this->response($request, $validator->errors());
        }
        
		return $next($request);
    }
	
	protected function response($request, $errors)
	{
		if($request->ajax()) {
			return new JsonResponse($errors, 422);
		}
		
		return redirect()->back()->withErrors($errors)->withInput();
	}
}

Now, we need to add this middleware in the $routeMiddleware array in the App\Http\Kernel.php class, for example, the $routeMiddleware is given below:

/**
	 * The application's route middleware.
	 *
	 * @var array
	 */
	protected $routeMiddleware = [
		'auth' => 'App\Http\Middleware\Authenticate',
		'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
		'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
		'acl' => 'App\Http\Middleware\CheckPermission',
		'validator' => 'App\Http\Middleware\InputValidator', // <-- This One
	];

Now, to use this middleware as form validator for our every model we may use this middleware in the route declaration as given below:

$router->get('create', [
	'uses' => 'TagController@create',
	'as' => 'admin.tag.create',
	'permission' => 'manage_tag',
	'middleware' => 'validator:App\Eloquent\Tag' // Pass the model name (including namespace)
]);

Here, the Validator is the middleware (alias of original middleware (App\Http\Middleware\InputValidator) class) and the parameter passed into the middleware is App\Eloquent\Tag to tell the middleware which model to use to get the validation rules so let's create the model with rules() method, for example, my models are saved in app/Eloquent directory and namespace is App\Eloquent so fully qualified name of the model class was passed as the middleware parameter so we can obtain an instance of that model easily.Let's check out the model now:

 'required|unique:tags,tag_title,'.$request->route()->parameter('id'),
			'tag_slug' => 'required|unique:tags,tag_slug,'.$request->route()->parameter('id'),
		];
	}
}

That's it. Now, I can validate the request inputs (Submitted Form Inputs) using the middleware and this way I can keep my validation rules inside the model it self and most importantly I can now use only this single middleware to validate all of my models instead of using an individual FormRequest class for each model. This way still my validation service is out of my controller which runs before the controller method gets called and everything goes very well. That's it.

Latest Blog

0
Php

PHP – 8.0 Match Expression

In PHP 8.0 there is a new feature or I should say a new language construct (keyword) going to be introduced,  which has been implemented depending […]