Laravel custom validation on registration form

All we need is an easy explanation of the problem, so here it is.

I’m currently struggling with a bit of validation on a registration form.

Basically when a user registers it will check if the unique code they have entered is valid and if not doesn’t let them sign up.

But in my codes table which this reads from I also have an expiry date on the code.

I need to do another check after it is deemed valid that the expiry date hasn’t passed, in other words it is not greater than now.

I think you can do this in the validator but I’m struggling a bit with the syntax and not sure where it should go. Here is my code:

protected function validator(array $data)
{

    return Validator::make($data, [
        'code' => 'required|exists:codes',
        'name' => 'required|max:255',
        'email' => 'required|email|max:255|unique:users',
        'date_of_birth' => 'required|date',
        'password' => 'required|min:6|confirmed',
        'accept_terms' => 'required|accepted',
    ]);
}

/**
 * Create a new user instance after a valid registration.
 *
 * @param  array  $data
 * @return User
 */
protected function create(array $data)
{   
    Code::where('code', $data['code'])->increment('uses');

    $data['code_id'] = Code::where('code', $data['code'])->value('id');

    return User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'date_of_birth' => $data['date_of_birth'],
        'accept_terms' => $data['accept_terms'],
        'code' => $data['code'],
        'code_id' => $data['code_id'],
        'password' => bcrypt($data['password']),
    ]);
}

Thanks in advance 🙂

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

As long as you’re using Laravel v5.3.18 (or higher) you can use the Rule Class to save you having to define a custom rule.

This:

'code' => 'required|exists:codes',

Can be replaced with:

'code' => [
    'required',
    Rule::exists('codes')->where(function ($query) {
        $query->where('expiry_date', '>=', Carbon::now());
    }),
],

(the above is assuming expiry_date is the actual name of the column in your db table).

Documentation: https://laravel.com/docs/5.3/validation#rule-exists

Just make sure you import those facades.

Hope this helps!

Method 2

You can create custom validation rule. Create service provider and register it. Then add something like this:

Validator::extend('is_code_valid', function($attribute, $value, $parameters, $validator) {
    $code = Code::where('code', $value)->where('date', '>', Carbon::now())->first();
    return !$code->isEmpty(); // Pass if valid code exists in DB.
});

And then use it:

'code' => 'required|is_code_valid',

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply