#1581 - Strict in Email constraint and use of Egulias\EmailValidator

This commit is contained in:
Eduardo Gulias Davis 2013-09-19 18:03:48 +02:00 committed by Fabien Potencier
parent e0de9586aa
commit 3368630482
10 changed files with 89 additions and 7 deletions

View File

@ -44,3 +44,31 @@ Form
public function getErrors($deep = false, $flatten = true)
{
```
Validator
---------
* EmailValidator has changed to allow `non-strict` and `strict` email validation
Before:
Email validation was done with php's `filter_var()`
After:
Default email validation is now done via a simple regex which may cause invalid emails (not RFC compilant) to be
valid. This is the default behaviour.
Strict email validation has to be explicitly activated in the configuration file by adding
```
framework_bundle:
//...
validation:
strict_email: true
//...
```
Also you have to add to your composer.json:
```
"egulias/email-validator": "1.1.*"
```

View File

@ -73,7 +73,8 @@
"monolog/monolog": "~1.3",
"propel/propel1": "1.6.*",
"ircmaxell/password-compat": "1.0.*",
"ocramius/proxy-manager": ">=0.3.1,<0.6-dev"
"ocramius/proxy-manager": ">=0.3.1,<0.6-dev",
"egulias/email-validator": "1.1.0"
},
"autoload": {
"psr-0": { "Symfony\\": "src/" },

View File

@ -445,6 +445,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('cache')->end()
->booleanNode('enable_annotations')->defaultFalse()->end()
->scalarNode('translation_domain')->defaultValue('validators')->end()
->booleanNode('strict_email')->defaultFalse()->end()
->end()
->end()
->end()

View File

@ -678,6 +678,9 @@ class FrameworkExtension extends Extension
$container->setParameter('validator.mapping.loader.xml_files_loader.mapping_files', $this->getValidatorXmlMappingFiles($container));
$container->setParameter('validator.mapping.loader.yaml_files_loader.mapping_files', $this->getValidatorYamlMappingFiles($container));
$definition = $container->findDefinition('validator.email');
$definition->replaceArgument(0, $config['strict_email']);
if (array_key_exists('enable_annotations', $config) && $config['enable_annotations']) {
$loaderChain = $container->getDefinition('validator.mapping.loader.loader_chain');
$arguments = $loaderChain->getArguments();

View File

@ -18,6 +18,7 @@
<parameter key="validator.mapping.loader.xml_files_loader.mapping_files" type="collection" />
<parameter key="validator.mapping.loader.yaml_files_loader.mapping_files" type="collection" />
<parameter key="validator.expression.class">Symfony\Component\Validator\Constraints\ExpressionValidator</parameter>
<parameter key="validator.email.class">Symfony\Component\Validator\Constraints\EmailValidator</parameter>
</parameters>
<services>
@ -69,5 +70,10 @@
<argument type="service" id="property_accessor" />
<tag name="validator.constraint_validator" alias="validator.expression" />
</service>
<service id="validator.email" class="%validator.email.class%">
<argument></argument>
<tag name="validator.constraint_validator" alias="validator.email" />
</service>
</services>
</container>

View File

@ -127,6 +127,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase
'enabled' => false,
'enable_annotations' => false,
'translation_domain' => 'validators',
'strict_email' => false,
),
'annotations' => array(
'cache' => 'file',

View File

@ -25,4 +25,13 @@ class Email extends Constraint
public $message = 'This value is not a valid email address.';
public $checkMX = false;
public $checkHost = false;
public $strict = null;
/**
* {@inheritDoc}
*/
public function validatedBy()
{
return 'validator.email';
}
}

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Egulias\EmailValidator\EmailValidator as StrictEmailValidator;
/**
* @author Bernhard Schussek <bschussek@gmail.com>
@ -22,6 +23,18 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
*/
class EmailValidator extends ConstraintValidator
{
/**
* isStrict
*
* @var Boolean
*/
private $isStrict;
public function __construct($strict = false)
{
$this->isStrict = $strict;
}
/**
* {@inheritDoc}
*/
@ -40,12 +53,23 @@ class EmailValidator extends ConstraintValidator
}
$value = (string) $value;
$valid = filter_var($value, FILTER_VALIDATE_EMAIL);
if (null === $constraint->strict) {
$constraint->strict = $this->isStrict;
}
if ($constraint->strict && class_exists('\Egulias\EmailValidator\EmailValidator')) {
$strictValidator = new StrictEmailValidator();
$valid = $strictValidator->isValid($value, false);
} elseif ($constraint->strict === true) {
throw new \RuntimeException('Strict email validation requires egulias/email-validator');
} else {
$valid = preg_match('/.+\@.+\..+/', $value);
}
if ($valid) {
$host = substr($value, strpos($value, '@') + 1);
// Check for host DNS resource records
if ($valid && $constraint->checkMX) {
$valid = $this->checkMX($host);
} elseif ($valid && $constraint->checkHost) {

View File

@ -22,7 +22,7 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
$this->validator = new EmailValidator();
$this->validator = new EmailValidator(false);
$this->validator->initialize($this->context);
}
@ -100,7 +100,14 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
array('example'),
array('example@'),
array('example@localhost'),
array('example@example.com@example.com'),
);
}
public function testStrict()
{
$this->context->expects($this->never())
->method('addViolation');
$this->validator->validate('example@localhost', new Email(array('strict' => true)));
}
}

View File

@ -26,7 +26,8 @@
"symfony/yaml": "~2.0",
"symfony/config": "~2.2",
"doctrine/annotations": "~1.0",
"doctrine/cache": "~1.0"
"doctrine/cache": "~1.0",
"egulias/email-validator": "~1.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
@ -34,7 +35,8 @@
"symfony/http-foundation": "",
"symfony/intl": "",
"symfony/yaml": "",
"symfony/config": ""
"symfony/config": "",
"egulias/email-validator": "Strict (RFC compliant) email validation"
},
"autoload": {
"psr-0": { "Symfony\\Component\\Validator\\": "" }