Skip to content

Commit 2ce7aed

Browse files
committed
[Validator] Html5 Email Validation
Currently we only support a very loose validation. There is now a standard HTML5 element with matching regex. This will add the ability to set a "Mode" on the email validator. The mode will change the validation that is applied to the field as a whole. These modes are: * RFC - Previously called "strict" * HTML5 * Loose
1 parent 522d079 commit 2ce7aed

File tree

3 files changed

+41
-26
lines changed

3 files changed

+41
-26
lines changed

src/Symfony/Component/Validator/Constraints/Email.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ class Email extends Constraint
3131
self::HOST_CHECK_FAILED_ERROR => 'HOST_CHECK_FAILED_ERROR',
3232
);
3333

34+
const VALIDATION_MODE_HTML5 = 'html5';
35+
const VALIDATION_MODE_RFC = 'rfc';
36+
const VALIDATION_MODE_LOOSE = 'loose';
37+
3438
public $message = 'This value is not a valid email address.';
3539
public $checkMX = false;
3640
public $checkHost = false;
37-
public $strict;
41+
public $mode = 'html5';
3842
}

src/Symfony/Component/Validator/Constraints/EmailValidator.php

+30-18
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@
2424
class EmailValidator extends ConstraintValidator
2525
{
2626
/**
27-
* @var bool
27+
* @var string
2828
*/
29-
private $isStrict;
29+
private $mode;
3030

31-
public function __construct($strict = false)
31+
public function __construct($mode = 'html5')
3232
{
33-
$this->isStrict = $strict;
33+
$this->mode = $mode;
3434
}
3535

3636
/**
@@ -52,33 +52,45 @@ public function validate($value, Constraint $constraint)
5252

5353
$value = (string) $value;
5454

55-
if (null === $constraint->strict) {
56-
$constraint->strict = $this->isStrict;
55+
if (null === $constraint->mode) {
56+
$constraint->mode = $this->mode;
5757
}
5858

59-
if ($constraint->strict) {
59+
var_dump($constraint->mode);
60+
61+
if ($constraint->mode === Email::VALIDATION_MODE_RFC) {
6062
if (!class_exists('\Egulias\EmailValidator\EmailValidator')) {
61-
throw new RuntimeException('Strict email validation requires egulias/email-validator ~1.2|~2.0');
63+
throw new RuntimeException('RFC email validation requires egulias/email-validator ~1.2|~2.0');
6264
}
6365

64-
$strictValidator = new \Egulias\EmailValidator\EmailValidator();
66+
$rfcValidator = new \Egulias\EmailValidator\EmailValidator();
6567

66-
if (interface_exists(EmailValidation::class) && !$strictValidator->isValid($value, new NoRFCWarningsValidation())) {
68+
if (interface_exists(EmailValidation::class) && !$rfcValidator->isValid($value, new NoRFCWarningsValidation())) {
6769
$this->context->buildViolation($constraint->message)
68-
->setParameter('{{ value }}', $this->formatValue($value))
69-
->setCode(Email::INVALID_FORMAT_ERROR)
70-
->addViolation();
70+
->setParameter('{{ value }}', $this->formatValue($value))
71+
->setCode(Email::INVALID_FORMAT_ERROR)
72+
->addViolation();
7173

7274
return;
73-
} elseif (!interface_exists(EmailValidation::class) && !$strictValidator->isValid($value, false, true)) {
75+
} elseif (!interface_exists(EmailValidation::class) && !$rfcValidator->isValid($value, false, true)) {
7476
$this->context->buildViolation($constraint->message)
75-
->setParameter('{{ value }}', $this->formatValue($value))
76-
->setCode(Email::INVALID_FORMAT_ERROR)
77-
->addViolation();
77+
->setParameter('{{ value }}', $this->formatValue($value))
78+
->setCode(Email::INVALID_FORMAT_ERROR)
79+
->addViolation();
7880

7981
return;
8082
}
81-
} elseif (!preg_match('/^.+\@\S+\.\S+$/', $value)) {
83+
} elseif ($constraint->mode === Email::VALIDATION_MODE_LOOSE && preg_match('/^.+\@\S+\.\S+$/', $value)) {
84+
$this->context->buildViolation($constraint->message)
85+
->setParameter('{{ value }}', $this->formatValue($value))
86+
->setCode(Email::INVALID_FORMAT_ERROR)
87+
->addViolation();
88+
89+
return;
90+
} elseif ($constraint->mode === Email::VALIDATION_MODE_HTML5 && preg_match(
91+
'/^[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])?)+$/',
92+
$value
93+
)) {
8294
$this->context->buildViolation($constraint->message)
8395
->setParameter('{{ value }}', $this->formatValue($value))
8496
->setCode(Email::INVALID_FORMAT_ERROR)

src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php

+6-7
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ public function testExpectsStringCompatibleType()
5454
public function testValidEmails($email)
5555
{
5656
$this->validator->validate($email, new Email());
57-
5857
$this->assertNoViolation();
5958
}
6059

@@ -94,23 +93,23 @@ public function getInvalidEmails()
9493
);
9594
}
9695

97-
public function testStrict()
96+
public function testRfc()
9897
{
99-
$constraint = new Email(array('strict' => true));
98+
$constraint = new Email(array('mode' => 'rfc'));
10099

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

103102
$this->assertNoViolation();
104103
}
105104

106105
/**
107-
* @dataProvider getInvalidEmailsForStrictChecks
106+
* @dataProvider getInvalidEmailsForRfcChecks
108107
*/
109-
public function testStrictWithInvalidEmails($email)
108+
public function testRfcWithInvalidEmails($email)
110109
{
111110
$constraint = new Email(array(
112111
'message' => 'myMessage',
113-
'strict' => true,
112+
'mode' => 'rfc',
114113
));
115114

116115
$this->validator->validate($email, $constraint);
@@ -125,7 +124,7 @@ public function testStrictWithInvalidEmails($email)
125124
/**
126125
* @see https://github.com/egulias/EmailValidator/blob/1.2.8/tests/egulias/Tests/EmailValidator/EmailValidatorTest.php
127126
*/
128-
public function getInvalidEmailsForStrictChecks()
127+
public function getInvalidEmailsForRfcChecks()
129128
{
130129
return array(
131130
array('test@example.com test'),

0 commit comments

Comments
 (0)