Skip to content

Commit 2feed4a

Browse files
samdarkStyleCIBotarogachev
authored
Add phpdoc for Email and EmailHandler (#477)
* Clean up/add docs for Url and UrlHandler * Apply fixes from StyleCI * Apply code review suggestions * Added more @see references * Apply fixes from StyleCI * Fix typo * Use lists for placeholders * Add phpdoc for Email and EmailHandler * Apply fixes from StyleCI * More fixes * Apply fixes from StyleCI * Apply suggestions from code review Co-authored-by: Alexey Rogachev <[email protected]> * Fix the remaining review suggestions Co-authored-by: StyleCI Bot <[email protected]> Co-authored-by: Alexey Rogachev <[email protected]>
1 parent ab2b5f1 commit 2feed4a

4 files changed

Lines changed: 163 additions & 113 deletions

File tree

src/Rule/Email.php

Lines changed: 104 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use Attribute;
88
use Closure;
9-
use JetBrains\PhpStorm\Language;
109
use RuntimeException;
1110
use Yiisoft\Validator\Rule\Trait\SkipOnEmptyTrait;
1211
use Yiisoft\Validator\Rule\Trait\SkipOnErrorTrait;
@@ -19,7 +18,9 @@
1918
use function function_exists;
2019

2120
/**
22-
* Validates that the value is a valid email address.
21+
* Defines validation options to check that the value is a valid email address.
22+
*
23+
* @see EmailHandler
2324
*
2425
* @psalm-import-type WhenType from WhenInterface
2526
*/
@@ -30,61 +31,54 @@ final class Email implements RuleWithOptionsInterface, SkipOnErrorInterface, Whe
3031
use SkipOnErrorTrait;
3132
use WhenTrait;
3233

34+
/**
35+
* @param string $pattern The regular expression used to validate the value. See {@link https://www.regular-expressions.info/email.html}.
36+
* @param string $fullPattern The regular expression used to validate email addresses with the name part.
37+
* This property is used only when {@see $allowName} is `true`.
38+
* @param string $idnEmailPattern The regular expression used to validate complex emails when {@see $enableIdn} is `true`.
39+
* @param bool $allowName bool Whether to allow a name in the email address (e.g. "John Smith <[email protected]>").
40+
* Defaults to `false`. See {@see $fullPattern}.
41+
* @param bool $checkDns bool Whether to check email's domain exists and has either an A or MX record.
42+
* Be aware that this check can fail due to temporary DNS problems even if the email address is
43+
* valid and an email would be deliverable. Defaults to `false`.
44+
* @param bool $enableIdn Whether validation process should take IDN (internationalized domain names) into account.
45+
* Defaults to `false` meaning that validation of emails containing IDN will always fail.
46+
* Note that in order to use IDN validation you have to install and enable `intl` PHP extension,
47+
* otherwise an exception will be thrown.
48+
* @param string $incorrectInputMessage A message used when the input is incorrect.
49+
*
50+
* You may use the following placeholders in the message:
51+
*
52+
* - `{attribute}`: the label of the attribute being validated.
53+
* - `{type}`: the type of the attribute being validated.
54+
* @param string $message A message used when the value is not valid.
55+
*
56+
* You may use the following placeholders in the message:
57+
*
58+
* - `{attribute}`: the label of the attribute being validated.
59+
* - `{value}`: the value of the attribute being validated.
60+
* @param bool|callable|null $skipOnEmpty Whether to skip this rule if the value validated is empty. See {@see SkipOnEmptyInterface}.
61+
* @param bool $skipOnError Whether to skip this rule if any of the previous rules gave an error. See {@see SkipOnErrorInterface}.
62+
* @param Closure|null $when A callable to define a condition for applying the rule. See {@see WhenInterface}.
63+
* @psalm-param WhenType $when
64+
*
65+
* @throws RuntimeException If there was an attempt to enable IDN ({@see $enableIdn}), but "intl" PHP extension is
66+
* not installed or not enabled.
67+
*/
3368
public function __construct(
34-
#[Language('RegExp')]
35-
/**
36-
* @var string the regular expression used to validate value.
37-
*
38-
* @link https://www.regular-expressions.info/email.html
39-
*/
4069
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. This property is used
44-
* only when {@see $allowName} is `true`.
45-
*
46-
* @see $allowName
47-
*/
4870
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-
*/
5371
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 name in the email address (e.g. "John Smith <[email protected]>"). Defaults
56-
* to `false`.
57-
*
58-
* @see $fullPattern
59-
*/
6072
private bool $allowName = false,
61-
/**
62-
* @var bool whether to check whether the 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 into account IDN (internationalized domain
69-
* names). 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,
73+
private bool $checkDns = false,
74+
private bool $enableIdn = false,
7475
private string $incorrectInputMessage = 'The value must have a string type.',
7576
private string $message = 'This value is not a valid email address.',
76-
77-
/**
78-
* @var bool|callable|null
79-
*/
80-
private $skipOnEmpty = null,
77+
private mixed $skipOnEmpty = null,
8178
private bool $skipOnError = false,
82-
/**
83-
* @var WhenType
84-
*/
8579
private Closure|null $when = null,
8680
) {
87-
if ($enableIDN && !function_exists('idn_to_ascii')) {
81+
if ($enableIdn && !function_exists('idn_to_ascii')) {
8882
// Tested via separate CI configuration (see ".github/workflows/build.yml").
8983
// @codeCoverageIgnoreStart
9084
throw new RuntimeException('In order to use IDN validation intl extension must be installed and enabled.');
@@ -97,41 +91,97 @@ public function getName(): string
9791
return 'email';
9892
}
9993

94+
/**
95+
* Get the regular expression used to validate the value.
96+
*
97+
* @return string The regular expression.
98+
*
99+
* @see $pattern
100+
*/
100101
public function getPattern(): string
101102
{
102103
return $this->pattern;
103104
}
104105

106+
/**
107+
* Get the regular expression used to validate email addresses with the name part.
108+
*
109+
* @return string The regular expression.
110+
*
111+
* @see $fullPattern
112+
*/
105113
public function getFullPattern(): string
106114
{
107115
return $this->fullPattern;
108116
}
109117

118+
/**
119+
* Get the regular expression used to validate complex emails when {@see $enableIdn} is `true`.
120+
*
121+
* @return string The regular expression.
122+
*
123+
* @see $idnEmailPattern
124+
*/
110125
public function getIdnEmailPattern(): string
111126
{
112127
return $this->idnEmailPattern;
113128
}
114129

115-
public function isAllowName(): bool
130+
/**
131+
* Whether to allow a name in the email address (e.g. "John Smith <[email protected]>").
132+
*
133+
* @return bool Whether to allow a name in the email address.
134+
*
135+
* @see $allowName
136+
*/
137+
public function isNameAllowed(): bool
116138
{
117139
return $this->allowName;
118140
}
119141

120-
public function isCheckDNS(): bool
142+
/**
143+
* Whether to check email's domain exists and has either an A or MX record.
144+
*
145+
* @return bool Whether to check email's domain exists and has either an A or MX record.
146+
*
147+
* @see $checkDns
148+
*/
149+
public function shouldCheckDns(): bool
121150
{
122-
return $this->checkDNS;
151+
return $this->checkDns;
123152
}
124153

125-
public function isEnableIDN(): bool
154+
/**
155+
* Whether validation process should take IDN (internationalized domain names) into account.
156+
*
157+
* @return bool Whether validation process should take IDN (internationalized domain names) into account.
158+
*
159+
* @see $enableIdn
160+
*/
161+
public function isIdnEnabled(): bool
126162
{
127-
return $this->enableIDN;
163+
return $this->enableIdn;
128164
}
129165

166+
/**
167+
* Get a message used when the input is incorrect.
168+
*
169+
* @return string A message used when the input is incorrect.
170+
*
171+
* @see $incorrectInputMessage
172+
*/
130173
public function getIncorrectInputMessage(): string
131174
{
132175
return $this->incorrectInputMessage;
133176
}
134177

178+
/**
179+
* Get a message used when the value is not valid.
180+
*
181+
* @return string A message used when the value is not valid.
182+
*
183+
* @see $message
184+
*/
135185
public function getMessage(): string
136186
{
137187
return $this->message;
@@ -144,8 +194,8 @@ public function getOptions(): array
144194
'fullPattern' => $this->fullPattern,
145195
'idnEmailPattern' => $this->idnEmailPattern,
146196
'allowName' => $this->allowName,
147-
'checkDNS' => $this->checkDNS,
148-
'enableIDN' => $this->enableIDN,
197+
'checkDns' => $this->checkDns,
198+
'enableIdn' => $this->enableIdn,
149199
'incorrectInputMessage' => [
150200
'template' => $this->incorrectInputMessage,
151201
'parameters' => [],

src/Rule/EmailHandler.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function validate(mixed $value, object $rule, ValidationContext $context)
4141
$valid = false;
4242
} else {
4343
/** @var array{name:string,local:string,open:string,domain:string,close:string} $matches */
44-
if ($rule->isEnableIDN()) {
44+
if ($rule->isIdnEnabled()) {
4545
$matches['local'] = idn_to_ascii($matches['local']);
4646
$matches['domain'] = idn_to_ascii($matches['domain']);
4747
$value = implode([
@@ -70,17 +70,17 @@ public function validate(mixed $value, object $rule, ValidationContext $context)
7070
// https://www.rfc-editor.org/errata_search.php?eid=1690
7171
$valid = false;
7272
} else {
73-
$valid = preg_match($rule->getPattern(), $value) || ($rule->isAllowName() && preg_match(
73+
$valid = preg_match($rule->getPattern(), $value) || ($rule->isNameAllowed() && preg_match(
7474
$rule->getFullPattern(),
7575
$value
7676
));
77-
if ($valid && $rule->isCheckDNS()) {
77+
if ($valid && $rule->shouldCheckDns()) {
7878
$valid = checkdnsrr($matches['domain']);
7979
}
8080
}
8181
}
8282

83-
if ($valid === false && $rule->isEnableIDN()) {
83+
if ($valid === false && $rule->isIdnEnabled()) {
8484
$valid = (bool) preg_match($rule->getIdnEmailPattern(), $originalValue);
8585
}
8686

0 commit comments

Comments
 (0)