2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Validator\Constraints ;
2018-11-23 12:29:20 +00:00
use Egulias\EmailValidator\Validation\EmailValidation ;
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation ;
2015-08-17 17:00:26 -07:00
use Symfony\Component\Validator\Constraint ;
use Symfony\Component\Validator\ConstraintValidator ;
use Symfony\Component\Validator\Exception\RuntimeException ;
use Symfony\Component\Validator\Exception\UnexpectedTypeException ;
/**
* @ author Bernhard Schussek < bschussek @ gmail . com >
*/
class EmailValidator extends ConstraintValidator
{
private $isStrict ;
2018-11-23 12:29:20 +00:00
/**
* @ param bool $strict
*/
2015-08-17 17:00:26 -07:00
public function __construct ( $strict = false )
{
$this -> isStrict = $strict ;
}
/**
* { @ inheritdoc }
*/
public function validate ( $value , Constraint $constraint )
{
if ( ! $constraint instanceof Email ) {
throw new UnexpectedTypeException ( $constraint , __NAMESPACE__ . '\Email' );
}
if ( null === $value || '' === $value ) {
return ;
}
2018-11-23 12:29:20 +00:00
if ( ! is_scalar ( $value ) && ! ( \is_object ( $value ) && method_exists ( $value , '__toString' ))) {
2015-08-17 17:00:26 -07:00
throw new UnexpectedTypeException ( $value , 'string' );
}
$value = ( string ) $value ;
if ( null === $constraint -> strict ) {
$constraint -> strict = $this -> isStrict ;
}
if ( $constraint -> strict ) {
2018-11-23 12:29:20 +00:00
if ( ! class_exists ( '\Egulias\EmailValidator\EmailValidator' )) {
throw new RuntimeException ( 'Strict email validation requires egulias/email-validator ~1.2|~2.0' );
2015-08-17 17:00:26 -07:00
}
$strictValidator = new \Egulias\EmailValidator\EmailValidator ();
2018-11-23 12:29:20 +00:00
if ( interface_exists ( EmailValidation :: class ) && ! $strictValidator -> isValid ( $value , new NoRFCWarningsValidation ())) {
2015-08-17 17:00:26 -07:00
$this -> context -> buildViolation ( $constraint -> message )
-> setParameter ( '{{ value }}' , $this -> formatValue ( $value ))
-> setCode ( Email :: INVALID_FORMAT_ERROR )
-> addViolation ();
2018-11-23 12:29:20 +00:00
return ;
} elseif ( ! interface_exists ( EmailValidation :: class ) && ! $strictValidator -> isValid ( $value , false , true )) {
$this -> context -> buildViolation ( $constraint -> message )
2015-08-17 17:00:26 -07:00
-> setParameter ( '{{ value }}' , $this -> formatValue ( $value ))
-> setCode ( Email :: INVALID_FORMAT_ERROR )
-> addViolation ();
2018-11-23 12:29:20 +00:00
return ;
2015-08-17 17:00:26 -07:00
}
2018-11-23 12:29:20 +00:00
} elseif ( ! preg_match ( '/^.+\@\S+\.\S+$/' , $value )) {
$this -> context -> buildViolation ( $constraint -> message )
-> setParameter ( '{{ value }}' , $this -> formatValue ( $value ))
-> setCode ( Email :: INVALID_FORMAT_ERROR )
-> addViolation ();
2015-08-17 17:00:26 -07:00
return ;
}
2017-07-03 16:47:07 +01:00
$host = ( string ) substr ( $value , strrpos ( $value , '@' ) + 1 );
2015-08-17 17:00:26 -07:00
// Check for host DNS resource records
if ( $constraint -> checkMX ) {
if ( ! $this -> checkMX ( $host )) {
2018-11-23 12:29:20 +00:00
$this -> context -> buildViolation ( $constraint -> message )
-> setParameter ( '{{ value }}' , $this -> formatValue ( $value ))
-> setCode ( Email :: MX_CHECK_FAILED_ERROR )
-> addViolation ();
2015-08-17 17:00:26 -07:00
}
return ;
}
if ( $constraint -> checkHost && ! $this -> checkHost ( $host )) {
2018-11-23 12:29:20 +00:00
$this -> context -> buildViolation ( $constraint -> message )
-> setParameter ( '{{ value }}' , $this -> formatValue ( $value ))
-> setCode ( Email :: HOST_CHECK_FAILED_ERROR )
-> addViolation ();
2015-08-17 17:00:26 -07:00
}
}
/**
* Check DNS Records for MX type .
*
* @ param string $host Host
*
* @ return bool
*/
private function checkMX ( $host )
{
2017-07-03 16:47:07 +01:00
return '' !== $host && checkdnsrr ( $host , 'MX' );
2015-08-17 17:00:26 -07:00
}
/**
* Check if one of MX , A or AAAA DNS RR exists .
*
* @ param string $host Host
*
* @ return bool
*/
private function checkHost ( $host )
{
2017-07-03 16:47:07 +01:00
return '' !== $host && ( $this -> checkMX ( $host ) || ( checkdnsrr ( $host , 'A' ) || checkdnsrr ( $host , 'AAAA' )));
2015-08-17 17:00:26 -07:00
}
}