ILIAS  trunk Revision v12.0_alpha-16-g3e876e53c80
ILIAS\Data\EmailAddress Class Reference

An Email Address is a common personal address for people online. More...

+ Collaboration diagram for ILIAS\Data\EmailAddress:

Public Member Functions

 __construct (string $address_Full)
 
 getAddressFull ()
 
 getDomainPart ()
 
 getLocalPart ()
 
 getIsAscii ()
 
 getIsDomainPartAscii ()
 
 getIsLocalPartAscii ()
 
 __toString ()
 

Protected Member Functions

 checkAscii (string $str)
 
 digestFullAddress (string $address)
 
 digestDomainPart (string $address)
 
 digestLocalPart (string $address)
 

Static Protected Member Functions

static isAllowedIntlUnicode (string $string)
 

Protected Attributes

string $addressFull
 
string $domainPart
 
string $localPart
 
bool $isAscii
 
bool $isDomainPartAscii
 
bool $isLocalPartAscii
 

Detailed Description

An Email Address is a common personal address for people online.

This class ensures the address follows common format requirements. It also splits the address into some of the parts outlined in RFC 2822 that can then be retrieved separately. Non-ASCII characters are technically valid in the local (RFC 6531) and the domain (RFC 3490) parts, but...

  • in the local part they are only supported by a small amount of mailservers
  • in the domain part they are converted to ASCII punycode Because of this limited support, PHP's own FILTER_VALIDATE_EMAIL does not allow Unicode characters. However, we don't want to be as strict. ILIAS is used internationally where Latin-1 Supplement characters like ö, ä, ü, é, ø become more common in email addresses. Some Service Providers need to allow Japanese, Chinese and Cyrillic/Ukrainian scripts. Therefore, we allow Unicode characters covered by the Email Address Internationalization (EAI) framework. Be aware that not all email servers can process these by default and that additional steps might be necessary to enable ILIAS to send those emails. You can use isAscii() to check if an address is following the old standards and is likely supported by all servers.
Author
Ferdinand Engländer ferdi.nosp@m.nand.nosp@m..engl.nosp@m.aend.nosp@m.er@co.nosp@m.ncep.nosp@m.ts-an.nosp@m.d-tr.nosp@m.ainin.nosp@m.g.de

Definition at line 40 of file EmailAddress.php.

Constructor & Destructor Documentation

◆ __construct()

ILIAS\Data\EmailAddress::__construct ( string  $address_Full)

Definition at line 50 of file EmailAddress.php.

51 {
52 $this->addressFull = $this->digestFullAddress($address_Full);
53 $this->domainPart = $this->digestDomainPart($address_Full);
54 $this->localPart = $this->digestLocalPart($address_Full);
55 if ($this->isDomainPartAscii && $this->isLocalPartAscii) {
56 $this->isAscii = true;
57 } else {
58 $this->isAscii = false;
59 }
60 }
digestDomainPart(string $address)
digestFullAddress(string $address)
digestLocalPart(string $address)

References ILIAS\Data\EmailAddress\digestDomainPart(), ILIAS\Data\EmailAddress\digestFullAddress(), and ILIAS\Data\EmailAddress\digestLocalPart().

+ Here is the call graph for this function:

Member Function Documentation

◆ __toString()

ILIAS\Data\EmailAddress::__toString ( )

Definition at line 92 of file EmailAddress.php.

92 : string
93 {
94 return $this->getAddressFull();
95 }

References ILIAS\Data\EmailAddress\getAddressFull().

+ Here is the call graph for this function:

◆ checkAscii()

ILIAS\Data\EmailAddress::checkAscii ( string  $str)
protected

Definition at line 97 of file EmailAddress.php.

97 : bool
98 {
99 return mb_check_encoding($str, 'ASCII');
100 }

Referenced by ILIAS\Data\EmailAddress\digestDomainPart().

+ Here is the caller graph for this function:

◆ digestDomainPart()

ILIAS\Data\EmailAddress::digestDomainPart ( string  $address)
protected

Definition at line 120 of file EmailAddress.php.

