0

By default, Laravel's email validation does not fail on invalid email, eg 'example@example'.

$data = ['email' => 'example@example'];
$rules = ['email' => 'email'];
$v = Validator::make($data, $rules); // success

This would be ok, but it should be default:

$data = ['email' => 'example@example'];
$rules = ['email' => 'email:filter'];
$v = Validator::make($data, $rules); // fails

How can I set default e-mail validation policy?

Laravel version is 7.

2
  • 1
    Is it worth the effort to avoid writing ":filter" ? Commented Nov 27 at 15:48
  • Depends on the effort... :) But it's kinda silly for default validator not to catch such errors. Commented Dec 3 at 8:34

2 Answers 2

1

I don't think you can override the existing rules, but instead you can try adding new ones in app/providers/AppServiceProvider.php

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        \Validator::extend('email_default', function ($attribute, $value) {
            return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
        });
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Laravel 7 relies on the egulias/EmailValidator package for email validation. By default, the email rule is a shorthand for email:rfc. That's why using the stricter email:filter can catch invalid domain addresses.

You can introduce a new rule, but this does not solve the email problem - instead of creating a new rule, you can already use email:filter.

There is no way to override it directly. You could issue a patch for Laravel 7 that modifies the relevant part of the ValidatesAttributes file I quoted earlier.

Composer doesn't support this out of the box, but the cweagans/composer-patches package adds this capability.

composer require cweagans/composer-patches:~1.0

(A 2.x already requires PHP 8 support. Docs for 1.x: README.md)

composer.json

{
  "require": {
    "laravel/framework": "^7.30.7",
    "cweagans/composer-patches": "^1.0"
  },
  "extra": {
    "patches": {
      "laravel/framework": {
        "change-validation-email-default": "patches/laravel-framework-7-change-validation-email-default.patch"
      }
    }
  }
}

patches/laravel-framework-7-change-validation-email-default.patch

--- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php
+++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php
@@ -661,7 +661,7 @@ public function validateEmail($attribute, $value, $parameters)
                 }
             })
             ->values()
-            ->all() ?: [new RFCValidation()];
+            ->all() ?: [new FilterEmailValidation()];
 
         return (new EmailValidator)->isValid($value, new MultipleValidationWithAnd($validations));
     }

The settings will be applied automatically when running composer install, or you can apply them manually using the (1) composer patches-relock and (2) composer patch:reapply command.

Note: If the Laravel 7 ValidatesAttributes class ever receives an update, the patch file will need to be recreated. The simplest way is by using the git --diff command, or by creating a fork where you commit your modification, and when viewing that commit you can append .patch to the end of the URL.

Note: The patch file included in the answer was created after the 2021-12-06 commit, so it is valid for v7.30.6 and v7.30.7. (v7.30.6 also contained updates for the ValidatesAttributes class)

And then this way the email rule will point to email:filter instead of email:rfc.

2 Comments

Modifying built-in functionality is basically risky, because a new release can break the patch, but for such outdated versions that haven't received updates for years, retroactive patching is very useful. It's also better than manually editing the vendor folder, because this way the patch is automatically applied on every composer install.
Wow, thanks. That really answers my question :) Don't think I'll implement it though - risky, as pointed out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.