Xataface Email Module 0.2
Email/Mailmerge Module for Xataface
lib/XPM/PHP4/MIME4.php
Go to the documentation of this file.
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('FUNC4')) require_once 'FUNC4.php';
00024 
00025 class MIME4 {
00026 
00027         var $LE = "\r\n";
00028         var $HLEN = 52;
00029         var $MLEN = 73;
00030 
00031         var $HCHARSET = 'utf-8';
00032         var $MCHARSET = 'us-ascii';
00033 
00034         var $HENCDEF = 'quoted-printable';
00035         var $MENCDEF = 'quoted-printable';
00036 
00037         var $hencarr = array('quoted-printable' => '', 'base64' => '');
00038         var $mencarr = array('7bit' => '', '8bit' => '', 'quoted-printable' => '', 'base64' => '', 'binary' => '');
00039 
00040         var $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         var $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         function unique($add = null) {
00087                 return md5(FUNC4::microtime_float().$add);
00088         }
00089 
00090         function is_printable($str = null, $debug = null) {
00091                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00092                 if (!is_string($str)) FUNC4::trace($debug, 'invalid argument type');
00093                 else {
00094                         $_mime = new MIME4;
00095                         $contain = implode('', $_mime->qpkeys);
00096                         return (strcspn($str, $contain) == strlen($str));
00097                 }
00098         }
00099 
00100         function qp_encode($str = null, $len = null, $end = null, $debug = null) {
00101                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00102                 $_mime = new MIME4;
00103                 $err = array();
00104                 if (!is_string($str)) $err[] = 'invalid argument type';
00105                 if ($len == null) $len = $_mime->MLEN;
00106                 else if (!(is_int($len) && $len > 1)) $err[] = 'invalid line length value';
00107                 if ($end == null) $end = $_mime->LE;
00108                 else if (!is_string($end)) $err[] = 'invalid line end value';
00109                 if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
00110                 else {
00111                         if ($str == '') return $str;
00112                         else {
00113                                 $out = array();
00114                                 foreach (explode($end, $str) as $line) {
00115                                         if ($line == '') $out[] = '';
00116                                         else {
00117                                                 $line = str_replace('=', '=3D', $line);
00118                                                 $line = str_replace($_mime->qpkeys, $_mime->qpvrep, $line);
00119                                                 preg_match_all('/.{1,'.$len.'}([^=]{0,2})?/', $line, $match);
00120                                                 $mcnt = count($match[0]);
00121                                                 for ($i = 0; $i < $mcnt; $i++) {
00122                                                         $line = (substr($match[0][$i], -1) == ' ') ? substr($match[0][$i], 0, -1).'=20' : $match[0][$i];
00123                                                         if (($i+1) < $mcnt) $line .= '=';
00124                                                         $out[] = $line;
00125                                                 }
00126                                         }
00127                                 }
00128                                 return implode($end, $out);
00129                         }
00130                 }
00131         }
00132 
00133         function encode_header($str = null, $charset = null, $encoding = null, $len = null, $end = null, $debug = null) {
00134                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00135                 $_mime = new MIME4;
00136                 $err = array();
00137                 if (!is_string($str)) $err[] = 'invalid argument type';
00138                 if ($charset == null) $charset = $_mime->HCHARSET;
00139                 else if (!is_string($charset)) $err[] = 'invalid charset type';
00140                 else if (!(strlen($charset) >= 2 && FUNC4::is_alpha($charset, true, '-'))) $err[] = 'invalid charset value';
00141                 if ($encoding == null) $encoding = $_mime->HENCDEF;
00142                 else if (!is_string($encoding)) $err[] = 'invalid encoding type';
00143                 else {
00144                         $encoding = strtolower(FUNC4::str_clear($encoding));
00145                         if (!isset($_mime->hencarr[$encoding])) $err[] = 'invalid encoding value';
00146                 }
00147                 if ($len == null) $len = $_mime->HLEN;
00148                 else if (!(is_int($len) && $len > 1)) $err[] = 'invalid line length value';
00149                 if ($end == null) $end = $_mime->LE;
00150                 else if (!is_string($end)) $err[] = 'invalid line end value';
00151                 if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
00152                 else {
00153                         if ($str == '') return $str;
00154                         else {
00155                                 $enc = false;
00156                                 $dif = $len - strlen('=?'.$charset.'?X??=');
00157                                 if ($encoding == 'quoted-printable') {
00158                                         if (!MIME4::is_printable($str)) {
00159                                                 $new = (($dif-4) > 2) ? ($dif-4) : $len;
00160                                                 $enc = MIME4::qp_encode($str, $new, $end);
00161                                                 $enc = str_replace(array('?', ' ', '='.$end), array('=3F', '_', $end), $enc);
00162                                         }
00163                                 } else if ($encoding == 'base64') {
00164                                         $new = ($dif > 3) ? $dif : $len;
00165                                         if ($new > 3) {
00166                                                 for ($i = $new; $i > 2; $i--) {
00167                                                         $crt = '';
00168                                                         for ($j = 0; $j <= $i; $j++) $crt .= 'x';
00169                                                         if (strlen(base64_encode($crt)) <= $new) {
00170                                                                 $new = $i;
00171                                                                 break;
00172                                                         }
00173                                                 }
00174                                         }
00175                                         $cnk = rtrim(chunk_split($str, $new, $end));
00176                                         $imp = array();
00177                                         foreach (explode($end, $cnk) as $line) if ($line != '') $imp[] = base64_encode($line);
00178                                         $enc = implode($end, $imp);
00179                                 }
00180                                 $res = array();
00181                                 if ($enc) {
00182                                         $chr = ($encoding == 'base64') ? 'B' : 'Q';
00183                                         foreach (explode($end, $enc) as $val) if ($val != '') $res[] = '=?'.$charset.'?'.$chr.'?'.$val.'?=';
00184                                 } else {
00185                                         $cnk = rtrim(chunk_split($str, $len, $end));
00186                                         foreach (explode($end, $cnk) as $val) if ($val != '') $res[] = $val;
00187                                 }
00188                                 return implode($end."\t", $res);
00189                         }
00190                 }
00191         }
00192 
00193         function decode_header($str = null, $debug = null) {
00194                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00195                 if (!is_string($str)) FUNC4::trace($debug, 'invalid argument type');
00196                 else {
00197                         $_mime = new MIME4;
00198                         $str = trim(FUNC4::str_clear($str));
00199                         $arr = array();
00200                         if ($str == '') $arr[] = array('charset' => $_mime->HCHARSET, 'value' => '');
00201                         else {
00202                                 foreach (preg_split('/(?<!\\?(?i)q)\\?\\=/', $str, -1, PREG_SPLIT_NO_EMPTY) as $str1) {
00203                                         foreach (explode('=?', $str1, 2) as $str2) {
00204                                                 $def = false;
00205                                                 if (count($exp = explode('?B?', $str2)) == 2) {
00206                                                         if (strlen($exp[0]) >= 2 && FUNC4::is_alpha($exp[0], true, '-') && trim($exp[1]) != '') $def = array('charset' => $exp[0], 'value' => base64_decode(trim($exp[1])));
00207                                                 } else if (count($exp = explode('?b?', $str2)) == 2) {
00208                                                         if (strlen($exp[0]) >= 2 && FUNC4::is_alpha($exp[0], true, '-') && trim($exp[1]) != '') $def = array('charset' => $exp[0], 'value' => base64_decode(trim($exp[1])));
00209                                                 } else if (count($exp = explode('?Q?', $str2)) == 2) {
00210                                                         if (strlen($exp[0]) >= 2 && FUNC4::is_alpha($exp[0], true, '-') && $exp[1] != '') $def = array('charset' => $exp[0], 'value' => quoted_printable_decode(str_replace('_', ' ', $exp[1])));
00211                                                 } else if (count($exp = explode('?q?', $str2)) == 2) {
00212                                                         if (strlen($exp[0]) >= 2 && FUNC4::is_alpha($exp[0], true, '-') && $exp[1] != '') $def = array('charset' => $exp[0], 'value' => quoted_printable_decode(str_replace('_', ' ', $exp[1])));
00213                                                 }
00214                                                 if ($def) {
00215                                                         if ($def['value'] != '') $arr[] = array('charset' => $def['charset'], 'value' => $def['value']);
00216                                                 } else {
00217                                                         if ($str2 != '') $arr[] = array('charset' => $_mime->HCHARSET, 'value' => $str2);
00218                                                 }
00219                                         }
00220                                 }
00221                         }
00222                         return $arr;
00223                 }
00224         }
00225 
00226         function decode_content($str = null, $encoding = null, $debug = null) {
00227                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00228                 $err = array();
00229                 if (!is_string($str)) $err[] = 'invalid content type';
00230                 if ($encoding == null) $encoding = '7bit';
00231                 else if (!is_string($encoding)) $err[] = 'invalid encoding type';
00232                 else {
00233                         $_mime = new MIME4;
00234                         $encoding = strtolower($encoding);
00235                         if (!isset($_mime->mencarr[$encoding])) $err[] = 'invalid encoding value';
00236                 }
00237                 if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
00238                 else {
00239                         if ($encoding == 'base64') {
00240                                 $str = trim(FUNC4::str_clear($str));
00241                                 return base64_decode($str);
00242                         } else if ($encoding == 'quoted-printable') {
00243                                 return quoted_printable_decode($str);
00244                         } else return $str;
00245                 }
00246         }
00247 
00248         function message($content = null, $type = null, $name = null, $charset = null, $encoding = null, $disposition = null, $id = null, $len = null, $end = null, $debug = null) {
00249                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00250                 $_mime = new MIME4;
00251                 $err = array();
00252                 if (!(is_string($content) && $content != '')) $err[] = 'invalid content type';
00253                 if ($type == null) $type = 'application/octet-stream';
00254                 else if (is_string($type)) {
00255                         $type = trim(FUNC4::str_clear($type));
00256                         if (strlen($type) < 4) $err[] = 'invalid type value';
00257                 } else $err[] = 'invalid type';
00258                 if (is_string($name)) {
00259                         $name = trim(FUNC4::str_clear($name));
00260                         if ($name == '') $err[] = 'invalid name value';
00261                 } else if ($name != null) $err[] = 'invalid name type';
00262                 if ($charset == null) $charset = $_mime->MCHARSET;
00263                 else if (!is_string($charset)) $err[] = 'invalid charset type';
00264                 else if (!(strlen($charset) >= 2 && FUNC4::is_alpha($charset, true, '-'))) $err[] = 'invalid charset value';
00265                 if ($encoding == null) $encoding = $_mime->MENCDEF;
00266                 else if (!is_string($encoding)) $err[] = 'invalid encoding type';
00267                 else {
00268                         $encoding = strtolower(FUNC4::str_clear($encoding));
00269                         if (!isset($_mime->mencarr[$encoding])) $err[] = 'invalid encoding value';
00270                 }
00271                 if ($disposition == null) $disposition = 'inline';
00272                 else if (is_string($disposition)) {
00273                         $disposition = strtolower(FUNC4::str_clear($disposition));
00274                         if (!($disposition == 'inline' || $disposition == 'attachment')) $err[] = 'invalid disposition value';
00275                 } else $err[] = 'invalid disposition type';
00276                 if (is_string($id)) {
00277                         $id = FUNC4::str_clear($id, array(' '));
00278                         if ($id == '') $err[] = 'invalid id value';
00279                 } else if ($id != null) $err[] = 'invalid id type';
00280                 if ($len == null) $len = $_mime->MLEN;
00281                 else if (!(is_int($len) && $len > 1)) $err[] = 'invalid line length value';
00282                 if ($end == null) $end = $_mime->LE;
00283                 else if (!is_string($end)) $err[] = 'invalid line end value';
00284                 if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
00285                 else {
00286                         $header = ''.
00287                                 'Content-Type: '.$type.';'.$end."\t".'charset="'.$charset.'"'.
00288                                 (($name == null) ? '' : ';'.$end."\t".'name="'.$name.'"').$end.
00289                                 'Content-Transfer-Encoding: '.$encoding.$end.
00290                                 'Content-Disposition: '.$disposition.
00291                                 (($name == null) ? '' : ';'.$end."\t".'filename="'.$name.'"').
00292                                 (($id == null) ? '' : $end.'Content-ID: <'.$id.'>');
00293                         if ($encoding == '7bit' || $encoding == '8bit') $content = wordwrap(MIME4::fix_eol($content), $len, $end, true);
00294                         else if ($encoding == 'base64') $content = rtrim(chunk_split(base64_encode($content), $len, $end));
00295                         else if ($encoding == 'quoted-printable') $content = MIME4::qp_encode(MIME4::fix_eol($content), $len, $end);
00296                         return array('header' => $header, 'content' => $content);
00297                 }
00298         }
00299 
00300         function compose($text = null, $html = null, $attach = null, $uniq = null, $end = null, $debug = null) {
00301                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00302                 $_mime = new MIME4;
00303                 $err = array();
00304                 if ($text == null && $html == null) $err[] = 'message is not set';
00305                 else {
00306                         if ($text != null) {
00307                                 if (!(is_array($text) && isset($text['header'], $text['content']) && is_string($text['header']) && is_string($text['content']) && MIME4::isset_header($text['header'], 'content-type', 'text/plain', $debug))) $err[] = 'invalid text message type';
00308                         }
00309                         if ($html != null) {
00310                                 if (!(is_array($html) && isset($html['header'], $html['content']) && is_string($html['header']) && is_string($html['content']) && MIME4::isset_header($html['header'], 'content-type', 'text/html', $debug))) $err[] = 'invalid html message type';
00311                         }
00312                 }
00313                 if ($attach != null) {
00314                         if (is_array($attach) && count($attach) > 0) {
00315                                 foreach ($attach as $arr) {
00316                                         if (!(is_array($arr) && isset($arr['header'], $arr['content']) && is_string($arr['header']) && is_string($arr['content']) && (MIME4::isset_header($arr['header'], 'content-disposition', 'inline', $debug) || MIME4::isset_header($arr['header'], 'content-disposition', 'attachment', $debug)))) {
00317                                                 $err[] = 'invalid attachment type';
00318                                                 break;
00319                                         }
00320                                 }
00321                         } else $err[] = 'invalid attachment format';
00322                 }
00323                 if ($end == null) $end = $_mime->LE;
00324                 else if (!is_string($end)) $err[] = 'invalid line end value';
00325                 if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
00326                 else {
00327                         $multipart = false;
00328                         if ($text && $html) $multipart = true;
00329                         if ($attach) $multipart = true;
00330                         $header = $body = array();
00331                         $header[] = 'Date: '.date('r');
00332                         $header[] = base64_decode('WC1NYWlsZXI6IFhQTTQgdi4wLjUgPCB3d3cueHBlcnRtYWlsZXIuY29tID4=');
00333                         if ($multipart) {
00334                                 $uniq = ($uniq == null) ? 0 : intval($uniq);
00335                                 $boundary1 = '=_1.'.MIME4::unique($uniq++);
00336                                 $boundary2 = '=_2.'.MIME4::unique($uniq++);
00337                                 $boundary3 = '=_3.'.MIME4::unique($uniq++);
00338                                 $disp['inline'] = $disp['attachment'] = false;
00339                                 if ($attach != null) {
00340                                         foreach ($attach as $darr) {
00341                                                 if (MIME4::isset_header($darr['header'], 'content-disposition', 'inline', $debug)) $disp['inline'] = true;
00342                                                 else if (MIME4::isset_header($darr['header'], 'content-disposition', 'attachment', $debug)) $disp['attachment'] = true;
00343                                         }
00344                                 }
00345                                 $hstr = 'Content-Type: multipart/%s;'.$end."\t".'boundary="%s"';
00346                                 $bstr = '--%s'.$end.'%s'.$end.$end.'%s';
00347                                 $body[] = 'This is a message in MIME Format. If you see this, your mail reader does not support this format.'.$end;
00348                                 if ($text && $html) {
00349                                                 if ($disp['inline'] && $disp['attachment']) {
00350                                                         $header[] = sprintf($hstr, 'mixed', $boundary1);
00351                                                         $body[] = '--'.$boundary1;
00352                                                         $body[] = sprintf($hstr, 'related', $boundary2).$end;
00353                                                         $body[] = '--'.$boundary2;
00354                                                         $body[] = sprintf($hstr, 'alternative', $boundary3).$end;
00355                                                         $body[] = sprintf($bstr, $boundary3, $text['header'], $text['content']);
00356                                                         $body[] = sprintf($bstr, $boundary3, $html['header'], $html['content']);
00357                                                         $body[] = '--'.$boundary3.'--';
00358                                                         foreach ($attach as $desc) if (MIME4::isset_header($desc['header'], 'content-disposition', 'inline', $debug)) $body[] = sprintf($bstr, $boundary2, $desc['header'], $desc['content']);
00359                                                         $body[] = '--'.$boundary2.'--';
00360                                                         foreach ($attach as $desc) if (MIME4::isset_header($desc['header'], 'content-disposition', 'attachment', $debug)) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
00361                                                         $body[] = '--'.$boundary1.'--';
00362                                                 } else if ($disp['inline']) {
00363                                                         $header[] = sprintf($hstr, 'related', $boundary1);
00364                                                         $body[] = '--'.$boundary1;
00365                                                         $body[] = sprintf($hstr, 'alternative', $boundary2).$end;
00366                                                         $body[] = sprintf($bstr, $boundary2, $text['header'], $text['content']);
00367                                                         $body[] = sprintf($bstr, $boundary2, $html['header'], $html['content']);
00368                                                         $body[] = '--'.$boundary2.'--';
00369                                                         foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
00370                                                         $body[] = '--'.$boundary1.'--';
00371                                                 } else if ($disp['attachment']) {
00372                                                         $header[] = sprintf($hstr, 'mixed', $boundary1);
00373                                                         $body[] = '--'.$boundary1;
00374                                                         $body[] = sprintf($hstr, 'alternative', $boundary2).$end;
00375                                                         $body[] = sprintf($bstr, $boundary2, $text['header'], $text['content']);
00376                                                         $body[] = sprintf($bstr, $boundary2, $html['header'], $html['content']);
00377                                                         $body[] = '--'.$boundary2.'--';
00378                                                         foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
00379                                                         $body[] = '--'.$boundary1.'--';
00380                                                 } else {
00381                                                         $header[] = sprintf($hstr, 'alternative', $boundary1);
00382                                                         $body[] = sprintf($bstr, $boundary1, $text['header'], $text['content']);
00383                                                         $body[] = sprintf($bstr, $boundary1, $html['header'], $html['content']);
00384                                                         $body[] = '--'.$boundary1.'--';
00385                                                 }
00386                                 } else if ($text) {
00387                                         $header[] = sprintf($hstr, 'mixed', $boundary1);
00388                                         $body[] = sprintf($bstr, $boundary1, $text['header'], $text['content']);
00389                                         foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
00390                                         $body[] = '--'.$boundary1.'--';
00391                                 } else if ($html) {
00392                                         if ($disp['inline'] && $disp['attachment']) {
00393                                                 $header[] = sprintf($hstr, 'mixed', $boundary1);
00394                                                 $body[] = '--'.$boundary1;
00395                                                 $body[] = sprintf($hstr, 'related', $boundary2).$end;
00396                                                 $body[] = sprintf($bstr, $boundary2, $html['header'], $html['content']);
00397                                                 foreach ($attach as $desc) if (MIME4::isset_header($desc['header'], 'content-disposition', 'inline', $debug)) $body[] = sprintf($bstr, $boundary2, $desc['header'], $desc['content']);
00398                                                 $body[] = '--'.$boundary2.'--';
00399                                                 foreach ($attach as $desc) if (MIME4::isset_header($desc['header'], 'content-disposition', 'attachment', $debug)) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
00400                                                 $body[] = '--'.$boundary1.'--';
00401                                         } else if ($disp['inline']) {
00402                                                 $header[] = sprintf($hstr, 'related', $boundary1);
00403                                                 $body[] = sprintf($bstr, $boundary1, $html['header'], $html['content']);
00404                                                 foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
00405                                                 $body[] = '--'.$boundary1.'--';
00406                                         } else if ($disp['attachment']) {
00407                                                 $header[] = sprintf($hstr, 'mixed', $boundary1);
00408                                                 $body[] = sprintf($bstr, $boundary1, $html['header'], $html['content']);
00409                                                 foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
00410                                                 $body[] = '--'.$boundary1.'--';
00411                                         }
00412                                 }
00413                         } else {
00414                                 if ($text) {
00415                                         $header[] = $text['header'];
00416                                         $body[] = $text['content'];
00417                                 } else if ($html) {
00418                                         $header[] = $html['header'];
00419                                         $body[] = $html['content'];
00420                                 }
00421                         }
00422                         $header[] = 'MIME-Version: 1.0';
00423                         return array('header' => implode($end, $header), 'content' => implode($end, $body));
00424                 }
00425         }
00426 
00427         function isset_header($str = null, $name = null, $value = null, $debug = null) {
00428                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00429                 $err = array();
00430                 if (!(is_string($str) && $str != '')) $err[] = 'invalid header type';
00431                 if (!(is_string($name) && strlen($name) > 1 && FUNC4::is_alpha($name, true, '-'))) $err[] = 'invalid name type';
00432                 if ($value != null && !is_string($value)) $err[] = 'invalid value type';
00433                 if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
00434                 else {
00435                         $ret = false;
00436                         if ($exp = MIME4::split_header($str, $debug)) {
00437                                 foreach ($exp as $harr) {
00438                                         if (strtolower($harr['name']) == strtolower($name)) {
00439                                                 if ($value != null) $ret = (strtolower($harr['value']) == strtolower($value)) ? $harr['value'] : false;
00440                                                 else $ret = $harr['value'];
00441                                                 if ($ret) break;
00442                                         }
00443                                 }
00444                         }
00445                         return $ret;
00446                 }
00447         }
00448 
00449         function split_header($str = null, $debug = null) {
00450                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00451                 if (!(is_string($str) && $str != '')) FUNC4::trace($debug, 'invalid header value');
00452                 else {
00453                         $str = str_replace(array(";\r\n\t", "; \r\n\t", ";\r\n ", "; \r\n "), '; ', $str);
00454                         $str = str_replace(array(";\n\t", "; \n\t", ";\n ", "; \n "), '; ', $str);
00455                         $str = str_replace(array("\r\n\t", "\r\n "), '', $str);
00456                         $str = str_replace(array("\n\t", "\n "), '', $str);
00457                         $arr = array();
00458                         foreach (explode("\n", $str) as $line) {
00459                                 $line = trim(FUNC4::str_clear($line));
00460                                 if ($line != '') {
00461                                         if (count($exp1 = explode(':', $line, 2)) == 2) {
00462                                                 $name = rtrim($exp1[0]);
00463                                                 $val1 = ltrim($exp1[1]);
00464                                                 if (strlen($name) > 1 && FUNC4::is_alpha($name, true, '-') && $val1 != '') {
00465                                                         $name = ucfirst($name);
00466                                                         $hadd = array();
00467                                                         if (substr(strtolower($name), 0, 8) == 'content-') {
00468                                                                 $exp2 = explode('; ', $val1);
00469                                                                 $cnt2 = count($exp2);
00470                                                                 if ($cnt2 > 1) {
00471                                                                         for ($i = 1; $i < $cnt2; $i++) {
00472                                                                                 if (count($exp3 = explode('=', $exp2[$i], 2)) == 2) {
00473                                                                                         $hset = trim($exp3[0]);
00474                                                                                         $hval = trim($exp3[1], ' "');
00475                                                                                         if ($hset != '' && $hval != '') $hadd[strtolower($hset)] = $hval;
00476                                                                                 }
00477                                                                         }
00478                                                                 }
00479                                                         }
00480                                                         $val2 = (count($hadd) > 0) ? trim($exp2[0]) : $val1;
00481                                                         $arr[] = array('name' => $name, 'value' => $val2, 'content' => $hadd);
00482                                                 }
00483                                         }
00484                                 }
00485                         }
00486                         if (count($arr) > 0) return $arr;
00487                         else FUNC4::trace($debug, 'invalid header value', 1);
00488                 }
00489         }
00490 
00491         function split_message($str = null, $debug = null) {
00492                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00493                 if (!(is_string($str) && $str != '')) FUNC4::trace($debug, 'invalid message value');
00494                 else {
00495                         $ret = false;
00496                         if (strpos($str, "\r\n\r\n")) $ret = explode("\r\n\r\n", $str, 2);
00497                         else if (strpos($str, "\n\n")) $ret = explode("\n\n", $str, 2);
00498                         if ($ret) return array('header' => trim($ret[0]), 'content' => $ret[1]);
00499                         else return false;
00500                 }
00501         }
00502 
00503         function split_mail($str = null, &$headers, &$body, $debug = null) {
00504                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00505                 $headers = $body = false;
00506                 if (!$part = MIME4::split_message($str, $debug)) return false;
00507                 if (!$harr = MIME4::split_header($part['header'], $debug)) return false;
00508                 $type = $boundary = false;
00509                 foreach ($harr as $hnum) {
00510                         if (strtolower($hnum['name']) == 'content-type') {
00511                                 $type = strtolower($hnum['value']);
00512                                 foreach ($hnum['content'] as $hnam => $hval) {
00513                                         if (strtolower($hnam) == 'boundary') {
00514                                                 $boundary = $hval;
00515                                                 break;
00516                                         }
00517                                 }
00518                                 if ($boundary) break;
00519                         }
00520                 }
00521                 $headers = $harr;
00522                 $body = array();
00523                 if (substr($type, 0, strlen('multipart/')) == 'multipart/' && $boundary && strstr($part['content'], '--'.$boundary.'--')) $body = MIME4::_parts($part['content'], $boundary, strtolower(substr($type, strlen('multipart/'))), $debug);
00524                 if (count($body) == 0) $body[] = MIME4::_content($str, $debug);
00525         }
00526 
00527         function _parts($str = null, $boundary = null, $multipart = null, $debug = null) {
00528                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00529                 $err = array();
00530                 if (!(is_string($str) && $str != '')) $err[] = 'invalid content value';
00531                 if (!(is_string($boundary) && $boundary != '')) $err[] = 'invalid boundary value';
00532                 if (!(is_string($multipart) && $multipart != '')) $err[] = 'invalid multipart value';
00533                 if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
00534                 else {
00535                         $ret = array();
00536                         if (count($exp = explode('--'.$boundary.'--', $str)) == 2) {
00537                                 if (count($exp = explode('--'.$boundary, $exp[0])) > 2) {
00538                                         $cnt = 0;
00539                                         foreach ($exp as $split) {
00540                                                 $cnt++;
00541                                                 if ($cnt > 1 && $part = MIME4::split_message($split, $debug)) {
00542                                                         if ($harr = MIME4::split_header($part['header'], $debug)) {
00543                                                                 $type = $newb = false;
00544                                                                 foreach ($harr as $hnum) {
00545                                                                         if (strtolower($hnum['name']) == 'content-type') {
00546                                                                                 $type = strtolower($hnum['value']);
00547                                                                                 foreach ($hnum['content'] as $hnam => $hval) {
00548                                                                                         if (strtolower($hnam) == 'boundary') {
00549                                                                                                 $newb = $hval;
00550                                                                                                 break;
00551                                                                                         }
00552                                                                                 }
00553                                                                                 if ($newb) break;
00554                                                                         }
00555                                                                 }
00556                                                                 if (substr($type, 0, strlen('multipart/')) == 'multipart/' && $newb && strstr($part['content'], '--'.$newb.'--')) $ret = MIME4::_parts($part['content'], $newb, $multipart.'|'.strtolower(substr($type, strlen('multipart/'))), $debug);
00557                                                                 else {
00558                                                                         $res = MIME4::_content($split, $debug);
00559                                                                         $res['multipart'] = $multipart;
00560                                                                         $ret[] = $res;
00561                                                                 }
00562                                                         }
00563                                                 }
00564                                         }
00565                                 }
00566                         }
00567                         return $ret;
00568                 }
00569         }
00570 
00571         function _content($str = null, $debug = null) {
00572                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00573                 if (!(is_string($str) && $str != '')) FUNC4::trace($debug, 'invalid content value');
00574                 else {
00575                         if (!$part = MIME4::split_message($str, $debug)) return null;
00576                         if (!$harr = MIME4::split_header($part['header'], $debug)) return null;
00577                         $body = array();
00578                         $clen = strlen('content-');
00579                         $encoding = false;
00580                         foreach ($harr as $hnum) {
00581                                 if (substr(strtolower($hnum['name']), 0, $clen) == 'content-') {
00582                                         $name = strtolower(substr($hnum['name'], $clen));
00583                                         if ($name == 'transfer-encoding') $encoding = strtolower($hnum['value']);
00584                                         else if ($name == 'id') $body[$name] = array('value' => trim($hnum['value'], '<>'), 'extra' => $hnum['content']);
00585                                         else $body[$name] = array('value' => $hnum['value'], 'extra' => $hnum['content']);
00586                                 }
00587                         }
00588                         if ($encoding == 'base64' || $encoding == 'quoted-printable') $body['content'] = MIME4::decode_content($part['content'], $encoding, $debug);
00589                         else {
00590                                 if ($encoding) $body['transfer-encoding'] = $encoding;
00591                                 $body['content'] = $part['content'];
00592                         }
00593                         if (substr($body['content'], -2) == "\r\n") $body['content'] = substr($body['content'], 0, -2);
00594                         else if (substr($body['content'], -1) == "\n") $body['content'] = substr($body['content'], 0, -1);
00595                         return $body;
00596                 }
00597         }
00598 
00599         function fix_eol($str = null, $debug = null) {
00600                 if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
00601                 if (!(is_string($str) && $str != '')) FUNC4::trace($debug, 'invalid content value');
00602                 else {
00603                         $_mime = new MIME4;
00604                         $str = str_replace("\r\n", "\n", $str);
00605                         $str = str_replace("\r", "\n", $str);
00606                         if ($_mime->LE != "\n") $str = str_replace("\n", $_mime->LE, $str);
00607                         return $str;
00608                 }
00609         }
00610 
00611 }
00612 
00613 ?>
 All Data Structures Files Functions Variables Enumerations