Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a8df1a2

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 a8df1a2

File tree

3 files changed

+90
-15
lines changed

3 files changed

+90
-15
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,13 @@ 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_STRICT = 'strict';
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;
3741
public $strict;
42+
public $mode;
3843
}

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

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,22 @@
2424
class EmailValidator extends ConstraintValidator
2525
{
2626
/**
27-
* @var bool
27+
* @var string
2828
*/
29-
private $isStrict;
29+
private $defaultMode;
3030

31-
public function __construct($strict = false)
31+
public function __construct($defaultMode = Email::VALIDATION_MODE_LOOSE)
3232
{
33-
$this->isStrict = $strict;
33+
switch ($defaultMode) {
34+
case Email::VALIDATION_MODE_HTML5:
35+
case Email::VALIDATION_MODE_STRICT:
36+
case Email::VALIDATION_MODE_LOOSE:
37+
break;
38+
default:
39+
$defaultMode = true === $defaultMode ? Email::VALIDATION_MODE_STRICT : Email::VALIDATION_MODE_LOOSE;
40+
}
41+
42+
$this->defaultMode = $defaultMode;
3443
}
3544

3645
/**
@@ -52,11 +61,11 @@ public function validate($value, Constraint $constraint)
5261

5362
$value = (string) $value;
5463

55-
if (null === $constraint->strict) {
56-
$constraint->strict = $this->isStrict;
64+
if (null === $constraint->mode) {
65+
$constraint->mode = $this->defaultMode;
5766
}
5867

59-
if ($constraint->strict) {
68+
if (Email::VALIDATION_MODE_STRICT === $constraint->mode) {
6069
if (!class_exists('\Egulias\EmailValidator\EmailValidator')) {
6170
throw new RuntimeException('Strict email validation requires egulias/email-validator ~1.2|~2.0');
6271
}
@@ -78,13 +87,27 @@ public function validate($value, Constraint $constraint)
7887

7988
return;
8089
}
81-
} elseif (!preg_match('/^.+\@\S+\.\S+$/', $value)) {
82-
$this->context->buildViolation($constraint->message)
83-
->setParameter('{{ value }}', $this->formatValue($value))
84-
->setCode(Email::INVALID_FORMAT_ERROR)
85-
->addViolation();
90+
} elseif (Email::VALIDATION_MODE_LOOSE === $constraint->mode) {
91+
if (!preg_match('/^.+\@\S+\.\S+$/', $value)) {
92+
$this->context->buildViolation($constraint->message)
93+
->setParameter('{{ value }}', $this->formatValue($value))
94+
->setCode(Email::INVALID_FORMAT_ERROR)
95+
->addViolation();
8696

87-
return;
97+
return;
98+
}
99+
} elseif (Email::VALIDATION_MODE_HTML5 === $constraint->mode) {
100+
if (!preg_match(
101+
'/^[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])?)+$/',
102+
$value
103+
)) {
104+
$this->context->buildViolation($constraint->message)
105+
->setParameter('{{ value }}', $this->formatValue($value))
106+
->setCode(Email::INVALID_FORMAT_ERROR)
107+
->addViolation();
108+
109+
return;
110+
}
88111
}
89112

90113
$host = (string) substr($value, strrpos($value, '@') + 1);

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

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,15 @@ public function testExpectsStringCompatibleType()
5454
public function testValidEmails($email)
5555
{
5656
$this->validator->validate($email, new Email());
57+
$this->assertNoViolation();
58+
}
5759

60+
/**
61+
* @dataProvider getValidEmails
62+
*/
63+
public function testValidEmailsHtml5($email)
64+
{
65+
$this->validator->validate($email, new Email(array('mode' => Email::VALIDATION_MODE_HTML5)));
5866
$this->assertNoViolation();
5967
}
6068

@@ -71,6 +79,24 @@ public function getValidEmails()
7179
* @dataProvider getInvalidEmails
7280
*/
7381
public function testInvalidEmails($email)
82+
{
83+
$constraint = new Email(array(
84+
'message' => 'myMessage',
85+
'mode' => Email::VALIDATION_MODE_LOOSE,
86+
));
87+
88+
$this->validator->validate($email, $constraint);
89+
90+
$this->buildViolation('myMessage')
91+
->setParameter('{{ value }}', '"'.$email.'"')
92+
->setCode(Email::INVALID_FORMAT_ERROR)
93+
->assertRaised();
94+
}
95+
96+
/**
97+
* @dataProvider getInvalidHtml5Emails
98+
*/
99+
public function testInvalidHtml5Emails($email)
74100
{
75101
$constraint = new Email(array(
76102
'message' => 'myMessage',
@@ -94,9 +120,30 @@ public function getInvalidEmails()
94120
);
95121
}
96122

123+
public function getInvalidHtml5Emails()
124+
{
125+
return array(
126+
array('example'),
127+
array('example@'),
128+
array('example@localhost'),
129+
130+
array('[email protected] bar'),
131+
array('example@example.'),
132+
133+
array('@example.com'),
134+
135+
array('example@.'),
136+
array(' [email protected]'),
137+
array('example@ '),
138+
array(' [email protected] '),
139+
array(' example @example .com '),
140+
141+
);
142+
}
143+
97144
public function testStrict()
98145
{
99-
$constraint = new Email(array('strict' => true));
146+
$constraint = new Email(array('mode' => Email::VALIDATION_MODE_STRICT));
100147

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

@@ -110,7 +157,7 @@ public function testStrictWithInvalidEmails($email)
110157
{
111158
$constraint = new Email(array(
112159
'message' => 'myMessage',
113-
'strict' => true,
160+
'strict' => false,
114161
));
115162

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

0 commit comments

Comments
 (0)