Passed
Pull Request — master (#222)
by Alexander
02:58
created

Email   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Test Coverage

Coverage 97.73%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 47
dl 0
loc 131
ccs 43
cts 44
cp 0.9773
rs 10
c 3
b 0
f 0
wmc 21
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Attribute;
8
use Closure;
9
use JetBrains\PhpStorm\ArrayShape;
10
use RuntimeException;
11
use Yiisoft\Validator\Rule\Trait\RuleNameTrait;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_TRAIT, expecting T_STRING or '{' on line 11 at column 27
Loading history...
12
use Yiisoft\Validator\Rule\Trait\HandlerClassNameTrait;
13
use Yiisoft\Validator\ParametrizedRuleInterface;
14
use function function_exists;
15
16
/**
17
 * Validates that the value is a valid email address.
18
 */
19
#[Attribute(Attribute::TARGET_PROPERTY)]
20
final class Email implements ParametrizedRuleInterface
21
{
22
    use HandlerClassNameTrait;
23
    use RuleNameTrait;
24
25
    public function __construct(
26
        /**
27
         * @var string the regular expression used to validate value.
28
         *
29
         * @link http://www.regular-expressions.info/email.html
30
         */
31
        private string $pattern = '/^[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/',
32
        /**
33
         * @var string the regular expression used to validate email addresses with the name part. This property is used
34
         * only when {@see $allowName} is `true`.
35
         *
36
         * @see $allowName
37
         */
38
        private string $fullPattern = '/^[^@]*<[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?>$/',
39
        /**
40
         * @var string the regular expression used to validate complex emails when {@see $enableIDN} is `true`.
41
         */
42
        private string $idnEmailPattern = '/^([a-zA-Z0-9._%+-]+)@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|\d{1,3})(\]?)$/',
43
        /**
44
         * @var bool whether to allow name in the email address (e.g. "John Smith <[email protected]>"). Defaults
45
         * to `false`.
46
         *
47
         * @see $fullPattern
48
         */
49
        private bool $allowName = false,
50
        /**
51
         * @var bool whether to check whether the email's domain exists and has either an A or MX record.
52
         * Be aware that this check can fail due to temporary DNS problems even if the email address is
53
         * valid and an email would be deliverable. Defaults to `false`.
54
         */
55
        private bool $checkDNS = false,
56
        /**
57
         * @var bool whether validation process should take into account IDN (internationalized domain
58
         * names). Defaults to false meaning that validation of emails containing IDN will always fail.
59
         * Note that in order to use IDN validation you have to install and enable `intl` PHP extension,
60
         * otherwise an exception would be thrown.
61
         */
62
        private bool $enableIDN = false,
63
        private string $message = 'This value is not a valid email address.',
64
        private bool $skipOnEmpty = false,
65
        private bool $skipOnError = false,
66
        private ?Closure $when = null,
67
    ) {
68
        if ($enableIDN && !function_exists('idn_to_ascii')) {
69
            throw new RuntimeException('In order to use IDN validation intl extension must be installed and enabled.');
70
        }
71
    }
72
73
    /**
74
     * @return string
75
     */
76 73
    public function getPattern(): string
77
    {
78 73
        return $this->pattern;
79
    }
80
81
    /**
82
     * @return string
83
     */
84 20
    public function getFullPattern(): string
85
    {
86 20
        return $this->fullPattern;
87
    }
88
89
    /**
90
     * @return string
91
     */
92 10
    public function getIdnEmailPattern(): string
93
    {
94 10
        return $this->idnEmailPattern;
95
    }
96
97
    /**
98
     * @return bool
99
     */
100 47
    public function isAllowName(): bool
101
    {
102 47
        return $this->allowName;
103
    }
104
105
    /**
106
     * @return bool
107
     */
108 39
    public function isCheckDNS(): bool
109
    {
110 39
        return $this->checkDNS;
111
    }
112
113
    /**
114
     * @return bool
115
     */
116 83
    public function isEnableIDN(): bool
117
    {
118 83
        return $this->enableIDN;
119
    }
120
121
    /**
122
     * @return string
123
     */
124 45
    public function getMessage(): string
125
    {
126 45
        return $this->message;
127
    }
128
129
    /**
130
     * @return bool
131
     */
132
    public function isSkipOnEmpty(): bool
133
    {
134
        return $this->skipOnEmpty;
135
    }
136
137
    /**
138
     * @return bool
139
     */
140
    public function isSkipOnError(): bool
141
    {
142
        return $this->skipOnError;
143
    }
144
145
    /**
146
     * @return Closure|null
147
     */
148
    public function getWhen(): ?Closure
149
    {
150
        return $this->when;
151
    }
152
153 4
    #[ArrayShape([
154
        'pattern' => 'string',
155
        'fullPattern' => 'string',
156
        'idnEmailPattern' => 'string',
157
        'allowName' => 'bool',
158
        'checkDNS' => 'bool',
159
        'enableIDN' => 'bool',
160
        'message' => 'string[]',
161
        'skipOnEmpty' => 'bool',
162
        'skipOnError' => 'bool',
163
    ])]
164
    public function getOptions(): array
165
    {
166
        return [
167 4
            'pattern' => $this->pattern,
168 4
            'fullPattern' => $this->fullPattern,
169 4
            'idnEmailPattern' => $this->idnEmailPattern,
170 4
            'allowName' => $this->allowName,
171 4
            'checkDNS' => $this->checkDNS,
172 4
            'enableIDN' => $this->enableIDN,
173
            'message' => [
174 4
                'message' => $this->message,
175
            ],
176 4
            'skipOnEmpty' => $this->skipOnEmpty,
177 4
            'skipOnError' => $this->skipOnError,
178
        ];
179
    }
180
}
181