8000 [Validator] new email validation option to match with w3c official specification by guillemfondin · Pull Request #47872 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Validator] new email validation option to match with w3c official specification #47872

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Symfony/Component/Validator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CHANGELOG
6.2
---

* Add option `Email::VALIDATION_MODE_HTML5_ALLOW_NO_TLD` with "html5-allow-no-tld" e-mail validation mode, to match with the W3C official specification
* Add method `getCause()` to `ConstraintViolationInterface`
* Add the `When` constraint and validator
* Deprecate the "loose" e-mail validation mode, use "html5" instead
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/Validator/Constraints/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
class Email extends Constraint
{
public const VALIDATION_MODE_HTML5_ALLOW_NO_TLD = 'html5-allow-no-tld';
public const VALIDATION_MODE_HTML5 = 'html5';
public const VALIDATION_MODE_STRICT = 'strict';
/**
Expand All @@ -35,6 +36,7 @@ class Email extends Constraint
public const INVALID_FORMAT_ERROR = 'bd79c0ab-ddba-46cc-a703-a7a4b08de310';

public const VALIDATION_MODES = [
self::VALIDATION_MODE_HTML5_ALLOW_NO_TLD,
self::VALIDATION_MODE_HTML5,
self::VALIDATION_MODE_STRICT,
self::VALIDATION_MODE_LOOSE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
*/
class EmailValidator extends ConstraintValidator
{
private const PATTERN_HTML5_ALLOW_NO_TLD = '/^[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/';
private const PATTERN_HTML5 = '/^[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/';
private const PATTERN_LOOSE = '/^.+\@\S+\.\S+$/';

private const EMAIL_PATTERNS = [
Email::VALIDATION_MODE_LOOSE => self::PATTERN_LOOSE,
Email::VALIDATION_MODE_HTML5 => self::PATTERN_HTML5,
Email::VALIDATION_MODE_HTML5_ALLOW_NO_TLD => self::PATTERN_HTML5_ALLOW_NO_TLD,
];

private string $defaultMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ public function testConstructorStrict()
$this->assertEquals(Email::VALIDATION_MODE_STRICT, $subject->mode);
}

public function testConstructorHtml5AllowNoTld()
{
$subject = new Email(['mode' => Email::VALIDATION_MODE_HTML5_ALLOW_NO_TLD]);

$this->assertEquals(Email::VALIDATION_MODE_HTML5_ALLOW_NO_TLD, $subject->mode);
}

public function testUnknownModesTriggerException()
{
$this->expectException(InvalidArgumentException::class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,35 @@ public function getInvalidHtml5Emails()
];
}

/**
* @dataProvider getInvalidAllowNoTldEmails
*/
public function testInvalidAllowNoTldEmails($email)
{
$constraint = new Email([
'message' => 'myMessage',
'mode' => Email::VALIDATION_MODE_HTML5_ALLOW_NO_TLD,
]);

$this->validator->validate($email, $constraint);

$this->buildViolation('myMessage')
->setParameter('{{ value }}', '"'.$email.'"')
->setCode(Email::INVALID_FORMAT_ERROR)
->assertRaised();
}

public function getInvalidAllowNoTldEmails()
{
return [
['example bar'],
['example@'],
['example@ bar'],
['example@localhost bar'],
['foo@example.com bar'],
];
}

public function testModeStrict()
{
$constraint = new Email(['mode' => Email::VALIDATION_MODE_STRICT]);
Expand All @@ -253,6 +282,15 @@ public function testModeHtml5()
->assertRaised();
}

public function testModeHtml5AllowNoTld()
{
$constraint = new Email(['mode' => Email::VALIDATION_MODE_HTML5_ALLOW_NO_TLD]);

$this->validator->validate('example@example', $constraint);

$this->assertNoViolation();
}

/**
* @group legacy
*/
Expand Down
0