120 : string
121 {
122 [, $domain] = explode('@', $address, 2);
123
124 $this->isDomainPartAscii = $this->checkAscii($domain);
125
126 if ($domain === 'localhost') {
127 return $domain;
128 }
129
130 if (preg_match('/[\p{C}\p{Z}]/u', $domain)) {
131 throw new \InvalidArgumentException("Domain part contains invalid characters (e.g., whitespace or control).");
132 }
133
134 if (str_contains($domain, '..')) {
135 throw new \InvalidArgumentException("Domain part contains consecutive dots.");
136 }
137
138 // not flagging double hyphens as punycode uses those
139
140 if (substr_count($domain, '.') < 1) {
141 throw new \InvalidArgumentException("Domain must contain at least one dot except for 'localhost'.");
142 }
143
144 if (strlen($domain) > 254) {
145 throw new \InvalidArgumentException("Domain part exceeds 254 character limit.");
146 }
147
148 $labels = explode('.', $domain);
149 foreach ($labels as $label) {
150 if (strlen($label) > 63) {
151 throw new \InvalidArgumentException("Domain label exceeds 63 character limit.");
152 }
153
154 if ($label === '') {
155 throw new \InvalidArgumentException("Domain contains an empty label.");
156 }
157
158 if ($label[0] === '-' || $label[strlen($label) - 1] === '-') {
159 throw new \InvalidArgumentException("Domain labels must not start or end with a hyphen.");
160 }
161 }
162
163 return $domain;
164 }

References ILIAS\Data\EmailAddress\checkAscii().

Referenced by ILIAS\Data\EmailAddress\__construct().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ digestFullAddress()

ILIAS\Data\EmailAddress::digestFullAddress ( string  $address)
protected

Definition at line 102 of file EmailAddress.php.

102 : string
103 {
104 $address = trim($address);
105
106 if (substr_count($address, '@') !== 1) {
107 throw new \InvalidArgumentException("Email must contain exactly one '@' character.");
108 }
109
110 [$local, $domain] = explode('@', $address, 2);
111
112 if ($local === '' || $domain === '') {
113 throw new \InvalidArgumentException("Email must have non-empty local and domain parts.");
114 }
115
116 $this->addressFull = $address;
117 return $address;
118 }

Referenced by ILIAS\Data\EmailAddress\__construct().

+ Here is the caller graph for this function:

◆ digestLocalPart()

ILIAS\Data\EmailAddress::digestLocalPart ( string  $address)
protected

Definition at line 166 of file EmailAddress.php.

