176 $this->structure = [];
177 $this->addresses = [];
181 $this->address = preg_replace(
'/\\r?\\n/',
'
183 $this->address = preg_replace(
'/\\r\\n(\\t| )+/',
' ', $this->address);
186 if ($this->address ===
false || isset($this->error)) {
187 throw new \InvalidArgumentException($this->error, 1294681466);
191 foreach ($this->addresses as
$address) {
193 if ($valid ===
false || isset($this->error)) {
194 throw new \InvalidArgumentException($this->error, 1294681467);
196 $this->structure = array_merge($this->structure, $valid);
210 if (!empty($this->limit) && count($this->addresses) == $this->limit) {
213 if ($this->
_isGroup($address) && !isset($this->error)) {
216 } elseif (!isset($this->error)) {
219 } elseif (isset($this->error)) {
223 $parts = explode($split_char,
$address);
230 if (strpos($string,
':') ===
false) {
231 $this->error =
'Invalid address: ' . $string;
243 $this->addresses[] = [
244 'address' => trim($string),
278 if (count($parts = explode(
':', $string)) > 1) {
280 return $string2 !== $string;
296 $partsCounter = count($parts);
297 for ($i = 0; $i < $partsCounter; $i++) {
299 if (isset($parts[$i + 1])) {
300 $string = $string . $char . $parts[$i + 1];
302 $this->error =
'Invalid address spec. Unclosed bracket or quotes';
322 $string = trim($string);
323 $iMax = strlen($string);
326 for (; $i < $iMax; ++$i) {
327 switch ($string[$i]) {
332 if ($slashes % 2 == 0) {
333 $in_quote = !$in_quote;
354 $num_angle_start = substr_count($string, $chars[0]);
355 $num_angle_end = substr_count($string, $chars[1]);
358 if ($num_angle_start < $num_angle_end) {
359 $this->error =
'Invalid address spec. Unmatched quote or bracket (' . $chars .
')';
362 return $num_angle_start > $num_angle_end;
376 $parts = explode($char, $string);
377 $partsCounter = count($parts);
378 for ($i = 0; $i < $partsCounter; $i++) {
382 if (isset($parts[$i + 1])) {
383 $parts[$i + 1] = $parts[$i] . $char . $parts[$i + 1];
403 $parts = explode(
':',
$address[
'address']);
408 $this->error =
'Group name did not validate.';
417 $parts = explode(
',',
$address[
'address']);
428 $this->error =
'Empty group.';
439 for ($i = 0; $i < $addressesCount; $i++) {
441 if (empty($this->error)) {
442 $this->error =
'Validation failed for: ' .
$addresses[$i];
465 $parts = preg_split(
'/[ \\x09]+/', $phrase, -1, PREG_SPLIT_NO_EMPTY);
467 while (!empty($parts)) {
469 for ($i = 0; $i < $this->index + 1; $i++) {
473 foreach ($phrase_parts as $part) {
475 if ($part[0] ===
'"') {
504 if (!$this->validate) {
509 if (!preg_match(
'/^[\\x00-\\x7E]+$/i', $atom, $matches)) {
513 if (preg_match(
'/[][()<>@,;\\:". ]/', $atom)) {
517 if (preg_match(
'/[\\x00-\\x1F]+/', $atom)) {
534 $qstring = substr($qstring, 1, -1);
536 return !preg_match(
'/[\\x0D\\\\"]/', preg_replace(
'/\\\\./',
'', $qstring));
553 $_mailbox = $mailbox;
554 while (trim($_mailbox) !==
'') {
555 $parts = explode(
'(', $_mailbox);
557 if ($before_comment != $_mailbox) {
559 $comment = substr(str_replace($before_comment,
'', $_mailbox), 1);
560 $parts = explode(
')', $comment);
562 $comments[] = $comment;
564 $_mailbox = substr($_mailbox, strpos($_mailbox,
'(' . $comment) + strlen($comment) + 2);
569 foreach ($comments as $comment) {
570 $mailbox = str_replace(
'(' . $comment .
')',
'', $mailbox);
572 $mailbox = trim($mailbox);
574 if (substr($mailbox, -1) ===
'>' && $mailbox[0] !==
'<') {
575 $parts = explode(
'<', $mailbox);
577 $phrase = trim($name);
578 $route_addr = trim(substr($mailbox, strlen($name .
'<'), -1));
584 if ($mailbox[0] ===
'<' && substr($mailbox, -1) ===
'>') {
585 $addr_spec = substr($mailbox, 1, -1);
587 $addr_spec = $mailbox;
594 $mbox = new \stdClass();
596 $mbox->personal = $phrase;
597 $mbox->comment = $comments ?? [];
598 if (isset($route_addr)) {
599 $mbox->mailbox = $route_addr[
'local_part'];
600 $mbox->host = $route_addr[
'domain'];
601 $route_addr[
'adl'] !==
'' ? ($mbox->adl = $route_addr[
'adl']) :
'';
603 $mbox->mailbox = $addr_spec[
'local_part'];
604 $mbox->host = $addr_spec[
'domain'];
624 if (strpos($route_addr,
':') !==
false) {
625 $parts = explode(
':', $route_addr);
628 $route = $route_addr;
632 if ($route === $route_addr) {
634 $addr_spec = $route_addr;
643 $addr_spec = substr($route_addr, strlen($route .
':'));
650 $return[
'adl'] = $route;
654 $return = array_merge($return, $addr_spec);
669 $domains = explode(
',', trim($route));
670 foreach ($domains as $domain) {
671 $domain = str_replace(
'@',
'', trim($domain));
692 $subdomains = explode(
'.', $domain);
693 while (!empty($subdomains)) {
695 for ($i = 0; $i < $this->index + 1; $i++) {
696 array_shift($subdomains);
699 foreach ($sub_domains as $sub_domain) {
718 if (preg_match(
'|^\\[(.*)]$|', $subdomain, $arr)) {
741 return !preg_match(
'/(.)[][\\x0D\\\\]/', $dliteral, $matches) && $matches[1] !==
'\\';
755 $addr_spec = trim($addr_spec);
757 if (strpos($addr_spec,
'@') !==
false) {
758 $parts = explode(
'@', $addr_spec);
760 $domain = substr($addr_spec, strlen($local_part .
'@'));
762 $local_part = $addr_spec;
772 return [
'local_part' => $local_part,
'domain' => $domain];
785 $parts = explode(
'.', $local_part);
788 while (!empty($parts)) {
790 for ($i = 0; $i < $this->index + 1; $i++) {
795 foreach ($words as $word) {
797 if (strpos($word,
' ') && $word[0] !==
'"') {