Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00019 final class MailAddress
00020 {
00021 const RFC_MAX_ENCODED_WORD_LENGTH = 75;
00022
00023 private $address = null;
00024 private $person = null;
00025 private $charset = 'UTF-8';
00026
00027 public static function create()
00028 {
00029 return new self;
00030 }
00031
00032 public function setAddress($address)
00033 {
00034 $this->address = $address;
00035
00036 return $this;
00037 }
00038
00039 public function getAddress()
00040 {
00041 return $this->address;
00042 }
00043
00044 public function setPerson($person)
00045 {
00046 $this->person = $person;
00047
00048 return $this;
00049 }
00050
00051 public function getPerson()
00052 {
00053 return $this->person;
00054 }
00055
00056 public function setCharset($charset)
00057 {
00058 $this->charset = $charset;
00059
00060 return $this;
00061 }
00062
00063 public function getCharset()
00064 {
00065 return $this->charset;
00066 }
00067
00068 public function toString()
00069 {
00070 $specials = preg_quote('()<>@,;:".[]\\', '/');
00071 $cr = '\015';
00072 $space = '\ ';
00073
00074 $ctls = '\000-\037\177';
00075 $char = '\000-\177';
00076
00077 $atom = "[^{$specials}{$space}{$ctls}]+";
00078 $asciiAtom = "[$char]+";
00079
00080 if (
00081 !preg_match($this->getAddressRegExp($asciiAtom), $this->address)
00082 || !preg_match($this->getAddressRegExp($atom), $this->address)
00083 )
00084 throw new WrongArgumentException(
00085 'wrongly formatted address is encountered'
00086 .' or local-part contains quoted-string'
00087 .' or domain contains domain-literal (unimplemented yet)'
00088 );
00089
00090 if (!$this->person)
00091 return $this->address;
00092
00093
00094 $person = $this->person;
00095
00096 if (
00097 !preg_match($this->getUnquotedPhraseRegexp($asciiAtom), $person)
00098 || !preg_match($this->getUnquotedPhraseRegexp($atom), $person)
00099 ) {
00100
00101 $qtextWithNoExceptions = "[$char\ ]";
00102 $qtextExceptions = "[$cr\"\\\\]";
00103
00104
00105 if (
00106 preg_match("/^{$qtextWithNoExceptions}*$/u", $person)
00107 && !preg_match("/{$qtextExceptions}/", $person)
00108 ) {
00109 $person = '"'.$person.'"';
00110
00111 } else {
00112 $person = $this->getEncodedPerson();
00113 }
00114 }
00115
00116 return "$person <{$this->address}>";
00117 }
00118
00119 private function getAddressRegExp($atom)
00120 {
00121
00122 $word = $atom;
00123
00124 $localPart = "{$word}(\.{$word})*";
00125
00126 $domainRef = $atom;
00127
00128
00129 $subDomain = $domainRef;
00130
00131 $domain = "{$subDomain}(\.{$subDomain})*";
00132
00133 $addrSpec = "{$localPart}@{$domain}";
00134
00135 return "/^{$addrSpec}$/";
00136 }
00137
00138 private function getUnquotedPhraseRegexp($atom)
00139 {
00140 return "/^({$atom})(\ {$atom})*$/u";
00141 }
00142
00143 private function getEncodedWord($word)
00144 {
00145 return "=?{$this->charset}?B?".base64_encode($word)."?=";
00146 }
00147
00148 private function getEncodedPerson()
00149 {
00150 $result = null;
00151
00152 $personChunk = null;
00153
00154 for ($i = 0; $i < mb_strlen($this->person); $i++) {
00155 $symbol = mb_substr($this->person, $i, 1);
00156
00157 $newLength = strlen(
00158 $this->getEncodedWord($personChunk.$symbol)
00159 );
00160
00161 if ($newLength >= self::RFC_MAX_ENCODED_WORD_LENGTH) {
00162 $result = $this->appendChunk($result, $personChunk);
00163
00164 $personChunk = null;
00165 }
00166
00167 $personChunk .= $symbol;
00168 }
00169
00170 if ($personChunk)
00171 $result = $this->appendChunk($result, $personChunk);
00172
00173 return $result;
00174 }
00175
00176 private function appendChunk($encodedPerson, $personChunk)
00177 {
00178 $crlfSpace = "\015\012 ";
00179
00180 return
00181 $encodedPerson
00182 .($encodedPerson ? $crlfSpace : null)
00183 .$this->getEncodedWord($personChunk);
00184 }
00185 }
00186 ?>