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

EmailAddress::parseEmail()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 11
dl 0
loc 21
rs 9.9
c 1
b 1
f 0
cc 3
nc 3
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EmailValidator;
6
7
class EmailAddress
8
{
9
    /**
10
     * @var string
11
     */
12
    private string $email;
13
14
    /**
15
     * @var string|null
16
     */
17
    private ?string $localPart = null;
18
19
    /**
20
     * @var string|null
21
     */
22
    private ?string $domain = null;
23
24
    public function __construct(string $email)
25
    {
26
        $this->email = $email;
27
        $this->parseEmail();
28
    }
29
30
    /**
31
     * Parses the email address into local part and domain
32
     * 
33
     * This method handles:
34
     * - Multiple @ symbols in quoted strings
35
     * - Domain literals (IP addresses in square brackets)
36
     * - Comments in email addresses
37
     * 
38
     * @return void
39
     */
40
    private function parseEmail(): void
41
    {
42
        // First, remove any comments
43
        $email = preg_replace('/\([^)]*\)/', '', $this->email);
44
        
45
        // Handle domain literals (IP addresses in square brackets)
46
        if (preg_match('/\[([^\]]+)\]$/', $email, $matches)) {
47
            $this->domain = $matches[1];
48
            $this->localPart = substr($email, 0, strrpos($email, '@'));
49
            return;
50
        }
51
52
        // Split on the last @ symbol
53
        $parts = explode('@', $email);
54
        if (count($parts) < 2) {
55
            return;
56
        }
57
58
        $this->domain = end($parts);
59
        array_pop($parts);
60
        $this->localPart = implode('@', $parts);
61
    }
62
63
    /**
64
     * Returns the domain name portion of the email address.
65
     *
66
     * @return string|null
67
     */
68
    public function getDomain(): ?string
69
    {
70
        return $this->domain;
71
    }
72
73
    /**
74
     * Returns the email address.
75
     *
76
     * @return string
77
     */
78
    public function getEmailAddress(): string
79
    {
80
        return $this->email;
81
    }
82
83
    /**
84
     * Returns the username of the email address.
85
     *
86
     * @since 1.1.0
87
     * @return string
88
     */
89
    private function getUsername(): string
90
    {
91
        return $this->localPart ?? '';
92
    }
93
94
    /**
95
     * Determines if a gmail account is using the "plus trick".
96
     *
97
     * @since 1.1.0
98
     * @return bool
99
     */
100
    public function isGmailWithPlusChar(): bool
101
    {
102
        $result = false;
103
        if (in_array($this->getDomain(), ['gmail.com', 'googlemail.com'])) {
104
            $result = strpos($this->getUsername(), '+') !== false;
105
        }
106
107
        return $result;
108
    }
109
110
    /**
111
     * Returns a gmail address without the "plus trick" portion of the email address.
112
     *
113
     * @since 1.1.0
114
     * @return string
115
     */
116
    public function getGmailAddressWithoutPlus(): string
117
    {
118
        return preg_replace('/^(.+?)(\+.+?)(@.+)/', '$1$3', $this->getEmailAddress());
119
    }
120
121
    /**
122
     * Returns a gmail address without the "plus trick" portion of the email address and all dots removed.
123
     *
124
     * @since 1.1.4
125
     * @return string
126
     */
127
    public function getSanitizedGmailAddress(): string
128
    {
129
        $email = new EmailAddress($this->getGmailAddressWithoutPlus());
130
        return sprintf(
131
            '%s@%s',
132
            str_replace('.', '', $email->getUsername()),
133
            $email->getDomain()
134
        );
135
    }
136
}
137