cdd162d816f98d9095f0616000c50e021191399c
[yaffs-website] / vendor / symfony / validator / Constraints / EmailValidator.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Validator\Constraints;
13
14 use Symfony\Component\Validator\Context\ExecutionContextInterface;
15 use Symfony\Component\Validator\Constraint;
16 use Symfony\Component\Validator\ConstraintValidator;
17 use Symfony\Component\Validator\Exception\RuntimeException;
18 use Symfony\Component\Validator\Exception\UnexpectedTypeException;
19
20 /**
21  * @author Bernhard Schussek <bschussek@gmail.com>
22  */
23 class EmailValidator extends ConstraintValidator
24 {
25     /**
26      * @var bool
27      */
28     private $isStrict;
29
30     public function __construct($strict = false)
31     {
32         $this->isStrict = $strict;
33     }
34
35     /**
36      * {@inheritdoc}
37      */
38     public function validate($value, Constraint $constraint)
39     {
40         if (!$constraint instanceof Email) {
41             throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Email');
42         }
43
44         if (null === $value || '' === $value) {
45             return;
46         }
47
48         if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
49             throw new UnexpectedTypeException($value, 'string');
50         }
51
52         $value = (string) $value;
53
54         if (null === $constraint->strict) {
55             $constraint->strict = $this->isStrict;
56         }
57
58         if ($constraint->strict) {
59             if (!class_exists('\Egulias\EmailValidator\EmailValidator') || interface_exists('\Egulias\EmailValidator\Validation\EmailValidation')) {
60                 throw new RuntimeException('Strict email validation requires egulias/email-validator:~1.2');
61             }
62
63             $strictValidator = new \Egulias\EmailValidator\EmailValidator();
64
65             if (!$strictValidator->isValid($value, false, true)) {
66                 if ($this->context instanceof ExecutionContextInterface) {
67                     $this->context->buildViolation($constraint->message)
68                         ->setParameter('{{ value }}', $this->formatValue($value))
69                         ->setCode(Email::INVALID_FORMAT_ERROR)
70                         ->addViolation();
71                 } else {
72                     $this->buildViolation($constraint->message)
73                         ->setParameter('{{ value }}', $this->formatValue($value))
74                         ->setCode(Email::INVALID_FORMAT_ERROR)
75                         ->addViolation();
76                 }
77
78                 return;
79             }
80         } elseif (!preg_match('/^.+\@\S+\.\S+$/', $value)) {
81             if ($this->context instanceof ExecutionContextInterface) {
82                 $this->context->buildViolation($constraint->message)
83                     ->setParameter('{{ value }}', $this->formatValue($value))
84                     ->setCode(Email::INVALID_FORMAT_ERROR)
85                     ->addViolation();
86             } else {
87                 $this->buildViolation($constraint->message)
88                     ->setParameter('{{ value }}', $this->formatValue($value))
89                     ->setCode(Email::INVALID_FORMAT_ERROR)
90                     ->addViolation();
91             }
92
93             return;
94         }
95
96         $host = (string) substr($value, strrpos($value, '@') + 1);
97
98         // Check for host DNS resource records
99         if ($constraint->checkMX) {
100             if (!$this->checkMX($host)) {
101                 if ($this->context instanceof ExecutionContextInterface) {
102                     $this->context->buildViolation($constraint->message)
103                         ->setParameter('{{ value }}', $this->formatValue($value))
104                         ->setCode(Email::MX_CHECK_FAILED_ERROR)
105                         ->addViolation();
106                 } else {
107                     $this->buildViolation($constraint->message)
108                         ->setParameter('{{ value }}', $this->formatValue($value))
109                         ->setCode(Email::MX_CHECK_FAILED_ERROR)
110                         ->addViolation();
111                 }
112             }
113
114             return;
115         }
116
117         if ($constraint->checkHost && !$this->checkHost($host)) {
118             if ($this->context instanceof ExecutionContextInterface) {
119                 $this->context->buildViolation($constraint->message)
120                     ->setParameter('{{ value }}', $this->formatValue($value))
121                     ->setCode(Email::HOST_CHECK_FAILED_ERROR)
122                     ->addViolation();
123             } else {
124                 $this->buildViolation($constraint->message)
125                     ->setParameter('{{ value }}', $this->formatValue($value))
126                     ->setCode(Email::HOST_CHECK_FAILED_ERROR)
127                     ->addViolation();
128             }
129         }
130     }
131
132     /**
133      * Check DNS Records for MX type.
134      *
135      * @param string $host Host
136      *
137      * @return bool
138      */
139     private function checkMX($host)
140     {
141         return '' !== $host && checkdnsrr($host, 'MX');
142     }
143
144     /**
145      * Check if one of MX, A or AAAA DNS RR exists.
146      *
147      * @param string $host Host
148      *
149      * @return bool
150      */
151     private function checkHost($host)
152     {
153         return '' !== $host && ($this->checkMX($host) || (checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA')));
154     }
155 }