Xataface Email Module  0.3.2
Email/Mailmerge Module for Xataface
 All Data Structures Files Functions Variables Pages
MIME4.php
Go to the documentation of this file.
1 <?php
2 
3 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
4  * *
5  * XPertMailer is a PHP Mail Class that can send and read messages in MIME format. *
6  * This file is part of the XPertMailer package (http://xpertmailer.sourceforge.net/) *
7  * Copyright (C) 2007 Tanase Laurentiu Iulian *
8  * *
9  * This library is free software; you can redistribute it and/or modify it under the *
10  * terms of the GNU Lesser General Public License as published by the Free Software *
11  * Foundation; either version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, but WITHOUT ANY *
14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
15  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU Lesser General Public License along with *
18  * this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, *
19  * Fifth Floor, Boston, MA 02110-1301, USA *
20  * *
21  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22 
23 if (!class_exists('FUNC4')) require_once 'FUNC4.php';
24 
25 class MIME4 {
26 
27  var $LE = "\r\n";
28  var $HLEN = 52;
29  var $MLEN = 73;
30 
31  var $HCHARSET = 'utf-8';
32  var $MCHARSET = 'us-ascii';
33 
34  var $HENCDEF = 'quoted-printable';
35  var $MENCDEF = 'quoted-printable';
36 
37  var $hencarr = array('quoted-printable' => '', 'base64' => '');
38  var $mencarr = array('7bit' => '', '8bit' => '', 'quoted-printable' => '', 'base64' => '', 'binary' => '');
39 
40  var $qpkeys = array(
41  "\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07",
42  "\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F",
43  "\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17",
44  "\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F",
45  "\x7F","\x80","\x81","\x82","\x83","\x84","\x85","\x86",
46  "\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E",
47  "\x8F","\x90","\x91","\x92","\x93","\x94","\x95","\x96",
48  "\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E",
49  "\x9F","\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6",
50  "\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE",
51  "\xAF","\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6",
52  "\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE",
53  "\xBF","\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6",
54  "\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE",
55  "\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6",
56  "\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE",
57  "\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6",
58  "\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE",
59  "\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6",
60  "\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE",
61  "\xFF");
62 
63  var $qpvrep = array(
64  "=00","=01","=02","=03","=04","=05","=06","=07",
65  "=08","=09","=0A","=0B","=0C","=0D","=0E","=0F",
66  "=10","=11","=12","=13","=14","=15","=16","=17",
67  "=18","=19","=1A","=1B","=1C","=1D","=1E","=1F",
68  "=7F","=80","=81","=82","=83","=84","=85","=86",
69  "=87","=88","=89","=8A","=8B","=8C","=8D","=8E",
70  "=8F","=90","=91","=92","=93","=94","=95","=96",
71  "=97","=98","=99","=9A","=9B","=9C","=9D","=9E",
72  "=9F","=A0","=A1","=A2","=A3","=A4","=A5","=A6",
73  "=A7","=A8","=A9","=AA","=AB","=AC","=AD","=AE",
74  "=AF","=B0","=B1","=B2","=B3","=B4","=B5","=B6",
75  "=B7","=B8","=B9","=BA","=BB","=BC","=BD","=BE",
76  "=BF","=C0","=C1","=C2","=C3","=C4","=C5","=C6",
77  "=C7","=C8","=C9","=CA","=CB","=CC","=CD","=CE",
78  "=CF","=D0","=D1","=D2","=D3","=D4","=D5","=D6",
79  "=D7","=D8","=D9","=DA","=DB","=DC","=DD","=DE",
80  "=DF","=E0","=E1","=E2","=E3","=E4","=E5","=E6",
81  "=E7","=E8","=E9","=EA","=EB","=EC","=ED","=EE",
82  "=EF","=F0","=F1","=F2","=F3","=F4","=F5","=F6",
83  "=F7","=F8","=F9","=FA","=FB","=FC","=FD","=FE",
84  "=FF");
85 
86  function unique($add = null) {
87  return md5(FUNC4::microtime_float().$add);
88  }
89 
90  function is_printable($str = null, $debug = null) {
91  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
92  if (!is_string($str)) FUNC4::trace($debug, 'invalid argument type');
93  else {
94  $_mime = new MIME4;
95  $contain = implode('', $_mime->qpkeys);
96  return (strcspn($str, $contain) == strlen($str));
97  }
98  }
99 
100  function qp_encode($str = null, $len = null, $end = null, $debug = null) {
101  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
102  $_mime = new MIME4;
103  $err = array();
104  if (!is_string($str)) $err[] = 'invalid argument type';
105  if ($len == null) $len = $_mime->MLEN;
106  else if (!(is_int($len) && $len > 1)) $err[] = 'invalid line length value';
107  if ($end == null) $end = $_mime->LE;
108  else if (!is_string($end)) $err[] = 'invalid line end value';
109  if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
110  else {
111  if ($str == '') return $str;
112  else {
113  $out = array();
114  foreach (explode($end, $str) as $line) {
115  if ($line == '') $out[] = '';
116  else {
117  $line = str_replace('=', '=3D', $line);
118  $line = str_replace($_mime->qpkeys, $_mime->qpvrep, $line);
119  preg_match_all('/.{1,'.$len.'}([^=]{0,2})?/', $line, $match);
120  $mcnt = count($match[0]);
121  for ($i = 0; $i < $mcnt; $i++) {
122  $line = (substr($match[0][$i], -1) == ' ') ? substr($match[0][$i], 0, -1).'=20' : $match[0][$i];
123  if (($i+1) < $mcnt) $line .= '=';
124  $out[] = $line;
125  }
126  }
127  }
128  return implode($end, $out);
129  }
130  }
131  }
132 
133  function encode_header($str = null, $charset = null, $encoding = null, $len = null, $end = null, $debug = null) {
134  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
135  $_mime = new MIME4;
136  $err = array();
137  if (!is_string($str)) $err[] = 'invalid argument type';
138  if ($charset == null) $charset = $_mime->HCHARSET;
139  else if (!is_string($charset)) $err[] = 'invalid charset type';
140  else if (!(strlen($charset) >= 2 && FUNC4::is_alpha($charset, true, '-'))) $err[] = 'invalid charset value';
141  if ($encoding == null) $encoding = $_mime->HENCDEF;
142  else if (!is_string($encoding)) $err[] = 'invalid encoding type';
143  else {
144  $encoding = strtolower(FUNC4::str_clear($encoding));
145  if (!isset($_mime->hencarr[$encoding])) $err[] = 'invalid encoding value';
146  }
147  if ($len == null) $len = $_mime->HLEN;
148  else if (!(is_int($len) && $len > 1)) $err[] = 'invalid line length value';
149  if ($end == null) $end = $_mime->LE;
150  else if (!is_string($end)) $err[] = 'invalid line end value';
151  if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
152  else {
153  if ($str == '') return $str;
154  else {
155  $enc = false;
156  $dif = $len - strlen('=?'.$charset.'?X??=');
157  if ($encoding == 'quoted-printable') {
158  if (!MIME4::is_printable($str)) {
159  $new = (($dif-4) > 2) ? ($dif-4) : $len;
160  $enc = MIME4::qp_encode($str, $new, $end);
161  $enc = str_replace(array('?', ' ', '='.$end), array('=3F', '_', $end), $enc);
162  }
163  } else if ($encoding == 'base64') {
164  $new = ($dif > 3) ? $dif : $len;
165  if ($new > 3) {
166  for ($i = $new; $i > 2; $i--) {
167  $crt = '';
168  for ($j = 0; $j <= $i; $j++) $crt .= 'x';
169  if (strlen(base64_encode($crt)) <= $new) {
170  $new = $i;
171  break;
172  }
173  }
174  }
175  $cnk = rtrim(chunk_split($str, $new, $end));
176  $imp = array();
177  foreach (explode($end, $cnk) as $line) if ($line != '') $imp[] = base64_encode($line);
178  $enc = implode($end, $imp);
179  }
180  $res = array();
181  if ($enc) {
182  $chr = ($encoding == 'base64') ? 'B' : 'Q';
183  foreach (explode($end, $enc) as $val) if ($val != '') $res[] = '=?'.$charset.'?'.$chr.'?'.$val.'?=';
184  } else {
185  $cnk = rtrim(chunk_split($str, $len, $end));
186  foreach (explode($end, $cnk) as $val) if ($val != '') $res[] = $val;
187  }
188  return implode($end."\t", $res);
189  }
190  }
191  }
192 
193  function decode_header($str = null, $debug = null) {
194  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
195  if (!is_string($str)) FUNC4::trace($debug, 'invalid argument type');
196  else {
197  $_mime = new MIME4;
198  $str = trim(FUNC4::str_clear($str));
199  $arr = array();
200  if ($str == '') $arr[] = array('charset' => $_mime->HCHARSET, 'value' => '');
201  else {
202  foreach (preg_split('/(?<!\\?(?i)q)\\?\\=/', $str, -1, PREG_SPLIT_NO_EMPTY) as $str1) {
203  foreach (explode('=?', $str1, 2) as $str2) {
204  $def = false;
205  if (count($exp = explode('?B?', $str2)) == 2) {
206  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])));
207  } else if (count($exp = explode('?b?', $str2)) == 2) {
208  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])));
209  } else if (count($exp = explode('?Q?', $str2)) == 2) {
210  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])));
211  } else if (count($exp = explode('?q?', $str2)) == 2) {
212  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])));
213  }
214  if ($def) {
215  if ($def['value'] != '') $arr[] = array('charset' => $def['charset'], 'value' => $def['value']);
216  } else {
217  if ($str2 != '') $arr[] = array('charset' => $_mime->HCHARSET, 'value' => $str2);
218  }
219  }
220  }
221  }
222  return $arr;
223  }
224  }
225 
226  function decode_content($str = null, $encoding = null, $debug = null) {
227  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
228  $err = array();
229  if (!is_string($str)) $err[] = 'invalid content type';
230  if ($encoding == null) $encoding = '7bit';
231  else if (!is_string($encoding)) $err[] = 'invalid encoding type';
232  else {
233  $_mime = new MIME4;
234  $encoding = strtolower($encoding);
235  if (!isset($_mime->mencarr[$encoding])) $err[] = 'invalid encoding value';
236  }
237  if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
238  else {
239  if ($encoding == 'base64') {
240  $str = trim(FUNC4::str_clear($str));
241  return base64_decode($str);
242  } else if ($encoding == 'quoted-printable') {
243  return quoted_printable_decode($str);
244  } else return $str;
245  }
246  }
247 
248  function message($content = null, $type = null, $name = null, $charset = null, $encoding = null, $disposition = null, $id = null, $len = null, $end = null, $debug = null) {
249  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
250  $_mime = new MIME4;
251  $err = array();
252  if (!(is_string($content) && $content != '')) $err[] = 'invalid content type';
253  if ($type == null) $type = 'application/octet-stream';
254  else if (is_string($type)) {
255  $type = trim(FUNC4::str_clear($type));
256  if (strlen($type) < 4) $err[] = 'invalid type value';
257  } else $err[] = 'invalid type';
258  if (is_string($name)) {
259  $name = trim(FUNC4::str_clear($name));
260  if ($name == '') $err[] = 'invalid name value';
261  } else if ($name != null) $err[] = 'invalid name type';
262  if ($charset == null) $charset = $_mime->MCHARSET;
263  else if (!is_string($charset)) $err[] = 'invalid charset type';
264  else if (!(strlen($charset) >= 2 && FUNC4::is_alpha($charset, true, '-'))) $err[] = 'invalid charset value';
265  if ($encoding == null) $encoding = $_mime->MENCDEF;
266  else if (!is_string($encoding)) $err[] = 'invalid encoding type';
267  else {
268  $encoding = strtolower(FUNC4::str_clear($encoding));
269  if (!isset($_mime->mencarr[$encoding])) $err[] = 'invalid encoding value';
270  }
271  if ($disposition == null) $disposition = 'inline';
272  else if (is_string($disposition)) {
273  $disposition = strtolower(FUNC4::str_clear($disposition));
274  if (!($disposition == 'inline' || $disposition == 'attachment')) $err[] = 'invalid disposition value';
275  } else $err[] = 'invalid disposition type';
276  if (is_string($id)) {
277  $id = FUNC4::str_clear($id, array(' '));
278  if ($id == '') $err[] = 'invalid id value';
279  } else if ($id != null) $err[] = 'invalid id type';
280  if ($len == null) $len = $_mime->MLEN;
281  else if (!(is_int($len) && $len > 1)) $err[] = 'invalid line length value';
282  if ($end == null) $end = $_mime->LE;
283  else if (!is_string($end)) $err[] = 'invalid line end value';
284  if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
285  else {
286  $header = ''.
287  'Content-Type: '.$type.';'.$end."\t".'charset="'.$charset.'"'.
288  (($name == null) ? '' : ';'.$end."\t".'name="'.$name.'"').$end.
289  'Content-Transfer-Encoding: '.$encoding.$end.
290  'Content-Disposition: '.$disposition.
291  (($name == null) ? '' : ';'.$end."\t".'filename="'.$name.'"').
292  (($id == null) ? '' : $end.'Content-ID: <'.$id.'>');
293  if ($encoding == '7bit' || $encoding == '8bit') $content = wordwrap(MIME4::fix_eol($content), $len, $end, true);
294  else if ($encoding == 'base64') $content = rtrim(chunk_split(base64_encode($content), $len, $end));
295  else if ($encoding == 'quoted-printable') $content = MIME4::qp_encode(MIME4::fix_eol($content), $len, $end);
296  return array('header' => $header, 'content' => $content);
297  }
298  }
299 
300  function compose($text = null, $html = null, $attach = null, $uniq = null, $end = null, $debug = null) {
301  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
302  $_mime = new MIME4;
303  $err = array();
304  if ($text == null && $html == null) $err[] = 'message is not set';
305  else {
306  if ($text != null) {
307  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';
308  }
309  if ($html != null) {
310  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';
311  }
312  }
313  if ($attach != null) {
314  if (is_array($attach) && count($attach) > 0) {
315  foreach ($attach as $arr) {
316  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)))) {
317  $err[] = 'invalid attachment type';
318  break;
319  }
320  }
321  } else $err[] = 'invalid attachment format';
322  }
323  if ($end == null) $end = $_mime->LE;
324  else if (!is_string($end)) $err[] = 'invalid line end value';
325  if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
326  else {
327  $multipart = false;
328  if ($text && $html) $multipart = true;
329  if ($attach) $multipart = true;
330  $header = $body = array();
331  $header[] = 'Date: '.date('r');
332  $header[] = base64_decode('WC1NYWlsZXI6IFhQTTQgdi4wLjUgPCB3d3cueHBlcnRtYWlsZXIuY29tID4=');
333  if ($multipart) {
334  $uniq = ($uniq == null) ? 0 : intval($uniq);
335  $boundary1 = '=_1.'.MIME4::unique($uniq++);
336  $boundary2 = '=_2.'.MIME4::unique($uniq++);
337  $boundary3 = '=_3.'.MIME4::unique($uniq++);
338  $disp['inline'] = $disp['attachment'] = false;
339  if ($attach != null) {
340  foreach ($attach as $darr) {
341  if (MIME4::isset_header($darr['header'], 'content-disposition', 'inline', $debug)) $disp['inline'] = true;
342  else if (MIME4::isset_header($darr['header'], 'content-disposition', 'attachment', $debug)) $disp['attachment'] = true;
343  }
344  }
345  $hstr = 'Content-Type: multipart/%s;'.$end."\t".'boundary="%s"';
346  $bstr = '--%s'.$end.'%s'.$end.$end.'%s';
347  $body[] = 'This is a message in MIME Format. If you see this, your mail reader does not support this format.'.$end;
348  if ($text && $html) {
349  if ($disp['inline'] && $disp['attachment']) {
350  $header[] = sprintf($hstr, 'mixed', $boundary1);
351  $body[] = '--'.$boundary1;
352  $body[] = sprintf($hstr, 'related', $boundary2).$end;
353  $body[] = '--'.$boundary2;
354  $body[] = sprintf($hstr, 'alternative', $boundary3).$end;
355  $body[] = sprintf($bstr, $boundary3, $text['header'], $text['content']);
356  $body[] = sprintf($bstr, $boundary3, $html['header'], $html['content']);
357  $body[] = '--'.$boundary3.'--';
358  foreach ($attach as $desc) if (MIME4::isset_header($desc['header'], 'content-disposition', 'inline', $debug)) $body[] = sprintf($bstr, $boundary2, $desc['header'], $desc['content']);
359  $body[] = '--'.$boundary2.'--';
360  foreach ($attach as $desc) if (MIME4::isset_header($desc['header'], 'content-disposition', 'attachment', $debug)) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
361  $body[] = '--'.$boundary1.'--';
362  } else if ($disp['inline']) {
363  $header[] = sprintf($hstr, 'related', $boundary1);
364  $body[] = '--'.$boundary1;
365  $body[] = sprintf($hstr, 'alternative', $boundary2).$end;
366  $body[] = sprintf($bstr, $boundary2, $text['header'], $text['content']);
367  $body[] = sprintf($bstr, $boundary2, $html['header'], $html['content']);
368  $body[] = '--'.$boundary2.'--';
369  foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
370  $body[] = '--'.$boundary1.'--';
371  } else if ($disp['attachment']) {
372  $header[] = sprintf($hstr, 'mixed', $boundary1);
373  $body[] = '--'.$boundary1;
374  $body[] = sprintf($hstr, 'alternative', $boundary2).$end;
375  $body[] = sprintf($bstr, $boundary2, $text['header'], $text['content']);
376  $body[] = sprintf($bstr, $boundary2, $html['header'], $html['content']);
377  $body[] = '--'.$boundary2.'--';
378  foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
379  $body[] = '--'.$boundary1.'--';
380  } else {
381  $header[] = sprintf($hstr, 'alternative', $boundary1);
382  $body[] = sprintf($bstr, $boundary1, $text['header'], $text['content']);
383  $body[] = sprintf($bstr, $boundary1, $html['header'], $html['content']);
384  $body[] = '--'.$boundary1.'--';
385  }
386  } else if ($text) {
387  $header[] = sprintf($hstr, 'mixed', $boundary1);
388  $body[] = sprintf($bstr, $boundary1, $text['header'], $text['content']);
389  foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
390  $body[] = '--'.$boundary1.'--';
391  } else if ($html) {
392  if ($disp['inline'] && $disp['attachment']) {
393  $header[] = sprintf($hstr, 'mixed', $boundary1);
394  $body[] = '--'.$boundary1;
395  $body[] = sprintf($hstr, 'related', $boundary2).$end;
396  $body[] = sprintf($bstr, $boundary2, $html['header'], $html['content']);
397  foreach ($attach as $desc) if (MIME4::isset_header($desc['header'], 'content-disposition', 'inline', $debug)) $body[] = sprintf($bstr, $boundary2, $desc['header'], $desc['content']);
398  $body[] = '--'.$boundary2.'--';
399  foreach ($attach as $desc) if (MIME4::isset_header($desc['header'], 'content-disposition', 'attachment', $debug)) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
400  $body[] = '--'.$boundary1.'--';
401  } else if ($disp['inline']) {
402  $header[] = sprintf($hstr, 'related', $boundary1);
403  $body[] = sprintf($bstr, $boundary1, $html['header'], $html['content']);
404  foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
405  $body[] = '--'.$boundary1.'--';
406  } else if ($disp['attachment']) {
407  $header[] = sprintf($hstr, 'mixed', $boundary1);
408  $body[] = sprintf($bstr, $boundary1, $html['header'], $html['content']);
409  foreach ($attach as $desc) $body[] = sprintf($bstr, $boundary1, $desc['header'], $desc['content']);
410  $body[] = '--'.$boundary1.'--';
411  }
412  }
413  } else {
414  if ($text) {
415  $header[] = $text['header'];
416  $body[] = $text['content'];
417  } else if ($html) {
418  $header[] = $html['header'];
419  $body[] = $html['content'];
420  }
421  }
422  $header[] = 'MIME-Version: 1.0';
423  return array('header' => implode($end, $header), 'content' => implode($end, $body));
424  }
425  }
426 
427  function isset_header($str = null, $name = null, $value = null, $debug = null) {
428  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
429  $err = array();
430  if (!(is_string($str) && $str != '')) $err[] = 'invalid header type';
431  if (!(is_string($name) && strlen($name) > 1 && FUNC4::is_alpha($name, true, '-'))) $err[] = 'invalid name type';
432  if ($value != null && !is_string($value)) $err[] = 'invalid value type';
433  if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
434  else {
435  $ret = false;
436  if ($exp = MIME4::split_header($str, $debug)) {
437  foreach ($exp as $harr) {
438  if (strtolower($harr['name']) == strtolower($name)) {
439  if ($value != null) $ret = (strtolower($harr['value']) == strtolower($value)) ? $harr['value'] : false;
440  else $ret = $harr['value'];
441  if ($ret) break;
442  }
443  }
444  }
445  return $ret;
446  }
447  }
448 
449  function split_header($str = null, $debug = null) {
450  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
451  if (!(is_string($str) && $str != '')) FUNC4::trace($debug, 'invalid header value');
452  else {
453  $str = str_replace(array(";\r\n\t", "; \r\n\t", ";\r\n ", "; \r\n "), '; ', $str);
454  $str = str_replace(array(";\n\t", "; \n\t", ";\n ", "; \n "), '; ', $str);
455  $str = str_replace(array("\r\n\t", "\r\n "), '', $str);
456  $str = str_replace(array("\n\t", "\n "), '', $str);
457  $arr = array();
458  foreach (explode("\n", $str) as $line) {
459  $line = trim(FUNC4::str_clear($line));
460  if ($line != '') {
461  if (count($exp1 = explode(':', $line, 2)) == 2) {
462  $name = rtrim($exp1[0]);
463  $val1 = ltrim($exp1[1]);
464  if (strlen($name) > 1 && FUNC4::is_alpha($name, true, '-') && $val1 != '') {
465  $name = ucfirst($name);
466  $hadd = array();
467  if (substr(strtolower($name), 0, 8) == 'content-') {
468  $exp2 = explode('; ', $val1);
469  $cnt2 = count($exp2);
470  if ($cnt2 > 1) {
471  for ($i = 1; $i < $cnt2; $i++) {
472  if (count($exp3 = explode('=', $exp2[$i], 2)) == 2) {
473  $hset = trim($exp3[0]);
474  $hval = trim($exp3[1], ' "');
475  if ($hset != '' && $hval != '') $hadd[strtolower($hset)] = $hval;
476  }
477  }
478  }
479  }
480  $val2 = (count($hadd) > 0) ? trim($exp2[0]) : $val1;
481  $arr[] = array('name' => $name, 'value' => $val2, 'content' => $hadd);
482  }
483  }
484  }
485  }
486  if (count($arr) > 0) return $arr;
487  else FUNC4::trace($debug, 'invalid header value', 1);
488  }
489  }
490 
491  function split_message($str = null, $debug = null) {
492  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
493  if (!(is_string($str) && $str != '')) FUNC4::trace($debug, 'invalid message value');
494  else {
495  $ret = false;
496  if (strpos($str, "\r\n\r\n")) $ret = explode("\r\n\r\n", $str, 2);
497  else if (strpos($str, "\n\n")) $ret = explode("\n\n", $str, 2);
498  if ($ret) return array('header' => trim($ret[0]), 'content' => $ret[1]);
499  else return false;
500  }
501  }
502 
503  function split_mail($str = null, &$headers, &$body, $debug = null) {
504  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
505  $headers = $body = false;
506  if (!$part = MIME4::split_message($str, $debug)) return false;
507  if (!$harr = MIME4::split_header($part['header'], $debug)) return false;
508  $type = $boundary = false;
509  foreach ($harr as $hnum) {
510  if (strtolower($hnum['name']) == 'content-type') {
511  $type = strtolower($hnum['value']);
512  foreach ($hnum['content'] as $hnam => $hval) {
513  if (strtolower($hnam) == 'boundary') {
514  $boundary = $hval;
515  break;
516  }
517  }
518  if ($boundary) break;
519  }
520  }
521  $headers = $harr;
522  $body = array();
523  if (substr($type, 0, strlen('multipart/')) == 'multipart/' && $boundary && strstr($part['content'], '--'.$boundary.'--')) $body = MIME4::_parts($part['content'], $boundary, strtolower(substr($type, strlen('multipart/'))), $debug);
524  if (count($body) == 0) $body[] = MIME4::_content($str, $debug);
525  }
526 
527  function _parts($str = null, $boundary = null, $multipart = null, $debug = null) {
528  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
529  $err = array();
530  if (!(is_string($str) && $str != '')) $err[] = 'invalid content value';
531  if (!(is_string($boundary) && $boundary != '')) $err[] = 'invalid boundary value';
532  if (!(is_string($multipart) && $multipart != '')) $err[] = 'invalid multipart value';
533  if (count($err) > 0) FUNC4::trace($debug, implode(', ', $err));
534  else {
535  $ret = array();
536  if (count($exp = explode('--'.$boundary.'--', $str)) == 2) {
537  if (count($exp = explode('--'.$boundary, $exp[0])) > 2) {
538  $cnt = 0;
539  foreach ($exp as $split) {
540  $cnt++;
541  if ($cnt > 1 && $part = MIME4::split_message($split, $debug)) {
542  if ($harr = MIME4::split_header($part['header'], $debug)) {
543  $type = $newb = false;
544  foreach ($harr as $hnum) {
545  if (strtolower($hnum['name']) == 'content-type') {
546  $type = strtolower($hnum['value']);
547  foreach ($hnum['content'] as $hnam => $hval) {
548  if (strtolower($hnam) == 'boundary') {
549  $newb = $hval;
550  break;
551  }
552  }
553  if ($newb) break;
554  }
555  }
556  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);
557  else {
558  $res = MIME4::_content($split, $debug);
559  $res['multipart'] = $multipart;
560  $ret[] = $res;
561  }
562  }
563  }
564  }
565  }
566  }
567  return $ret;
568  }
569  }
570 
571  function _content($str = null, $debug = null) {
572  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
573  if (!(is_string($str) && $str != '')) FUNC4::trace($debug, 'invalid content value');
574  else {
575  if (!$part = MIME4::split_message($str, $debug)) return null;
576  if (!$harr = MIME4::split_header($part['header'], $debug)) return null;
577  $body = array();
578  $clen = strlen('content-');
579  $encoding = false;
580  foreach ($harr as $hnum) {
581  if (substr(strtolower($hnum['name']), 0, $clen) == 'content-') {
582  $name = strtolower(substr($hnum['name'], $clen));
583  if ($name == 'transfer-encoding') $encoding = strtolower($hnum['value']);
584  else if ($name == 'id') $body[$name] = array('value' => trim($hnum['value'], '<>'), 'extra' => $hnum['content']);
585  else $body[$name] = array('value' => $hnum['value'], 'extra' => $hnum['content']);
586  }
587  }
588  if ($encoding == 'base64' || $encoding == 'quoted-printable') $body['content'] = MIME4::decode_content($part['content'], $encoding, $debug);
589  else {
590  if ($encoding) $body['transfer-encoding'] = $encoding;
591  $body['content'] = $part['content'];
592  }
593  if (substr($body['content'], -2) == "\r\n") $body['content'] = substr($body['content'], 0, -2);
594  else if (substr($body['content'], -1) == "\n") $body['content'] = substr($body['content'], 0, -1);
595  return $body;
596  }
597  }
598 
599  function fix_eol($str = null, $debug = null) {
600  if (!FUNC4::is_debug($debug)) $debug = debug_backtrace();
601  if (!(is_string($str) && $str != '')) FUNC4::trace($debug, 'invalid content value');
602  else {
603  $_mime = new MIME4;
604  $str = str_replace("\r\n", "\n", $str);
605  $str = str_replace("\r", "\n", $str);
606  if ($_mime->LE != "\n") $str = str_replace("\n", $_mime->LE, $str);
607  return $str;
608  }
609  }
610 
611 }
612 
613 ?>