166 : string
167 {
168 [$local,] = explode('@', $address, 2);
169
170 if (!mb_check_encoding($local, 'UTF-8')) {
171 throw new \InvalidArgumentException("Local part is not valid UTF-8.");
172 }
173
174 if ($local[0] === '.' || str_ends_with($local, '.')) {
175 throw new \InvalidArgumentException("Local part cannot start or end with a dot.");
176 }
177
178 if (str_contains($local, '..')) {
179 throw new \InvalidArgumentException("Local part cannot contain consecutive dots.");
180 }
181
182 // double quotes are allowed only as first and last character
183 if (str_starts_with($local, '"') && str_ends_with($local, '"')) {
184 $local_strip_quotes = substr($local, 1, -1);
185 } else {
186 $local_strip_quotes = $local;
187 }
188
189 if (preg_match('/[\x00-\x1F\x7F]/', $local_strip_quotes)) {
190 throw new \InvalidArgumentException("Local part contains unsupported control characters or invalid escape sequences.");
191 }
192
193 // check if safe Ascii
194 if (preg_match('/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local_strip_quotes)) {
195 $this->isLocalPartAscii = true;
196 } else {
197 $this->isLocalPartAscii = false;
198 }
199 // check if save Unicode
200 if (!self::isAllowedIntlUnicode($local_strip_quotes)) {
201 throw new \InvalidArgumentException("Local part is not a valid Unicode string.");
202 }
203
204 return $local;
205 }

Referenced by ILIAS\Data\EmailAddress\__construct().

+ Here is the caller graph for this function:

◆ getAddressFull()

ILIAS\Data\EmailAddress::getAddressFull ( )

Definition at line 62 of file EmailAddress.php.

62 : string
63 {
64 return $this->addressFull;
65 }

References ILIAS\Data\EmailAddress\$addressFull.

Referenced by ILIAS\Data\EmailAddress\__toString().

+ Here is the caller graph for this function:

◆ getDomainPart()

ILIAS\Data\EmailAddress::getDomainPart ( )

Definition at line 67 of file EmailAddress.php.

67 : string
68 {
69 return $this->domainPart;
70 }

References ILIAS\Data\EmailAddress\$domainPart.

◆ getIsAscii()

ILIAS\Data\EmailAddress::getIsAscii ( )

Definition at line 77 of file EmailAddress.php.

77 : bool
78 {
79 return $this->isAscii;
80 }

References ILIAS\Data\EmailAddress\$isAscii.

◆ getIsDomainPartAscii()

ILIAS\Data\EmailAddress::getIsDomainPartAscii ( )

Definition at line 82 of file EmailAddress.php.

82 : bool
83 {
85 }

References ILIAS\Data\EmailAddress\$isDomainPartAscii.

◆ getIsLocalPartAscii()

ILIAS\Data\EmailAddress::getIsLocalPartAscii ( )

Definition at line 87 of file EmailAddress.php.

87 : bool
88 {
90 }

References ILIAS\Data\EmailAddress\$isLocalPartAscii.

◆ getLocalPart()

ILIAS\Data\EmailAddress::getLocalPart ( )

Definition at line 72 of file EmailAddress.php.

72 : string
73 {
74 return $this->localPart;
75 }

References ILIAS\Data\EmailAddress\$localPart.

◆ isAllowedIntlUnicode()

static ILIAS\Data\EmailAddress::isAllowedIntlUnicode ( string  $string)
staticprotected

Definition at line 207 of file EmailAddress.php.

207 : bool
208 {
209 // Check allowed Unicode characters this includes e.g.
210 // * a-z, A-Z, 0-9
211 // * Latin accented: é, ñ, ö, č
212 // * Greek: Α, β, Ω
213 // * Cyrillic: Б, и, я
214 // * Arabic letters: ا, ب, خ
215 // * Hebrew: א, ב, ג
216 // * East Asian ideographs (CJK): 日, 本, 語, 汉, 字
217 // * Devanagari (Hindi, Marathi): अ, आ, क
218 // * Hangul (Korean): 한, 글
219 // * and more
220 // \p{L} includes all characters Unicode defines as letters
221 // \p{N} includes all characters Unicode defines as numbers
222 // this excludes emojis and control characters which are not allowed in the local part
223 if (!preg_match('/^[\p{L}\p{N}!#$%&\'*+\/=?^_`{|}~\.-]+$/u', $string)) {
224 return false;
225 } else {
226 return true;
227 }
228 }

Field Documentation

◆ $addressFull

string ILIAS\Data\EmailAddress::$addressFull
protected

Definition at line 42 of file EmailAddress.php.

Referenced by ILIAS\Data\EmailAddress\getAddressFull().

◆ $domainPart

string ILIAS\Data\EmailAddress::$domainPart
protected

Definition at line 43 of file EmailAddress.php.

Referenced by ILIAS\Data\EmailAddress\getDomainPart().

◆ $isAscii

bool ILIAS\Data\EmailAddress::$isAscii
protected

Definition at line 45 of file EmailAddress.php.

Referenced by ILIAS\Data\EmailAddress\getIsAscii().

◆ $isDomainPartAscii

bool ILIAS\Data\EmailAddress::$isDomainPartAscii
protected

Definition at line 46 of file EmailAddress.php.

Referenced by ILIAS\Data\EmailAddress\getIsDomainPartAscii().

◆ $isLocalPartAscii

bool ILIAS\Data\EmailAddress::$isLocalPartAscii
protected

Definition at line 47 of file EmailAddress.php.

Referenced by ILIAS\Data\EmailAddress\getIsLocalPartAscii().

◆ $localPart

string ILIAS\Data\EmailAddress::$localPart
protected

Definition at line 44 of file EmailAddress.php.

Referenced by ILIAS\Data\EmailAddress\getLocalPart().


The documentation for this class was generated from the following file: