Validation result

How to configure Server side Email form only allow business email address in Laravel using validation rule

This Post will cover server-side code configuration in Laravel by creating custom laravel validation rule free email and fetch remote URL free email domain list from the gist and running PHP preg match command.

Workspace requirements

  • Laravel (Basically PHP backend server-side validation)
  • Free domain list (Available on GitHub gist created by T. Brian Jones) URL: https://gist.github.com/tbrianjones/5992856

The last blog post I covered how to create Business email validation Client-side using jquery

where all requirements are in place we are going to continue the last session where the validation will also happen on the server-side.

Creating a Form POST method

Form Controller.

In form controller create a new public function where form post request will come.

public function postreqest(Request $request)
{
    dd($request->post('email'));
}

Add new POST route in web.php file

Route::post('/submit', 'FormController@postreqest')->name('submit');
adding post route in laravel

Update index.blade.php page Form by adding method and action. Where 

method="POST"
action="submit" // As web.php file post route name is submitted.
adding method and acion in form

Now submitting for its should show the die dump message post request.

Submitting Form dd message

The following exercises are confirming the POST request is reaching with the email address entered in a form.

Adding Validation Rule.

Now we will create a new Validation rule using Laravel Make Rule command

php artisan make:rule FreeEmailValidation
laravel make rule command

The following command will create a new PHP file Name “FreeEmailValidation.php” which is located in the rules folder.

laravel rules folder and file structure

The file contains 2 sections where we are focusing now.

  • Passes: We create Out Validation role code
  • Message: When passes rule fail the following message will return on form validation.

Use the following code in passes.

public function passes($attribute, $value)
 {
   $parts = explode('@', $value);
   $email = $parts[1];
   $url = "https://gist.githubusercontent.com/tbrianjones/5992856/raw/93213efb652749e226e69884d6c048e595c1280a/free_email_provider_domains.txt";
   $json = file_get_contents($url);
        if (preg_match("/{$email}/i", $json)) {
            return false;
       } else {
         return true;
        }
 }
passes function mail validation rule

The passes function will get an attribute and value where the value is pass by the controller.

In our case, we are getting an email which looks like [email protected] So we need to use PHP explode command to split the value into 2 parts by using @ and store in $parts. For the following mail, it will be.

$parts[0] = anyname
$parts[1] = anydomain.com

Then it will store second in $email variable. We will store the raw text of the free mail provider in the $url variable. $json will get file content of URL variable and store in $json.

Now, if also rule uses PHP preg_match command using regex function wherein the given domain name in $email variable match our passes function will return false and if in that list is not match it will return true.

Note: if the function will match the email domain from the list if its match. we don’t want to accept that email address that’s why if its match we return false validation.

In the message function just use the string which wants to return on validation fails. for example, I used “Please use your Business email”.

return message when validation fail

Configure Validation in Laravel Controller.

Now in our form controller postrequest function, the following code will be used.

public function postreqest(Request $request)
 {
   $data = request()->validate([
      'email' => ['required', 'email', new FreeEmailValidation],
   ]);
   return "Email Address Validated";
 }

In an email, validation array will use required, email and then our custom validation rule. If email validated its just return message and failed it will return an error that is updated in our index.blade.php file below source.

Note: don’t forget to add “use App\Rules\FreeEmailValidation;” form controller.

custom request validation in laravel controller

Now when the request where I removed the client-side jquery validation form, the error and success server-side validation result.

Validation result

SOURCE CODE:

FormController.php

use App\Rules\FreeEmailValidation;

class FormController extends Controller
{
    public function index()
    {
        return view('form.index');
    }

    public function postreqest(Request $request)
    {
        $data = request()->validate([
            'email' => ['required', 'email', new FreeEmailValidation],
        ]);

        return "Email Address Validated";
    }
    public function emailverify(Request $request)
    {
        $emailrequest = $request->get('email');
        $parts = explode('@', $emailrequest);
        $email = $parts[1];
        $url = "https://gist.githubusercontent.com/tbrianjones/5992856/raw/93213efb652749e226e69884d6c048e595c1280a/free_email_provider_domains.txt";
        $json = file_get_contents($url);

        if (preg_match("/{$email}/i", $json)) {
            return response()->json(false);
        } else {
            return response()->json(True);
        }
    }
}

index.blade.php

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <style>
        .error {
            color: red;
        }
    </style>
    <title>Anish Mandal</title>
</head>

<body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 offset-md-3 pt-5">
                <h2>Non Free Email Form Validation</h2>
                <form id='contactform' method="POST" action="submit">
                    @csrf
                    <div class="form-group">
                        <label for="exampleInputEmail1">Non Free Email address or Work/School Email</label>
                        <input type="email" class="form-control" name="email" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
                        <span class="error">{{$errors->first('email')}}</span>
                        <br>
                        <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>

                    </div>
                    <div class="form-group form-check">
                        <input type="checkbox" class="form-check-input" id="exampleCheck1">
                        <label class="form-check-label" for="exampleCheck1">Agree T & C</label>
                    </div>
                    <br>
                    <button type="submit" id="submit" class="btn btn-primary">Submit</button>
                </form>
            </div>
        </div>
    </div>

    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <!-- jQuery Validation -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js" integrity="sha256-sPB0F50YUDK0otDnsfNHawYmA5M0pjjUf4TvRJkGFrI=" crossorigin="anonymous"></script>


    <!-- Optional JavaScript -->
    <script>
        $(document).ready(function() {
            $("#submit").prop("disabled", "disabled");
            var $contactform = $("#contactform");

            $("input").on("blur keyup", function() {
                if ($contactform.valid()) {
                    $("#submit").prop("disabled", false);
                } else {
                    $("#submit").prop("disabled", "disabled");
                }
            });

            // Actual form
            $contactform.validate({
                errorElement: "div",
                rules: {
                    email: {
                        required: true,
                        email: true,
                        remote: "email/verify"
                    },
                },
                messages: {
                    email: {
                        required: "Email is Mandatory",
                        email: "Enter Valid Email",
                        remote: "Please use your Business email"
                    },
                }
            });
        });
    </script>

</body>

</html>

FreeEmailValidation.php

class FreeEmailValidation implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $parts = explode('@', $value);
        $email = $parts[1];
        $url = "https://gist.githubusercontent.com/tbrianjones/5992856/raw/93213efb652749e226e69884d6c048e595c1280a/free_email_provider_domains.txt";
        $json = file_get_contents($url);

        if (preg_match("/{$email}/i", $json)) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'Please use your Business email';
    }
}

Route File web.php

Route::get('/', 'FormController@index')->name('home');
Route::get('email/verify', 'FormController@emailverify')->name('email.verify');
Route::post('/submit', 'FormController@postreqest')->name('submit');