![]() |
Xataface Email Module 0.3
Email/Mailmerge Module for Xataface
|
00001 <?php 00002 00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00004 * * 00005 * XPertMailer is a PHP Mail Class that can send and read messages in MIME format. * 00006 * This file is part of the XPertMailer package (http://xpertmailer.sourceforge.net/) * 00007 * Copyright (C) 2007 Tanase Laurentiu Iulian * 00008 * * 00009 * This library is free software; you can redistribute it and/or modify it under the * 00010 * terms of the GNU Lesser General Public License as published by the Free Software * 00011 * Foundation; either version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, but WITHOUT ANY * 00014 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 00015 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU Lesser General Public License along with * 00018 * this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, * 00019 * Fifth Floor, Boston, MA 02110-1301, USA * 00020 * * 00021 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00022 00023 if (!class_exists('FUNC5')) require_once 'FUNC5.php'; 00024 00025 class MIME5 { 00026 00027 const LE = PHP_EOL; 00028 const HLEN = 52; 00029 const MLEN = 73; 00030 00031 const HCHARSET = 'utf-8'; 00032 const MCHARSET = 'us-ascii'; 00033 00034 const HENCDEF = 'quoted-printable'; 00035 const MENCDEF = 'quoted-printable'; 00036 00037 static public $hencarr = array('quoted-printable' => '', 'base64' => ''); 00038 static public $mencarr = array('7bit' => '', '8bit' => '', 'quoted-printable' => '', 'base64' => '', 'binary' => ''); 00039 00040 static public $qpkeys = array( 00041 "\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07", 00042 "\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F", 00043 "\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17", 00044 "\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F", 00045 "\x7F","\x80","\x81","\x82","\x83","\x84","\x85","\x86", 00046 "\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E", 00047 "\x8F","\x90","\x91","\x92","\x93","\x94","\x95","\x96", 00048 "\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E", 00049 "\x9F","\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6", 00050 "\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE", 00051 "\xAF","\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6", 00052 "\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE", 00053 "\xBF","\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6", 00054 "\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE", 00055 "\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6", 00056 "\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE", 00057 "\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6", 00058 "\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE", 00059 "\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6", 00060 "\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE", 00061 "\xFF"); 00062 00063 static public $qpvrep = array( 00064 "=00","=01","=02","=03","=04","=05","=06","=07", 00065 "=08","=09","=0A","=0B","=0C","=0D","=0E","=0F", 00066 "=10","=11","=12","=13","=14","=15","=16","=17", 00067 "=18","=19","=1A","=1B","=1C","=1D","=1E","=1F", 00068 "=7F","=80","=81","=82","=83","=84","=85","=86", 00069 "=87","=88","=89","=8A","=8B","=8C","=8D","=8E", 00070 "=8F","=90","=91","=92","=93","=94","=95","=96", 00071 "=97","=98","=99","=9A","=9B","=9C","=9D","=9E", 00072 "=9F","=A0","=A1","=A2","=A3","=A4","=A5","=A6", 00073 "=A7","=A8","=A9","=AA","=AB","=AC","=AD","=AE", 00074 "=AF","=B0","=B1","=B2","=B3","=B4","=B5","=B6", 00075 "=B7","=B8","=B9","=BA","=BB","=BC","=BD","=BE", 00076 "=BF","=C0","=C1","=C2","=C3","=C4","=C5","=C6", 00077 "=C7","=C8","=C9","=CA","=CB","=CC","=CD","=CE", 00078 "=CF","=D0","=D1","=D2","=D3","=D4","=D5","=D6", 00079 "=D7","=D8","=D9","=DA","=DB","=DC","=DD","=DE", 00080 "=DF","=E0","=E1","=E2","=E3","=E4","=E5","=E6", 00081 "=E7","=E8","=E9","=EA","=EB","=EC","=ED","=EE", 00082 "=EF","=F0","=F1","=F2","=F3","=F4","=F5","=F6", 00083 "=F7","=F8","=F9","=FA","=FB","=FC","=FD","=FE", 00084 "=FF"); 00085 00086 static public function unique($add = null) { 00087 return md5(microtime(true).$add); 00088 } 00089 00090 static public function is_printable($str = null, $debug = null) { 00091 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00092 if (!is_string($str)) FUNC5::trace($debug, 'invalid argument type'); 00093 else { 00094 $contain = implode('', self::$qpkeys); 00095 return (strcspn($str, $contain) == strlen($str)); 00096 } 00097 } 00098 00099 static public function qp_encode($str = null, $len = null, $end = null, $debug = null) { 00100 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00101 $err = array(); 00102 if (!is_string($str)) $err[] = 'invalid argument type'; 00103 if ($len == null) $len = self::MLEN; 00104 else if (!(is_int($len) && $len > 1)) $err[] = 'invalid line length value'; 00105 if ($end == null) $end = self::LE; 00106 else if (!is_string($end)) $err[] = 'invalid line end value'; 00107 if (count($err) > 0) FUNC5::trace($debug, implode(', ', $err)); 00108 else { 00109 if ($str == '') return $str; 00110 else { 00111 $out = array(); 00112 foreach (explode($end, $str) as $line) { 00113 if ($line == '') $out[] = ''; 00114 else { 00115 $line = str_replace('=', '=3D', $line); 00116 $line = str_replace(self::$qpkeys, self::$qpvrep, $line); 00117 preg_match_all('/.{1,'.$len.'}([^=]{0,2})?/', $line, $match); 00118 $mcnt = count($match[0]); 00119 for ($i = 0; $i < $mcnt; $i++) { 00120 $line = (substr($match[0][$i], -1) == ' ') ? substr($match[0][$i], 0, -1).'=20' : $match[0][$i]; 00121 if (($i+1) < $mcnt) $line .= '='; 00122 $out[] = $line; 00123 } 00124 } 00125 } 00126 return implode($end, $out); 00127 } 00128 } 00129 } 00130 00131 static public function encode_header($str = null, $charset = null, $encoding = null, $len = null, $end = null, $debug = null) { 00132 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00133 $err = array(); 00134 if (!is_string($str)) $err[] = 'invalid argument type'; 00135 if ($charset == null) $charset = self::HCHARSET; 00136 else if (!is_string($charset)) $err[] = 'invalid charset type'; 00137 else if (!(strlen($charset) >= 2 && FUNC5::is_alpha($charset, true, '-'))) $err[] = 'invalid charset value'; 00138 if ($encoding == null) $encoding = self::HENCDEF; 00139 else if (!is_string($encoding)) $err[] = 'invalid encoding type'; 00140 else { 00141 $encoding = strtolower(FUNC5::str_clear($encoding)); 00142 if (!isset(self::$hencarr[$encoding])) $err[] = 'invalid encoding value'; 00143 } 00144 if ($len == null) $len = self::HLEN; 00145 else if (!(is_int($len) && $len > 1)) $err[] = 'invalid line length value'; 00146 if ($end == null) $end = self::LE; 00147 else if (!is_string($end)) $err[] = 'invalid line end value'; 00148 if (count($err) > 0) FUNC5::trace($debug, implode(', ', $err)); 00149 else { 00150 if ($str == '') return $str; 00151 else { 00152 $enc = false; 00153 $dif = $len - strlen('=?'.$charset.'?X??='); 00154 if ($encoding == 'quoted-printable') { 00155 if (!self::is_printable($str)) { 00156 $new = (($dif-4) > 2) ? ($dif-4) : $len; 00157 $enc = self::qp_encode($str, $new, $end); 00158 $enc = str_replace(array('?', ' ', '='.$end), array('=3F', '_', $end), $enc); 00159 } 00160 } else if ($encoding == 'base64') { 00161 $new = ($dif > 3) ? $dif : $len; 00162 if ($new > 3) { 00163 for ($i = $new; $i > 2; $i--) { 00164 $crt = ''; 00165 for ($j = 0; $j <= $i; $j++) $crt .= 'x'; 00166 if (strlen(base64_encode($crt)) <= $new) { 00167 $new = $i; 00168 break; 00169 } 00170 } 00171 } 00172 $cnk = rtrim(chunk_split($str, $new, $end)); 00173 $imp = array(); 00174 foreach (explode($end, $cnk) as $line) if ($line != '') $imp[] = base64_encode($line); 00175 $enc = implode($end, $imp); 00176 } 00177 $res = array(); 00178 if ($enc) { 00179 $chr = ($encoding == 'base64') ? 'B' : 'Q'; 00180 foreach (explode($end, $enc) as $val) if ($val != '') $res[] = '=?'.$charset.'?'.$chr.'?'.$val.'?='; 00181 } else { 00182 $cnk = rtrim(chunk_split($str, $len, $end)); 00183 foreach (explode($end, $cnk) as $val) if ($val != '') $res[] = $val; 00184 } 00185 return implode($end."\t", $res); 00186 } 00187 } 00188 } 00189 00190 static public function decode_header($str = null, $debug = null) { 00191 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00192 if (!is_string($str)) FUNC5::trace($debug, 'invalid argument type'); 00193 else { 00194 $str = trim(FUNC5::str_clear($str)); 00195 $arr = array(); 00196 if ($str == '') $arr[] = array('charset' => self::HCHARSET, 'value' => ''); 00197 else { 00198 foreach (preg_split('/(?<!\\?(?i)q)\\?\\=/', $str, -1, PREG_SPLIT_NO_EMPTY) as $str1) { 00199 foreach (explode('=?', $str1, 2) as $str2) { 00200 $def = false; 00201 if (count($exp = explode('?B?', $str2)) == 2) { 00202 if (strlen($exp[0]) >= 2 && FUNC5::is_alpha($exp[0], true, '-') && trim($exp[1]) != '') $def = array('charset' => $exp[0], 'value' => base64_decode(trim($exp[1]))); 00203 } else if (count($exp = explode('?b?', $str2)) == 2) { 00204 if (strlen($exp[0]) >= 2 && FUNC5::is_alpha($exp[0], true, '-') && trim($exp[1]) != '') $def = array('charset' => $exp[0], 'value' => base64_decode(trim($exp[1]))); 00205 } else if (count($exp = explode('?Q?', $str2)) == 2) { 00206 if (strlen($exp[0]) >= 2 && FUNC5::is_alpha($exp[0], true, '-') && $exp[1] != '') $def = array('charset' => $exp[0], 'value' => quoted_printable_decode(str_replace('_', ' ', $exp[1]))); 00207 } else if (count($exp = explode('?q?', $str2)) == 2) { 00208 if (strlen($exp[0]) >= 2 && FUNC5::is_alpha($exp[0], true, '-') && $exp[1] != '') $def = array('charset' => $exp[0], 'value' => quoted_printable_decode(str_replace('_', ' ', $exp[1]))); 00209 } 00210 if ($def) { 00211 if ($def['value'] != '') $arr[] = array('charset' => $def['charset'], 'value' => $def['value']); 00212 } else { 00213 if ($str2 != '') $arr[] = array('charset' => self::HCHARSET, 'value' => $str2); 00214 } 00215 } 00216 } 00217 } 00218 return $arr; 00219 } 00220 } 00221 00222 static public function decode_content($str = null, $encoding = null, $debug = null) { 00223 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00224 $err = array(); 00225 if (!is_string($str)) $err[] = 'invalid content type'; 00226 if ($encoding == null) $encoding = '7bit'; 00227 else if (!is_string($encoding)) $err[] = 'invalid encoding type'; 00228 else { 00229 $encoding = strtolower($encoding); 00230 if (!isset(self::$mencarr[$encoding])) $err[] = 'invalid encoding value'; 00231 } 00232 if (count($err) > 0) FUNC5::trace($debug, implode(', ', $err)); 00233 else { 00234 if ($encoding == 'base64') { 00235 $str = trim(FUNC5::str_clear($str)); 00236 return base64_decode($str); 00237 } else if ($encoding == 'quoted-printable') { 00238 return quoted_printable_decode($str); 00239 } else return $str; 00240 } 00241 } 00242 00243 static public function message($content = null, $type = null, $name = null, $charset = null, $encoding = null, $disposition = null, $id = null, $len = null, $end = null, $debug = null) { 00244 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00245 $err = array(); 00246 if (!(is_string($content) && $content != '')) $err[] = 'invalid content type'; 00247 if ($type == null) $type = 'application/octet-stream'; 00248 else if (is_string($type)) { 00249 $type = trim(FUNC5::str_clear($type)); 00250 if (strlen($type) < 4) $err[] = 'invalid type value'; 00251 } else $err[] = 'invalid type'; 00252 if (is_string($name)) { 00253 $name = trim(FUNC5::str_clear($name)); 00254 if ($name == '') $err[] = 'invalid name value'; 00255 } else if ($name != null) $err[] = 'invalid name type'; 00256 if ($charset == null) $charset = self::MCHARSET; 00257 else if (!is_string($charset)) $err[] = 'invalid charset type'; 00258 else if (!(strlen($charset) >= 2 && FUNC5::is_alpha($charset, true, '-'))) $err[] = 'invalid charset value'; 00259 if ($encoding == null) $encoding = self::MENCDEF; 00260 else if (!is_string($encoding)) $err[] = 'invalid encoding type'; 00261 else { 00262 $encoding = strtolower(FUNC5::str_clear($encoding)); 00263 if (!isset(self::$mencarr[$encoding])) $err[] = 'invalid encoding value'; 00264 } 00265 if ($disposition == null) $disposition = 'inline'; 00266 else if (is_string($disposition)) { 00267 $disposition = strtolower(FUNC5::str_clear($disposition)); 00268 if (!($disposition == 'inline' || $disposition == 'attachment')) $err[] = 'invalid disposition value'; 00269 } else $err[] = 'invalid disposition type'; 00270 if (is_string($id)) { 00271 $id = FUNC5::str_clear($id, array(' ')); 00272 if ($id == '') $err[] = 'invalid id value'; 00273 } else if ($id != null) $err[] = 'invalid id type'; 00274 if ($len == null) $len = self::MLEN; 00275 else if (!(is_int($len) && $len > 1)) $err[] = 'invalid line length value'; 00276 if ($end == null) $end = self::LE; 00277 else if (!is_string($end)) $err[] = 'invalid line end value'; 00278 if (count($err) > 0) FUNC5::trace($debug, implode(', ', $err)); 00279 else { 00280 $header = ''. 00281 'Content-Type: '.$type.';'.$end."\t".'charset="'.$charset.'"'. 00282 (($name == null) ? '' : ';'.$end."\t".'name="'.$name.'"').$end. 00283 'Content-Transfer-Encoding: '.$encoding.$end. 00284 'Content-Disposition: '.$disposition. 00285 (($name == null) ? '' : ';'.$end."\t".'filename="'.$name.'"'). 00286 (($id == null) ? '' : $end.'Content-ID: <'.$id.'>'); 00287 if ($encoding == '7bit' || $encoding == '8bit') $content = wordwrap(self::fix_eol($content), $len, $end, true); 00288 else if ($encoding == 'base64') $content = rtrim(chunk_split(base64_encode($content), $len, $end)); 00289 else if ($encoding == 'quoted-printable') $content = self::qp_encode(self::fix_eol($content), $len, $end); 00290 return array('header' => $header, 'content' => $content); 00291 } 00292 } 00293 00294 static public function compose($text = null, $html = null, $attach = null, $uniq = null, $end = null, $debug = null) { 00295 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00296 $err = array(); 00297 if ($text == null && $html == null) $err[] = 'message is not set'; 00298 else { 00299 if ($text != null) { 00300 if (!(is_array($text) && isset($text['header'], $text['content']) && is_string($text['header']) && is_string($text['content']) && self::isset_header($text['header'], 'content-type', 'text/plain', $debug))) $err[] = 'invalid text message type'; 00301 } 00302 if ($html != null) { 00303 if (!(is_array($html) && isset($html['header'], $html['content']) && is_string($html['header']) && is_string($html['content']) && self::isset_header($html['header'], 'content-type', 'text/html', $debug))) $err[] = 'invalid html message type'; 00304 } 00305 } 00306 if ($attach != null) { 00307 if (is_array($attach) && count($attach) > 0) { 00308 foreach ($attach as $arr) { 00309 if (!(is_array($arr) && isset($arr['header'], $arr['content']) && is_string($arr['header']) && is_string($arr['content']) && (self::isset_header($arr['header'], 'content-disposition', 'inline', $debug) || self::isset_header($arr['header'], 'content-disposition', 'attachment', $debug)))) { 00310 $err[] = 'invalid attachment type'; 00311 break; 00312 } 00313 } 00314 } else $err[] = 'invalid attachment format'; 00315 } 00316 if ($end == null) $end = self::LE; 00317 else if (!is_string($end)) $err[] = 'invalid line end value'; 00318 if (count($err) > 0) FUNC5::trace($debug, implode(', ', $err)); 00319 else { 00320 $multipart = false; 00321 if ($text && $html) $multipart = true; 00322 if ($attach) $multipart = true; 00323 $header = $body = array(); 00324 $header[] = 'Date: '.date('r'); 00325 $header[] = base64_decode('WC1NYWlsZXI6IFhQTTQgdi4wLjUgPCB3d3cueHBlcnRtYWlsZXIuY29tID4='); 00326 if ($multipart) { 00327 $uniq = ($uniq == null) ? 0 : intval($uniq); 00328 $boundary1 = '=_1.'.self::unique($uniq++); 00329 $boundary2 = '=_2.'.self::unique($uniq++); 00330 $boundary3 = '=_3.'.self::unique($uniq++); 00331 $disp['inline'] = $disp['attachment'] = false; 00332 if ($attach != null) { 00333 foreach ($attach as $darr) { 00334 if (self::isset_header($darr['header'], 'content-disposition', 'inline', $debug)) $disp['inline'] = true; 00335 else if (self::isset_header($darr['header'], 'content-disposition', 'attachment', $debug)) $disp['attachment'] = true; 00336 } 00337 } 00338 $hstr = 'Content-Type: multipart/%s;'.$end."\t".'boundary="%s"'; 00339 $bstr = '--%s'.$end.'%s'.$end.$end.'%s'; 00340 $body[] = 'This is a message in MIME Format. If you see this, your mail reader does not support this format.'.$end; 00341 if ($text && $html) { 00342 if ($disp['inline'] && $disp['attachment']) { 00343 $header[] = sprintf($hstr, 'mixed', $boundary1); 00344 $body[] = '--'.$boundary1; 00345 $body[] = sprintf($hstr, 'related', $boundary2).$end; 00346 $body[] = '--'.$boundary2; 00347 $body[] = sprintf($hstr, 'alternative', $boundary3).$end; 00348 $body[] = sprintf($bstr, $boundary3, $text['header'], $text['content']); 00349 $body[] = sprintf($bstr, $boundary3, $html['header'], $html['content']); 00350 $body[] = '--'.$boundary3.'--'; 00351 foreach ($attach as $desc) if (self::isset_header($desc['header'], 'content-disposition', 'inline', $debug)) $body[] = sprintf($bstr, $boundary2, $desc['header'], $desc['content']); 00352 $body[] = '--'.$boundary2.'--'; 00353 foreach ($attach as $desc) if (self::isset_header($desc['header'], 'content-disposition', 'attachment', $debug)) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']); 00354 $body[] = '--'.$boundary1.'--'; 00355 } else if ($disp['inline']) { 00356 $header[] = sprintf($hstr, 'related', $boundary1); 00357 $body[] = '--'.$boundary1; 00358 $body[] = sprintf($hstr, 'alternative', $boundary2).$end; 00359 $body[] = sprintf($bstr, $boundary2, $text['header'], $text['content']); 00360 $body[] = sprintf($bstr, $boundary2, $html['header'], $html['content']); 00361 $body[] = '--'.$boundary2.'--'; 00362 foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']); 00363 $body[] = '--'.$boundary1.'--'; 00364 } else if ($disp['attachment']) { 00365 $header[] = sprintf($hstr, 'mixed', $boundary1); 00366 $body[] = '--'.$boundary1; 00367 $body[] = sprintf($hstr, 'alternative', $boundary2).$end; 00368 $body[] = sprintf($bstr, $boundary2, $text['header'], $text['content']); 00369 $body[] = sprintf($bstr, $boundary2, $html['header'], $html['content']); 00370 $body[] = '--'.$boundary2.'--'; 00371 foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']); 00372 $body[] = '--'.$boundary1.'--'; 00373 } else { 00374 $header[] = sprintf($hstr, 'alternative', $boundary1); 00375 $body[] = sprintf($bstr, $boundary1, $text['header'], $text['content']); 00376 $body[] = sprintf($bstr, $boundary1, $html['header'], $html['content']); 00377 $body[] = '--'.$boundary1.'--'; 00378 } 00379 } else if ($text) { 00380 $header[] = sprintf($hstr, 'mixed', $boundary1); 00381 $body[] = sprintf($bstr, $boundary1, $text['header'], $text['content']); 00382 foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']); 00383 $body[] = '--'.$boundary1.'--'; 00384 } else if ($html) { 00385 if ($disp['inline'] && $disp['attachment']) { 00386 $header[] = sprintf($hstr, 'mixed', $boundary1); 00387 $body[] = '--'.$boundary1; 00388 $body[] = sprintf($hstr, 'related', $boundary2).$end; 00389 $body[] = sprintf($bstr, $boundary2, $html['header'], $html['content']); 00390 foreach ($attach as $desc) if (self::isset_header($desc['header'], 'content-disposition', 'inline', $debug)) $body[] = sprintf($bstr, $boundary2, $desc['header'], $desc['content']); 00391 $body[] = '--'.$boundary2.'--'; 00392 foreach ($attach as $desc) if (self::isset_header($desc['header'], 'content-disposition', 'attachment', $debug)) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']); 00393 $body[] = '--'.$boundary1.'--'; 00394 } else if ($disp['inline']) { 00395 $header[] = sprintf($hstr, 'related', $boundary1); 00396 $body[] = sprintf($bstr, $boundary1, $html['header'], $html['content']); 00397 foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']); 00398 $body[] = '--'.$boundary1.'--'; 00399 } else if ($disp['attachment']) { 00400 $header[] = sprintf($hstr, 'mixed', $boundary1); 00401 $body[] = sprintf($bstr, $boundary1, $html['header'], $html['content']); 00402 foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']); 00403 $body[] = '--'.$boundary1.'--'; 00404 } 00405 } 00406 } else { 00407 if ($text) { 00408 $header[] = $text['header']; 00409 $body[] = $text['content']; 00410 } else if ($html) { 00411 $header[] = $html['header']; 00412 $body[] = $html['content']; 00413 } 00414 } 00415 $header[] = 'MIME-Version: 1.0'; 00416 return array('header' => implode($end, $header), 'content' => implode($end, $body)); 00417 } 00418 } 00419 00420 static public function isset_header($str = null, $name = null, $value = null, $debug = null) { 00421 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00422 $err = array(); 00423 if (!(is_string($str) && $str != '')) $err[] = 'invalid header type'; 00424 if (!(is_string($name) && strlen($name) > 1 && FUNC5::is_alpha($name, true, '-'))) $err[] = 'invalid name type'; 00425 if ($value != null && !is_string($value)) $err[] = 'invalid value type'; 00426 if (count($err) > 0) FUNC5::trace($debug, implode(', ', $err)); 00427 else { 00428 $ret = false; 00429 if ($exp = self::split_header($str, $debug)) { 00430 foreach ($exp as $harr) { 00431 if (strtolower($harr['name']) == strtolower($name)) { 00432 if ($value != null) $ret = (strtolower($harr['value']) == strtolower($value)) ? $harr['value'] : false; 00433 else $ret = $harr['value']; 00434 if ($ret) break; 00435 } 00436 } 00437 } 00438 return $ret; 00439 } 00440 } 00441 00442 static public function split_header($str = null, $debug = null) { 00443 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00444 if (!(is_string($str) && $str != '')) FUNC5::trace($debug, 'invalid header value'); 00445 else { 00446 $str = str_replace(array(";\r\n\t", "; \r\n\t", ";\r\n ", "; \r\n "), '; ', $str); 00447 $str = str_replace(array(";\n\t", "; \n\t", ";\n ", "; \n "), '; ', $str); 00448 $str = str_replace(array("\r\n\t", "\r\n "), '', $str); 00449 $str = str_replace(array("\n\t", "\n "), '', $str); 00450 $arr = array(); 00451 foreach (explode("\n", $str) as $line) { 00452 $line = trim(FUNC5::str_clear($line)); 00453 if ($line != '') { 00454 if (count($exp1 = explode(':', $line, 2)) == 2) { 00455 $name = rtrim($exp1[0]); 00456 $val1 = ltrim($exp1[1]); 00457 if (strlen($name) > 1 && FUNC5::is_alpha($name, true, '-') && $val1 != '') { 00458 $name = ucfirst($name); 00459 $hadd = array(); 00460 if (substr(strtolower($name), 0, 8) == 'content-') { 00461 $exp2 = explode('; ', $val1); 00462 $cnt2 = count($exp2); 00463 if ($cnt2 > 1) { 00464 for ($i = 1; $i < $cnt2; $i++) { 00465 if (count($exp3 = explode('=', $exp2[$i], 2)) == 2) { 00466 $hset = trim($exp3[0]); 00467 $hval = trim($exp3[1], ' "'); 00468 if ($hset != '' && $hval != '') $hadd[strtolower($hset)] = $hval; 00469 } 00470 } 00471 } 00472 } 00473 $val2 = (count($hadd) > 0) ? trim($exp2[0]) : $val1; 00474 $arr[] = array('name' => $name, 'value' => $val2, 'content' => $hadd); 00475 } 00476 } 00477 } 00478 } 00479 if (count($arr) > 0) return $arr; 00480 else FUNC5::trace($debug, 'invalid header value', 1); 00481 } 00482 } 00483 00484 static public function split_message($str = null, $debug = null) { 00485 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00486 if (!(is_string($str) && $str != '')) FUNC5::trace($debug, 'invalid message value'); 00487 else { 00488 $ret = false; 00489 if (strpos($str, "\r\n\r\n")) $ret = explode("\r\n\r\n", $str, 2); 00490 else if (strpos($str, "\n\n")) $ret = explode("\n\n", $str, 2); 00491 if ($ret) return array('header' => trim($ret[0]), 'content' => $ret[1]); 00492 else return false; 00493 } 00494 } 00495 00496 static public function split_mail($str = null, &$headers, &$body, $debug = null) { 00497 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00498 $headers = $body = false; 00499 if (!$part = self::split_message($str, $debug)) return false; 00500 if (!$harr = self::split_header($part['header'], $debug)) return false; 00501 $type = $boundary = false; 00502 foreach ($harr as $hnum) { 00503 if (strtolower($hnum['name']) == 'content-type') { 00504 $type = strtolower($hnum['value']); 00505 foreach ($hnum['content'] as $hnam => $hval) { 00506 if (strtolower($hnam) == 'boundary') { 00507 $boundary = $hval; 00508 break; 00509 } 00510 } 00511 if ($boundary) break; 00512 } 00513 } 00514 $headers = $harr; 00515 $body = array(); 00516 if (substr($type, 0, strlen('multipart/')) == 'multipart/' && $boundary && strstr($part['content'], '--'.$boundary.'--')) $body = self::_parts($part['content'], $boundary, strtolower(substr($type, strlen('multipart/'))), $debug); 00517 if (count($body) == 0) $body[] = self::_content($str, $debug); 00518 } 00519 00520 static private function _parts($str = null, $boundary = null, $multipart = null, $debug = null) { 00521 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00522 $err = array(); 00523 if (!(is_string($str) && $str != '')) $err[] = 'invalid content value'; 00524 if (!(is_string($boundary) && $boundary != '')) $err[] = 'invalid boundary value'; 00525 if (!(is_string($multipart) && $multipart != '')) $err[] = 'invalid multipart value'; 00526 if (count($err) > 0) FUNC5::trace($debug, implode(', ', $err)); 00527 else { 00528 $ret = array(); 00529 if (count($exp = explode('--'.$boundary.'--', $str)) == 2) { 00530 if (count($exp = explode('--'.$boundary, $exp[0])) > 2) { 00531 $cnt = 0; 00532 foreach ($exp as $split) { 00533 $cnt++; 00534 if ($cnt > 1 && $part = self::split_message($split, $debug)) { 00535 if ($harr = self::split_header($part['header'], $debug)) { 00536 $type = $newb = false; 00537 foreach ($harr as $hnum) { 00538 if (strtolower($hnum['name']) == 'content-type') { 00539 $type = strtolower($hnum['value']); 00540 foreach ($hnum['content'] as $hnam => $hval) { 00541 if (strtolower($hnam) == 'boundary') { 00542 $newb = $hval; 00543 break; 00544 } 00545 } 00546 if ($newb) break; 00547 } 00548 } 00549 if (substr($type, 0, strlen('multipart/')) == 'multipart/' && $newb && strstr($part['content'], '--'.$newb.'--')) $ret = self::_parts($part['content'], $newb, $multipart.'|'.strtolower(substr($type, strlen('multipart/'))), $debug); 00550 else { 00551 $res = self::_content($split, $debug); 00552 $res['multipart'] = $multipart; 00553 $ret[] = $res; 00554 } 00555 } 00556 } 00557 } 00558 } 00559 } 00560 return $ret; 00561 } 00562 } 00563 00564 static private function _content($str = null, $debug = null) { 00565 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00566 if (!(is_string($str) && $str != '')) FUNC5::trace($debug, 'invalid content value'); 00567 else { 00568 if (!$part = self::split_message($str, $debug)) return null; 00569 if (!$harr = self::split_header($part['header'], $debug)) return null; 00570 $body = array(); 00571 $clen = strlen('content-'); 00572 $encoding = false; 00573 foreach ($harr as $hnum) { 00574 if (substr(strtolower($hnum['name']), 0, $clen) == 'content-') { 00575 $name = strtolower(substr($hnum['name'], $clen)); 00576 if ($name == 'transfer-encoding') $encoding = strtolower($hnum['value']); 00577 else if ($name == 'id') $body[$name] = array('value' => trim($hnum['value'], '<>'), 'extra' => $hnum['content']); 00578 else $body[$name] = array('value' => $hnum['value'], 'extra' => $hnum['content']); 00579 } 00580 } 00581 if ($encoding == 'base64' || $encoding == 'quoted-printable') $body['content'] = self::decode_content($part['content'], $encoding, $debug); 00582 else { 00583 if ($encoding) $body['transfer-encoding'] = $encoding; 00584 $body['content'] = $part['content']; 00585 } 00586 if (substr($body['content'], -2) == "\r\n") $body['content'] = substr($body['content'], 0, -2); 00587 else if (substr($body['content'], -1) == "\n") $body['content'] = substr($body['content'], 0, -1); 00588 return $body; 00589 } 00590 } 00591 00592 static public function fix_eol($str = null, $debug = null) { 00593 if (!FUNC5::is_debug($debug)) $debug = debug_backtrace(); 00594 if (!(is_string($str) && $str != '')) FUNC5::trace($debug, 'invalid content value'); 00595 else { 00596 $str = str_replace("\r\n", "\n", $str); 00597 $str = str_replace("\r", "\n", $str); 00598 if (self::LE != "\n") $str = str_replace("\n", self::LE, $str); 00599 return $str; 00600 } 00601 } 00602 00603 } 00604 00605 ?>