Test Failed
Push — master ( e44931...f3016b )
by John
35:12
created

EmailValidator::getSanitizedGmailAddress()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EmailValidator;
6
7
use EmailValidator\Validator\AValidator;
8
use EmailValidator\Validator\BannedListValidator;
9
use EmailValidator\Validator\BasicValidator;
10
use EmailValidator\Validator\DisposableEmailValidator;
11
use EmailValidator\Validator\FreeEmailValidator;
12
use EmailValidator\Validator\GmailValidator;
13
use EmailValidator\Validator\MxValidator;
14
15
class EmailValidator
16
{
17
    public const NO_ERROR = 0;
18
19
    public const FAIL_BASIC = 1;
20
21
    public const FAIL_MX_RECORD = 2;
22
23
    public const FAIL_BANNED_DOMAIN = 3;
24
25
    public const FAIL_DISPOSABLE_DOMAIN = 4;
26
27
    public const FAIL_FREE_PROVIDER = 5;
28
29
    public const FAIL_CUSTOM = 6;
30
31
    /**
32
     * @var BasicValidator
33
     */
34
    private BasicValidator $basicValidator;
35
36
    /**
37
     * @var MxValidator
38
     */
39
    private MxValidator $mxValidator;
40
41
    /**
42
     * @var BannedListValidator
43
     */
44
    private BannedListValidator $bannedListValidator;
45
46
    /**
47
     * @var DisposableEmailValidator
48
     */
49
    private DisposableEmailValidator $disposableEmailValidator;
50
51
    /**
52
     * @var FreeEmailValidator
53
     */
54
    private FreeEmailValidator $freeEmailValidator;
55
56
    /**
57
     * @var GmailValidator
58
     */
59
    private GmailValidator $gmailValidator;
60
61
    /**
62
     * @var array<AValidator>
63
     * @since 2.0.0
64
     */
65
    private array $customValidators = [];
66
67
    /**
68
     * @var int
69
     */
70
    private int $reason;
71
72
    /**
73
     * @var EmailAddress|null
74
     * @since 1.1.0
75
     */
76
    private ?EmailAddress $emailAddress = null;
77
78
    public function __construct(array $config = [])
79
    {
80
        $this->reason = self::NO_ERROR;
81
82
        $policy = new Policy($config);
83
84
        $this->mxValidator = new MxValidator($policy);
85
        $this->basicValidator = new BasicValidator($policy);
86
        $this->bannedListValidator = new BannedListValidator($policy);
87
        $this->disposableEmailValidator = new DisposableEmailValidator($policy);
88
        $this->freeEmailValidator = new FreeEmailValidator($policy);
89
        $this->gmailValidator = new GmailValidator($policy);
90
    }
91
92
    /**
93
     * Register a custom validator
94
     *
95
     * @param AValidator $validator
96
     * @return void
97
     * @since 2.0.0
98
     */
99
    public function registerValidator(AValidator $validator): void
100
    {
101
        $this->customValidators[] = $validator;
102
    }
103
104
    /**
105
     * Validate an email address by the rules set forth in the Policy
106
     *
107
     * @param string $email
108
     * @return bool
109
     */
110
    public function validate(string $email): bool
111
    {
112
        $this->resetErrorCode();
113
114
        $this->emailAddress = new EmailAddress($email);
115
116
        if (!$this->basicValidator->validate($this->emailAddress)) {
117
            $this->reason = self::FAIL_BASIC;
118
        } elseif (!$this->mxValidator->validate($this->emailAddress)) {
119
            $this->reason = self::FAIL_MX_RECORD;
120
        } elseif (!$this->bannedListValidator->validate($this->emailAddress)) {
121
            $this->reason = self::FAIL_BANNED_DOMAIN;
122
        } elseif (!$this->disposableEmailValidator->validate($this->emailAddress)) {
123
            $this->reason = self::FAIL_DISPOSABLE_DOMAIN;
124
        } elseif (!$this->freeEmailValidator->validate($this->emailAddress)) {
125
            $this->reason = self::FAIL_FREE_PROVIDER;
126
        } else {
127
            foreach ($this->customValidators as $validator) {
128
                if (!$validator->validate($this->emailAddress)) {
129
                    $this->reason = self::FAIL_CUSTOM;
130
                    break;
131
                }
132
            }
133
        }
134
135
        return $this->reason === self::NO_ERROR;
136
    }
137
138
    /**
139
     * Returns the error code constant value for invalid email addresses.
140
     *
141
     * For use by integrating systems to create their own error messages.
142
     *
143
     * @since 1.0.1
144
     * @return int
145
     */
146
    public function getErrorCode(): int
147
    {
148
        return $this->reason;
149
    }
150
151
    /**
152
     * Returns an error message for invalid email addresses
153
     *
154
     * @return string
155
     */
156
    public function getErrorReason(): string
157
    {
158
        switch ($this->reason) {
159
            case self::FAIL_BASIC:
160
                $msg = 'Invalid format';
161
                break;
162
            case self::FAIL_MX_RECORD:
163
                $msg = 'Domain does not accept email';
164
                break;
165
            case self::FAIL_BANNED_DOMAIN:
166
                $msg = 'Domain is banned';
167
                break;
168
            case self::FAIL_DISPOSABLE_DOMAIN:
169
                $msg = 'Domain is used by disposable email providers';
170
                break;
171
            case self::FAIL_FREE_PROVIDER:
172
                $msg = 'Domain is used by free email providers';
173
                break;
174
            case self::FAIL_CUSTOM:
175
                $msg = 'Failed custom validation';
176
                break;
177
            case self::NO_ERROR:
178
            default:
179
                $msg = '';
180
        }
181
182
        return $msg;
183
    }
184
185
    /**
186
     * Resets the error code so each validation starts off defaulting to "valid"
187
     *
188
     * @since 1.0.2
189
     * @return void
190
     */
191
    private function resetErrorCode(): void
192
    {
193
        $this->reason = self::NO_ERROR;
194
    }
195
196
    /**
197
     * Determines if a gmail account is using the "plus trick".
198
     *
199
     * @codeCoverageIgnore
200
     * @since 1.1.0
201
     * @return bool
202
     */
203
    public function isGmailWithPlusChar(): bool
204
    {
205
        return $this->emailAddress !== null && $this->gmailValidator->isGmailWithPlusChar($this->emailAddress);
206
    }
207
208
    /**
209
     * Returns a gmail address with the "plus trick" portion of the email address.
210
     *
211
     * @codeCoverageIgnore
212
     * @since 1.1.0
213
     * @return string
214
     */
215
    public function getGmailAddressWithoutPlus(): string
216
    {
217
        if ($this->emailAddress === null) {
218
            return '';
219
        }
220
        return $this->gmailValidator->getGmailAddressWithoutPlus($this->emailAddress);
221
    }
222
223
    /**
224
     * Returns a sanitized gmail address (plus trick removed and dots removed).
225
     *
226
     * @codeCoverageIgnore
227
     * @since 1.1.4
228
     * @return string
229
     */
230
    public function getSanitizedGmailAddress(): string
231
    {
232
        if ($this->emailAddress === null) {
233
            return '';
234
        }
235
        return $this->gmailValidator->getSanitizedGmailAddress($this->emailAddress);
236
    }
237
}
238