Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

alierfani's avatar

L5: How to validate date input before passing to rules method in a form request?

I have a form which includes a deadline and the user should pick a deadline which is a Persian date. In the form Request, I'm compiling four fields into a deadline. So my form Request is like this:

public function rules()
    {
        $this->prepInput();
        return [

        ];
    }
    public function prepInput(){
        $input=$this->all();
        ...
        $input['deadline']=$this->prepDeadline($input['hour'], $input['month'], $input['day'], $input['year']);
        ...
        $this->replace($input);
    }


    public function prepDeadline($hour,$month,$day, $year){

            $time = jDateTime::mktime($hour, 0, 0, $month, $day, $year);
            return $deadline = strftime("%Y-%m-%d %H:%M:%S", $time);        
    }

and I need to check if the user have selected a valid date or not (e.g. 1394/12/31 is not a valid date). The jDatetime package has a checkdate method which works exactly like php checkdate. Where and how can I validate the date in this formRequest and notify the user to select a valid date? In fact I need this validation to take place before the deadline is passed to prepInput().

0 likes
11 replies
vitorarjol's avatar

@alierfani Well, I recently had to do some validation on my dates inside the Form Request.

The code is something like:

 public function rules()
    {
        return [
            'name' => 'required',
            'begin_date' => 'required | date_format:"d/m/Y"|after:"2015-01-01"',
            'end_date' => 'required | date_format:"d/m/Y"|after:begin_date'
        ];
    }

As you can see, I'm using some goodies from the Laravel validator. The format will be evaluated using the PHP date_parse_from_format function.

1 like
alierfani's avatar

@vitorarjol I have tried this and it won't work, because it will not check if an invalid date is provided by user and the invalid date will be converted to a valid one and the validation will be passed

vitorarjol's avatar

Really? That's strange.

My validation is working as expected, when the user input something like '11/11/2014' the validation fails and return the message to the user. Can you post some example of invalid date that this kind of validation passes?

alierfani's avatar

@vitorarjol I think the conversion is taking place in the prepDeadline method, so by the time it is passed to the prepInput method it will be a valid datetime. That's why the validation passes.

bimalshah72's avatar
Level 6

@alierfani

Here is I think your final solution::

Run artisan commnad:

artisan make:middleware Deadline

your Deadline class,,

<?php

namespace App\Http\Middleware;

use Closure;

class Deadline
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $input = $request->all();
        $input['deadline'] = $this->prepDeadline($input['hour'], $input['month'], $input['day'], $input['year']);
        $request->replace($input);
        return $next($request);
    }
    private function prepDeadline($hour,$month,$day, $year){

        $time = jDateTime::mktime($hour, 0, 0, $month, $day, $year);
        return $deadline = strftime("%Y-%m-%d %H:%M:%S", $time);
    }
}

Register middle ware in Http/kernal.php

protected $routeMiddleware = [
        'auth' => 'App\Http\Middleware\Authenticate',
        'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
        'Apiauth' => 'App\Http\Middleware\ApiAuth', 
             'deadline' => 'App\Http\Middleware\Deadline'

    ];

in controller add constructor

 public function __construct()
    {      
        $this->middleware('deadline', ['only' => ['fooAction', 'barAction']]);   //put your method name in which you need this
    }
alierfani's avatar

@bimalshah72 Thank you very much for your answer. It almost solved my problem and the middleware is like this:

 public function handle($request, Closure $next)
    {
        $input = $request->all();
        $input['deadline'] = $this->prepDeadline($input['hour'], $input['month'], $input['day'], $input['year']);
        $request->replace($input);
        if(is_null($input['deadline'])){
            return redirect(to the same page with a message);
        }
        return $next($request);

    }
    public function prepDeadline($hour,$month,$day, $year){
        if( jDateTime::checkdate($month,$day, $year)) {
        $time = jDateTime::mktime($hour, 0, 0, $month, $day, $year);
        return $deadline = strftime("%Y-%m-%d %H:%M:%S", $time);
        }else{
           return null;
        }
    }

But now my problem is that how can I redirect dynamically (I'm using this middleware for more than one method) and notify the user that they have entered an invalid date?

bimalshah72's avatar

@alierfani

public function handle($request, Closure $next)
    {
        $input = $request->all();
        $input['deadline'] = $this->prepDeadline($input['hour'], $input['month'], $input['day'], $input['year']);
       
        if(is_null($input['deadline'])){
       $segments = $request->segments(); // it returns array of URL segments, iterate it / check it and redirect
            return redirect(to the same page with a message);
        }
     $request->replace($input); // replace only if $input['deadline'] is not null
        return $next($request);

    }
1 like
alierfani's avatar

@bimalshah72 The $segments returns the the wrong URL. For example, the form URl is projects/create but the $segments returns projects. I decided to use this one instead:

return Redirect::back()->with('message', 'Please select a valid date');

And to get the error message I have the following in the view:

@if(count($errors)>0)
            <div class="alert alert-danger">
                <ul >
                    @foreach($errors->all() as $error)
                        <li>{{$error}}</li>
                    @endforeach
                </ul>
            </div>
        @endif

but no errors are displayed.

Lanka's avatar

@vitorarjol public function rules() { return [ 'name' => 'required', 'begin_date' => 'required | date_format:"d/m/Y"|after:"2015-01-01"', 'end_date' => 'required | date_format:"d/m/Y"|after:begin_date' ]; } This is great we can use it to validate time (two time fields) also , (but have to use custom message ;) ) Many Thanks, Lanka

1 like

Please or to participate in this conversation.