Passed
Pull Request — master (#477)
by Alexander
13:25 queued 10:58
created

Email::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 81
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 2
nc 2
nop 11
dl 0
loc 81
ccs 9
cts 9
cp 1
crap 3
rs 10
c 0
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\Language;
10
use RuntimeException;
11
use Yiisoft\Validator\Rule\Trait\SkipOnEmptyTrait;
12
use Yiisoft\Validator\Rule\Trait\SkipOnErrorTrait;
13
use Yiisoft\Validator\Rule\Trait\WhenTrait;
14
use Yiisoft\Validator\RuleWithOptionsInterface;
15
use Yiisoft\Validator\SkipOnEmptyInterface;
16
use Yiisoft\Validator\SkipOnErrorInterface;
17
use Yiisoft\Validator\WhenInterface;
18
19
use function function_exists;
20
21
/**
22
 * Validates that the value is a valid email address.
23
 *
24
 * @psalm-import-type WhenType from WhenInterface
25
 */
26
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
27
final class Email implements RuleWithOptionsInterface, SkipOnErrorInterface, WhenInterface, SkipOnEmptyInterface
28
{
29
    use SkipOnEmptyTrait;
30
    use SkipOnErrorTrait;
31
    use WhenTrait;
32 3
33
    public function __construct(
34
        #[Language('RegExp')]
35
        /**
36
         * @var string The regular expression used to validate the value.
37
         *
38
         * @link https://www.regular-expressions.info/email.html
39
         */
40
        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])?$/',
41
        #[Language('RegExp')]
42
        /**
43
         * @var string The regular expression used to validate email addresses with the name part.
44
         * This property is used only when {@see $allowName} is `true`.
45
         *
46
         * @see $allowName
47
         */
48
        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])?>$/',
49
        #[Language('RegExp')]
50
        /**
51
         * @var string The regular expression used to validate complex emails when {@see $enableIDN} is `true`.
52
         */
53
        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})(\]?)$/',
54
        /**
55
         * @var bool Whether to allow a name in the email address (e.g. "John Smith <[email protected]>").
56
         * Defaults to `false`.
57
         *
58
         * @see $fullPattern
59
         */
60
        private bool $allowName = false,
61
        /**
62
         * @var bool Whether to check email's domain exists and has either an A or MX record.
63
         * Be aware that this check can fail due to temporary DNS problems even if the email address is
64
         * valid and an email would be deliverable. Defaults to `false`.
65
         */
66
        private bool $checkDNS = false,
67
        /**
68
         * @var bool Whether validation process should take IDN (internationalized domain names) into account.
69
         * Defaults to false meaning that validation of emails containing IDN will always fail.
70
         * Note that in order to use IDN validation you have to install and enable `intl` PHP extension,
71
         * otherwise an exception would be thrown.
72
         */
73
        private bool $enableIDN = false,
74
        /**
75
         * @var string A message used when the input is incorrect.
76
         *
77
         * You may use the following placeholders in the message:
78
         *
79
         * - `{attribute}`: the label of the attribute being validated.
80
         * - `{value}`: the value of the attribute being validated.
81
         */
82
        private string $incorrectInputMessage = 'The value must have a string type.',
83
        /**
84
         * @var string A message used when the value is not valid.
85
         *
86 3
         * You may use the following placeholders in the message:
87
         *
88
         * - `{attribute}`: the label of the attribute being validated.
89
         * - `{value}`: the value of the attribute being validated.
90
         */
91
        private string $message = 'This value is not a valid email address.',
92
        /**
93
         * @var bool|callable|null Whether to skip this rule if the value validated is empty.
94 1
         *
95
         * @see SkipOnEmptyInterface
96 1
         */
97
        private $skipOnEmpty = null,
98
        /**
99 83
         * @var bool Whether to skip this rule if any of the previous rules gave an error.
100
         */
101 83
        private bool $skipOnError = false,
102
        /**
103
         * @var Closure|null A callable to define a condition for applying the rule.
104 20
         * @psalm-var WhenType
105
         *
106 20
         * @see WhenInterface
107
         */
108
        private Closure|null $when = null,
109 10
    ) {
110
        if ($enableIDN && !function_exists('idn_to_ascii')) {
111 10
            // Tested via separate CI configuration (see ".github/workflows/build.yml").
112
            // @codeCoverageIgnoreStart
113
            throw new RuntimeException('In order to use IDN validation intl extension must be installed and enabled.');
114 48
            // @codeCoverageIgnoreEnd
115
        }
116 48
    }
117
118
    public function getName(): string
119 48
    {
120
        return 'email';
121 48
    }
122
123
    /**
124 94
     * @return string The regular expression used to validate the value.
125
     *
126 94
     * @see $pattern
127
     */
128
    public function getPattern(): string
129 5
    {
130
        return $this->pattern;
131 5
    }
132
133
    /**
134 49
     * @return string The regular expression used to validate email addresses with the name part.
135
     *
136 49
     * @see $fullPattern
137
     */
138
    public function getFullPattern(): string
139 4
    {
140
        return $this->fullPattern;
141
    }
142 4
143 4
    /**
144 4
     * @return string The regular expression used to validate complex emails when {@see $enableIDN} is `true`.
145 4
     *
146 4
     * @see $idnEmailPattern
147 4
     */
148
    public function getIdnEmailPattern(): string
149 4
    {
150
        return $this->idnEmailPattern;
151
    }
152
153 4
    /**
154
     * @return bool Whether to allow a name in the email address (e.g. "John Smith <[email protected]>").
155
     *
156 4
     * @see $allowName
157 4
     */
158
    public function isNameAllowed(): bool
159
    {
160
        return $this->allowName;
161 99
    }
162
163 99
    /**
164
     * @return bool Whether to check email's domain exists and has either an A or MX record.
165
     *
166
     * @see $checkDNS
167
     */
168
    public function shouldCheckDNS(): bool
169
    {
170
        return $this->checkDNS;
171
    }
172
173
    /**
174
     * @return bool Whether validation process should take IDN (internationalized domain names) into account.
175
     *
176
     * @see $enableIDN
177
     */
178
    public function isIDNEnabled(): bool
179
    {
180
        return $this->enableIDN;
181
    }
182
183
    /**
184
     * @return string A message used when the input is incorrect.
185
     *
186
     * @see $incorrectInputMessage
187
     */
188
    public function getIncorrectInputMessage(): string
189
    {
190
        return $this->incorrectInputMessage;
191
    }
192
193
    /**
194
     * @return string A message used when the value is not valid.
195
     *
196
     * @see $message
197
     */
198
    public function getMessage(): string
199
    {
200
        return $this->message;
201
    }
202
203
    public function getOptions(): array
204
    {
205
        return [
206
            'pattern' => $this->pattern,
207
            'fullPattern' => $this->fullPattern,
208
            'idnEmailPattern' => $this->idnEmailPattern,
209
            'allowName' => $this->allowName,
210
            'checkDNS' => $this->checkDNS,
211
            'enableIDN' => $this->enableIDN,
212
            'incorrectInputMessage' => [
213
                'template' => $this->incorrectInputMessage,
214
                'parameters' => [],
215
            ],
216
            'message' => [
217
                'template' => $this->message,
218
                'parameters' => [],
219
            ],
220
            'skipOnEmpty' => $this->getSkipOnEmptyOption(),
221
            'skipOnError' => $this->skipOnError,
222
        ];
223
    }
224
225
    public function getHandler(): string
226
    {
227
        return EmailHandler::class;
228
    }
229
}
230