-
Notifications
You must be signed in to change notification settings - Fork 11.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[11.x] Add fluent Email
validation rule
#54067
Merged
+790
−2
Merged
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
e20a093
Add fluent `Email` validation rule
SanderMuller bee22d7
Fix style ci
SanderMuller 8b3fcb7
add descriptive method names for email validation rules
SanderMuller c2ef107
Apply review suggestions
SanderMuller 3ed80a9
fix typo
SanderMuller bacf4e0
formatting
taylorotwell f331f45
formatting
taylorotwell File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,343 @@ | ||
<?php | ||
|
||
namespace Illuminate\Validation\Rules; | ||
|
||
use Egulias\EmailValidator\EmailValidator; | ||
use Egulias\EmailValidator\Validation\DNSCheckValidation; | ||
use Egulias\EmailValidator\Validation\Extra\SpoofCheckValidation; | ||
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd; | ||
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation; | ||
use Egulias\EmailValidator\Validation\RFCValidation; | ||
use Illuminate\Container\Container; | ||
use Illuminate\Contracts\Support\Arrayable; | ||
use Illuminate\Contracts\Validation\DataAwareRule; | ||
use Illuminate\Contracts\Validation\Rule; | ||
use Illuminate\Contracts\Validation\ValidatorAwareRule; | ||
use Illuminate\Support\Arr; | ||
use Illuminate\Support\Collection; | ||
use Illuminate\Support\Facades\Validator; | ||
use Illuminate\Support\Str; | ||
use Illuminate\Support\Traits\Conditionable; | ||
use Illuminate\Support\Traits\Macroable; | ||
use Illuminate\Validation\Concerns\FilterEmailValidation; | ||
use InvalidArgumentException; | ||
use Stringable; | ||
use function Illuminate\Support\enum_value; | ||
|
||
class Email implements Rule, DataAwareRule, ValidatorAwareRule | ||
{ | ||
use Conditionable, Macroable; | ||
|
||
public bool $strict = false; | ||
|
||
public bool $dns = false; | ||
|
||
public bool $spoof = false; | ||
|
||
public bool $filter = false; | ||
|
||
public bool $filter_unicode = false; | ||
|
||
public bool $rfc = false; | ||
|
||
/** | ||
* An array of custom rules that will be merged into the validation rules. | ||
* | ||
* @var array | ||
*/ | ||
protected $customRules = []; | ||
|
||
/** | ||
* The error message after validation, if any. | ||
* | ||
* @var array | ||
*/ | ||
protected $messages = []; | ||
|
||
/** | ||
* The data under validation. | ||
* | ||
* @var array | ||
*/ | ||
protected $data; | ||
|
||
/** | ||
* The validator performing the validation. | ||
* | ||
* @var \Illuminate\Validation\Validator | ||
*/ | ||
protected $validator; | ||
|
||
/** | ||
* The callback that will generate the "default" version of the file rule. | ||
* | ||
* @var string|array|callable|null | ||
*/ | ||
public static $defaultCallback; | ||
|
||
/** | ||
* Set the default callback to be used for determining the email default rules. | ||
* | ||
* If no arguments are passed, the default email rule configuration will be returned. | ||
* | ||
* @param static|callable|null $callback | ||
* @return static|void | ||
*/ | ||
public static function defaults($callback = null) | ||
{ | ||
if (is_null($callback)) { | ||
return static::default(); | ||
} | ||
|
||
if (! is_callable($callback) && ! $callback instanceof static) { | ||
throw new InvalidArgumentException('The given callback should be callable or an instance of '.static::class); | ||
} | ||
|
||
static::$defaultCallback = $callback; | ||
} | ||
|
||
/** | ||
* Get the default configuration of the file rule. | ||
* | ||
* @return static | ||
*/ | ||
public static function default() | ||
{ | ||
$email = is_callable(static::$defaultCallback) | ||
? call_user_func(static::$defaultCallback) | ||
: static::$defaultCallback; | ||
|
||
return $email instanceof self ? $email : new self(); | ||
} | ||
|
||
/** | ||
* A strict rule set which includes DNS and Spoof checks. | ||
* | ||
* @return static | ||
*/ | ||
public static function strictSecurity() | ||
{ | ||
return (new self())->strict()->dns()->spoof(); | ||
} | ||
|
||
/** | ||
* Validate against NoRFCWarningsValidation. | ||
* | ||
* @return $this | ||
*/ | ||
public function strict() | ||
{ | ||
$this->strict = true; | ||
|
||
return $this; | ||
} | ||
SanderMuller marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Validate against DNSCheckValidation. | ||
* Requires the PHP intl extension. | ||
* | ||
* @return $this | ||
*/ | ||
public function dns() | ||
{ | ||
$this->dns = true; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Validate against SpoofCheckValidation. | ||
* Requires the PHP intl extension. | ||
* | ||
* @return $this | ||
*/ | ||
public function spoof() | ||
{ | ||
$this->spoof = true; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Validate against FilterEmailValidation. | ||
* | ||
* @return $this | ||
*/ | ||
public function filter() | ||
{ | ||
$this->filter = true; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Validate against FilterEmailValidation::unicode(). | ||
* | ||
* @return $this | ||
*/ | ||
public function filterUnicode() | ||
{ | ||
$this->filter_unicode = true; | ||
|
||
return $this; | ||
} | ||
SanderMuller marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Validate against RFCValidation. | ||
* | ||
* @return $this | ||
*/ | ||
public function rfc() | ||
{ | ||
$this->rfc = true; | ||
|
||
return $this; | ||
} | ||
SanderMuller marked this conversation as resolved.
Show resolved
Hide resolved
SanderMuller marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Specify additional validation rules that should be merged with the default rules during validation. | ||
* | ||
* @param string|array $rules | ||
* @return $this | ||
*/ | ||
public function rules($rules) | ||
{ | ||
$this->customRules = array_merge($this->customRules, Arr::wrap($rules)); | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Determine if the validation rule passes. | ||
* | ||
* @param string $attribute | ||
* @param mixed $value | ||
* @return bool | ||
*/ | ||
public function passes($attribute, $value) | ||
{ | ||
$this->messages = []; | ||
|
||
if (! is_string($value) && ! (is_object($value) && method_exists($value, '__toString'))) { | ||
return false; | ||
} | ||
|
||
$emailValidator = Container::getInstance()->make(EmailValidator::class); | ||
|
||
$passes = $emailValidator->isValid((string) $value, new MultipleValidationWithAnd($this->buildValidationRules())); | ||
|
||
if (! $passes) { | ||
$this->messages = [trans('validation.email', ['attribute' => $attribute])]; | ||
|
||
return false; | ||
} | ||
|
||
if ($this->customRules) { | ||
$validator = Validator::make( | ||
$this->data, | ||
[$attribute => $this->customRules], | ||
$this->validator->customMessages, | ||
$this->validator->customAttributes | ||
); | ||
|
||
if ($validator->fails()) { | ||
return $this->fail($validator->messages()->all()); | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Build the array of underlying validation rules based on the current state. | ||
* | ||
* @return array | ||
*/ | ||
protected function buildValidationRules() | ||
{ | ||
$rules = []; | ||
|
||
if ($this->rfc) { | ||
$rules[] = new RFCValidation; | ||
} | ||
|
||
if ($this->strict) { | ||
$rules[] = new NoRFCWarningsValidation; | ||
} | ||
|
||
if ($this->dns) { | ||
$rules[] = new DNSCheckValidation; | ||
} | ||
|
||
if ($this->spoof) { | ||
$rules[] = new SpoofCheckValidation; | ||
} | ||
|
||
if ($this->filter) { | ||
$rules[] = new FilterEmailValidation; | ||
} | ||
|
||
if ($this->filter_unicode) { | ||
$rules[] = FilterEmailValidation::unicode(); | ||
} | ||
|
||
if ($rules) { | ||
return $rules; | ||
} | ||
|
||
return [new RFCValidation]; | ||
} | ||
|
||
/** | ||
* Adds the given failures, and return false. | ||
* | ||
* @param array|string $messages | ||
* @return bool | ||
*/ | ||
protected function fail($messages) | ||
{ | ||
$messages = Collection::wrap($messages) | ||
->map(fn ($message) => $this->validator->getTranslator()->get($message)) | ||
->all(); | ||
|
||
$this->messages = array_merge($this->messages, $messages); | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* Get the validation error message. | ||
* | ||
* @return array | ||
*/ | ||
public function message() | ||
{ | ||
return $this->messages; | ||
} | ||
|
||
/** | ||
* Set the current validator. | ||
* | ||
* @param \Illuminate\Contracts\Validation\Validator $validator | ||
* @return $this | ||
*/ | ||
public function setValidator($validator) | ||
{ | ||
$this->validator = $validator; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Set the current data under validation. | ||
* | ||
* @param array $data | ||
* @return $this | ||
*/ | ||
public function setData($data) | ||
{ | ||
$this->data = $data; | ||
|
||
return $this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,7 +86,7 @@ class File implements Rule, DataAwareRule, ValidatorAwareRule | |
* If no arguments are passed, the default file rule configuration will be returned. | ||
* | ||
* @param static|callable|null $callback | ||
* @return static|null | ||
* @return static|void | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. never returns
SanderMuller marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
public static function defaults($callback = null) | ||
{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heavily inspired by
src/Illuminate/Validation/Rules/File.php