363f54005ab59ceba6e978b935d3325b073bf559
6 * Copyright (c) 2002 The SquirrelMail Project Team
7 * Licensed under the GNU GPL. For full terms see the file COPYING.
10 * This contains functions needed to handle mime messages.
19 * input: header_string or array
40 $more_headers = array(); /* only needed for constructing headers
43 function parseHeader($hdr)
47 $hdr = implode('',$hdr);
49 /* first we unfold the header */
50 $hdr = trim(str_replace(array("\r\n\t","\r\n "),array('',''),$hdr));
52 * now we can make a new header array with each element representing
55 $hdr = explode("\r\n" , $hdr);
56 foreach ($hdr as $line)
58 $pos = strpos($line,':');
61 $field = substr($line,0,$pos);
62 $value = trim(substr($line,$pos+
1));
63 $value = $this->stripComments($value);
64 $this->parseField($field,$value);
67 if ($this->content_type
== '')
69 $this->parseContentType('text/plain; charset=us-ascii');
73 function stripComments($value)
75 $cnt = strlen($value);
85 while ($value{$i} != '"')
87 if ($value{$i} == '\\')
99 while ($value{$i} != ')')
101 if ($value{$i} == '\\')
117 function parseField($field,$value)
119 $field = strtolower($field);
123 $d = strtr($value, array(' ' => ' '));
124 $d = explode(' ', $d);
125 $this->date
= getTimeStamp($d);
128 $this->subject
= $value;
131 $this->from
= $this->parseAddress($value,true);
134 $this->sender
= $this->parseAddress($value);
137 $this->reply_to
= $this->parseAddress($value, true);
140 $this->to
= $this->parseAddress($value, true);
143 $this->cc
= $this->parseAddress($value, true);
146 $this->bcc
= $this->parseAddress($value, true);
148 case ('in-reply-to'):
149 $this->in_reply_to
= $value;
152 $this->message_id
= $value;
154 case ('disposition-notification-to'):
155 $this->dnt
= $this->parseAddress($value);
157 case ('mime-Version'):
158 $value = str_replace(' ','',$value);
164 case ('content-type'):
165 $this->parseContentType($value);
167 case ('content-disposition'):
168 $this->parseDisposition($value);
171 $this->xmailer
= $value;
174 $this->priority
= $value;
177 $this->mlist('post',$value);
180 $this->mlist('reply',$value);
182 case ('list-subscribe'):
183 $this->mlist('subscribe',$value);
185 case ('list-unsubscribe'):
186 $this->mlist('unsubscribe',$value);
188 case ('list-archive'):
189 $this->mlist('archive',$value);
192 $this->mlist('owner',$value);
195 $this->mlist('help',$value);
198 $this->mlist('id',$value);
205 function parseAddress($address, $ar=false, $addr_ar = array(), $group = '')
208 $j = strlen( $address );
211 while ( $pos < $j ) {
212 switch ($address{$pos})
214 case ('"'): /* get the personal name */
216 if ($address{$pos} == '"')
221 while ( $pos < $j && $address{$pos} != '"')
223 if (substr($address, $pos, 2) == '\\"')
225 $name .= $address{$pos};
227 } elseif (substr($address, $pos, 2) == '\\\\')
229 $name .= $address{$pos};
232 $name .= $address{$pos};
238 case ('<'): /* get email address */
241 while ( $pos < $j && $address{$pos} != '>' )
243 $addr .= $address{$pos};
248 case ('('): /* rip off comments */
251 while ( $pos < $j && $address{$pos} != ')' )
253 $addr .= $address{$pos};
256 $address_start = substr($address,0,$addr_start);
257 $address_end = substr($address,$pos+
1);
258 $address = $address_start . $address_end;
259 $j = strlen( $address );
263 case (','): /* we reached a delimiter */
266 $addr = substr($address,0,$pos);
267 } elseif ($name == '') {
268 $name = trim(substr($address,0,$addr_start));
271 $at = strpos($addr, '@');
272 $addr_structure = new address_structure();
273 $addr_structure->personal
= $name;
274 $addr_structure->group
= $group;
277 $addr_structure->mailbox
= substr($addr,0,$at);
278 $addr_structure->host
= substr($addr,$at+
1);
281 $addr_structure->mailbox
= $addr;
283 $address = trim(substr($address,$pos+
1));
284 $j = strlen( $address );
288 $addr_ar[] = $addr_structure;
290 case (':'): /* process the group addresses */
292 $group = substr($address,0,$pos);
293 $address = substr($address,$pos+
1);
294 $result = $this->parseAddress($address, $ar, $addr_ar, $group);
295 $addr_ar = $result[0];
297 $address = substr($address,$pos);
298 $j = strlen( $address );
305 $address = substr($address, 0, $pos-1);
317 $addr = substr($address,0,$pos);
318 } elseif ($name == '')
320 $name = trim(substr($address,0,$addr_start));
322 $at = strpos($addr, '@');
323 $addr_structure = new address_structure();
324 $addr_structure->group
= $group;
327 $addr_structure->mailbox
= trim(substr($addr,0,$at));
328 $addr_structure->host
= trim(substr($addr,$at+
1));
331 $addr_structure->mailbox
= trim($addr);
333 if ($group && $addr == '') /* no addresses found in group */
335 $name = "$group: Undisclosed recipients;";
336 $addr_structure->personal
= $name;
337 $addr_ar[] = $addr_structure;
338 return (array($addr_ar,$pos+
1));
341 $addr_structure->personal
= $name;
344 $addr_ar[] = $addr_structure;
352 return ($addr_ar[0]);
356 function parseContentType($value)
358 $pos = strpos($value,';');
362 $type = trim(substr($value,0,$pos));
363 $props = trim(substr($type,$pos+
1));
368 $content_type = new content_type($type);
371 $properties = $this->parseProperties($props);
372 if (!isset($properties['charset']))
374 $properties['charset'] = 'us-ascii';
376 $content_type->properties
= $this->parseProperties($props);
378 $this->content_type
= $content_type;
381 function parseProperties($value)
383 $propArray = explode(';',$value);
384 $propResultArray = array();
385 foreach ($propArray as $prop)
388 $pos = strpos($prop,'=');
391 $key = trim(substr($prop,0,$pos));
392 $val = trim(substr($prop,$pos+
1));
395 $val = substr($val,1,-1);
397 $propResultArray[$key] = $val;
400 return $propResultArray;
403 function parseDisposition($value)
405 $pos = strpos($value,';');
409 $name = trim(substr($value,0,$pos));
410 $props = trim(substr($type,$pos+
1));
415 $props_a = $this->parseProperties($props);
416 $disp = new disposition($name);
417 $disp->properties
= $props_a;
418 $this->disposition
= $disp;
421 function mlist($field, $value)
424 $value_a = explode(',',$value);
425 foreach ($value_a as $val) {
429 $val = substr($val,1,-1);
431 if (substr($val,0,7) == 'mailto:')
433 $res_a['mailto'] = substr($val,7);
436 $res_a['href'] = $val;
439 $this->mlist
[$field] = $res_a;
443 * function to get the addres strings out of the header.
444 * Arguments: string or array of strings !
445 * example1: header->getAddr_s('to').
446 * example2: header->getAddr_s(array('to','cc','bcc'))
448 function getAddr_s($arr, $separator=', ')
453 foreach($arr as $arg )
455 $result = $this->getAddr_s($arg);
458 $s .= $separator . $result;
461 if ($s) $s = substr($s,2);
466 eval('$addr = $this->'.$arr.';') ;
469 foreach ($addr as $addr_o)
471 if (is_object($addr_o))
473 $s .= $addr_o->getAddress() . $separator;
476 $s = substr($s,0,-strlen($separator));
479 if (is_object($addr))
481 $s .= $addr->getAddress();
488 function getAddr_a($arg, $excl_arr=array(), $arr = array())
492 foreach($arg as $argument )
494 $arr = $this->getAddr_a($argument, $excl_arr, $arr);
499 eval('$addr = $this->'.$arg.';') ;
502 foreach ($addr as $addr_o)
504 if (is_object($addr_o))
506 if (isset($addr_o->host
) && $addr_o->host
!='')
508 $email = $addr_o->mailbox
.'@'.$addr_o->host
;
511 $email = $addr_o->mailbox
;
513 $email = strtolower($email);
514 if ($email && !isset($arr[$email]) && !isset($excl_arr[$email]))
516 $arr[$email] = $addr_o->personal
;
522 if (is_object($addr))
524 if (isset($addr->host
))
526 $email = $addr->mailbox
.'@'.$addr->host
;
529 $email = $addr->mailbox
;
531 $email = strtolower($email);
532 if ($email && !isset($arr[$email]) && !isset($excl_arr[$email]))
534 $arr[$email] = $addr->personal
;
542 function getContentType($type0, $type1)
544 $type0 = $this->content_type
->type0
;
545 $type1 = $this->content_type
->type1
;
546 return $this->content_type
->properties
;
552 /** msg_header contains all variables available in a bodystructure **/
553 /** entity like described in rfc2060 **/
557 $parameters = array(),
567 * returns addres_list of supplied argument
568 * arguments: array('to', 'from', ...) or just a string like 'to'.
569 * result: string: address1, addres2, ....
572 function setVar($var, $value)
574 $this->{$var} = $value;
577 function getParameter($par)
579 $value = strtolower($par);
580 if (isset($this->parameters
[$par]))
582 return $this->parameters
[$par];
587 function setParameter($parameter, $value)
589 $this->parameters
[strtolower($parameter)] = $value;
595 class address_structure
597 var $personal = '', $adl = '', $mailbox = '', $host = '', $group = '';
599 function getAddress($full=true)
601 if (is_object($this))
603 if (isset($this->host
) && $this->host
!='')
605 $email = $this->mailbox
.'@'.$this->host
;
608 $email = $this->mailbox
;
610 if (trim($this->personal
) !='')
614 $addr = '"' . $this->personal
. '" <' .$email.'>';
617 $addr = $this->personal
;
619 $best_dpl = $this->personal
;
638 /** message is the object that contains messages. It is a recursive
639 object in that through the $entities variable, it can contain
640 more objects of type message. See documentation in mime.txt for
641 a better description of how this works.
643 var $rfc822_header = '',
649 $parent_ent, $entity,
650 $parent = '', $decoded_body='',
651 $is_seen = 0, $is_answered = 0, $is_deleted = 0, $is_flagged = 0,
654 $offset = 0, /* for fetching body parts out of raw messages */
655 $length = 0; /* for fetching body parts out of raw messages */
657 function setEnt($ent)
659 $this->entity_id
= $ent;
662 function addEntity ($msg)
664 $msg->parent
= &$this;
665 $this->entities
[] = $msg;
668 function addRFC822Header($read)
670 $header = new rfc822_header();
671 $this->rfc822_header
= $header->parseHeader($read);
674 function getEntity($ent)
676 $cur_ent = $this->entity_id
;
678 if ($cur_ent == '' ||
$cur_ent == '0')
680 $cur_ent_a = array();
683 $cur_ent_a = explode('.',$this->entity_id
);
685 $ent_a = explode('.',$ent);
687 $cnt = count($ent_a);
689 for ($i=0;$i<$cnt -1;$i++
)
691 if (isset($cur_ent_a[$i]) && $cur_ent_a[$i] != $ent_a[$i])
694 $cur_ent_a = explode('.',$msg->entity_id
);
696 } else if (!isset($cur_ent_a[$i]))
698 if (isset($msg->entities
[($ent_a[$i]-1)]))
700 $msg = $msg->entities
[($ent_a[$i]-1)];
702 $msg = $msg->entities
[0];
705 if ($msg->type0
== 'message' && $msg->type1
== 'rfc822')
707 /*this is a header for a message/rfc822 entity */
708 $msg = $msg->entities
[0];
712 if ($msg->type0
== 'message' && $msg->type1
== 'rfc822')
714 /*this is a header for a message/rfc822 entity */
715 $msg = $msg->entities
[0];
718 if (isset($msg->entities
[($ent_a[$cnt-1])-1]))
720 $msg = $msg->entities
[($ent_a[$cnt-1]-1)];
728 $this->body_part
= $s;
734 $msg->body_part
= '';
736 while ( isset($msg->entities
[$i]))
738 $msg->entities
[$i]->clean_up();
743 function getMailbox()
746 while (is_object($msg->parent
))
750 return $msg->mailbox
;
753 function calcEntity($msg)
755 if ($this->type0
== 'message' && $this->type1
== 'rfc822')
757 $msg->entity_id
= $this->entity_id
.'.0'; /* header of message/rfc822 */
758 } else if (isset($this->entity_id
) && $this->entity_id
!='')
760 $ent_no = count($this->entities
)+
1;
761 $par_ent = substr($this->entity_id
,-2);
762 if ($par_ent{0} == '.')
764 $par_ent = $par_ent{1};
768 $ent_no = count($this->entities
)+
1;
771 $ent = substr($this->entity_id
,0,strrpos($this->entity_id
,'.'));
774 $ent = $ent . ".$ent_no";
779 $msg->entity_id
= $ent;
782 $msg->entity_id
= $ent_no;
786 $ent = $this->entity_id
. ".$ent_no";
787 $msg->entity_id
= $ent;
791 $msg->entity_id
= '0';
793 return $msg->entity_id
;
798 * Bodystructure parser, a recursive function for generating the
799 * entity-tree with all the mime-parts.
801 * It follows RFC2060 and stores all the described fields in the
806 * Ask for me (Marc Groot Koerkamp, stekkel@users.sourceforge.net.
809 function parseStructure($read, $i=0)
813 $cnt = strlen($read);
816 $char = strtoupper($read{$i});
824 $msg = new message();
825 $hdr = new msg_header();
826 $hdr->type0
= 'text';
827 $hdr->type1
= 'plain';
828 $hdr->encoding
= 'us-ascii';
829 $msg->entity_id
= $this->calcEntity($msg);
832 $msg->header
->type0
= 'multipart';
833 $msg->type0
= 'multipart';
834 while ($read{$i} == '(')
836 $res = $msg->parseStructure($read,$i);
838 $msg->addEntity($res[0]);
846 /* multipart properties */
848 $res = $this->parseProperties($read,$i);
854 if (isset($msg->type0
) && $msg->type0
== 'multipart')
857 $res = $msg->parseDisposition($read,$i);
860 } else /* properties */
862 $res = $msg->parseProperties($read,$i);
869 if (isset($msg->type0
) && $msg->type0
== 'multipart')
872 $res= $msg->parseLanguage($read,$i);
877 if ($arg_a[0] == 'message' && $arg_a[1] == 'rfc822')
879 $msg->header
->type0
= $arg_a[0];
880 $msg->type0
= $arg_a[0];
881 $msg->header
->type1
= $arg_a[1];
882 $msg->type1
= $arg_a[1];
883 $rfc822_hdr = new rfc822_header();
884 $res = $msg->parseEnvelope($read,$i,$rfc822_hdr);
886 $msg->rfc822_header
= $res[0];
888 while ($i < $cnt && $read{$i} != '(')
892 $res = $msg->parseStructure($read,$i);
894 $msg->addEntity($res[0]);
899 $res = $msg->parseDisposition($read,$i);
905 if ($arg_a[0] == 'text' ||
906 ($arg_a[0] == 'message' && $arg_a[1] == 'rfc822'))
909 $res = $msg->parseDisposition($read,$i);
915 $res = $msg->parseLanguage($read,$i);
922 if ($arg_a[0] == 'text' ||
923 ($arg_a[0] == 'message' && $arg_a[1] == 'rfc822'))
926 $res = $msg->parseLanguage($read,$i);
931 $i = $msg->parseParenthesis($read,$i);
932 $arg_a[] = ''; /* not yet desribed in rfc2060 */
937 /* unknown argument, skip this part */
938 $i = $msg->parseParenthesis($read,$i);
946 /* inside an entity -> start processing */
947 $debug = substr($read,$i,20);
948 $res = $msg->parseQuote($read,$i);
952 if ($arg_no < 3) $arg_s = strtolower($arg_s); /* type0 and type1 */
957 /* probably NIL argument */
958 if (strtoupper(substr($read,$i,4)) == 'NIL ' ||
959 strtoupper(substr($read,$i,4)) == 'NIL)')
967 /* process the literal value */
968 $res = $msg->parseLiteral($read,$i);
973 case (is_numeric($read{$i}) ):
974 /* process integers */
975 if ($read{$i} == ' ') break;
978 while (preg_match('/^[0-9]{1}$/',$read{$i}))
987 if (isset($msg->type0
) && $msg->type0
== 'multipart')
996 if ($arg_a[0] == 'text' ||
997 ($arg_a[0] == 'message' && $arg_a[1] == 'rfc822'))
999 $shifted_args = true;
1002 $shifted_args = false;
1004 $hdr->type0
= $arg_a[0];
1005 $hdr->type1
= $arg_a[1];
1007 $msg->type0
= $arg_a[0];
1008 $msg->type1
= $arg_a[1];
1013 $hdr->parameters
= $arg_a[2];
1015 $hdr->id
= str_replace( '<', '', str_replace( '>', '', $arg_a[3] ) );
1016 $hdr->description
= $arg_a[4];
1017 $hdr->encoding
= strtolower($arg_a[5]);
1018 $hdr->entity_id
= $msg->entity_id
;
1019 $hdr->size
= $arg_a[6];
1022 $hdr->lines
= $arg_a[7];
1023 if (isset($arg_a[8]))
1025 $hdr->md5
= $arg_a[8];
1027 if (isset($arg_a[9]))
1029 $hdr->disposition
= $arg_a[9];
1031 if (isset($arg_a[10]))
1033 $hdr->language
= $arg_a[10];
1037 if (isset($arg_a[7]))
1039 $hdr->md5
= $arg_a[7];
1041 if (isset($arg_a[8]))
1043 $hdr->disposition
= $arg_a[8];
1045 if (isset($arg_a[9]))
1047 $hdr->language
= $arg_a[9];
1050 $msg->header
= $hdr;
1053 if (substr($msg->entity_id
,-2) == '.0' && $msg->type0
!='multipart')
1057 return (array($msg, $i));
1060 $hdr->type0
= 'multipart';
1061 $hdr->type1
= $arg_a[0];
1062 $msg->type0
= 'multipart';
1063 $msg->type1
= $arg_a[0];
1064 if (is_array($arg_a[1]))
1066 $hdr->parameters
= $arg_a[1];
1068 if (isset($arg_a[2]))
1070 $hdr->disposition
= $arg_a[2];
1072 if (isset($arg_a[3]))
1074 $hdr->language
= $arg_a[3];
1076 $msg->header
= $hdr;
1077 return (array($msg, $i));
1084 } /* parsestructure */
1086 function parseProperties($read, $i)
1088 $properties = array();
1091 while ($read{$i} != ')')
1093 if ($read{$i} == '"')
1095 $res = $this->parseQuote($read,$i);
1098 } else if ($read{$i} == '{')
1100 $res = $this->parseLiteral($read,$i);
1104 if ($prop_name == '' && $arg_s)
1106 $prop_name = strtolower($arg_s);
1107 $properties[$prop_name] = '';
1109 } elseif ($prop_name != '' && $arg_s != '')
1111 $properties[$prop_name] = $arg_s;
1117 return (array($properties, $i));
1120 function parseEnvelope($read, $i, $hdr)
1124 $cnt = strlen($read);
1125 while ($i< $cnt && $read{$i} != ')')
1128 $char = strtoupper($read{$i});
1132 $res = $this->parseQuote($read,$i);
1138 $res = $this->parseLiteral($read,$i);
1144 /* probably NIL argument */
1145 if (strtoupper(substr($read,$i,3)) == 'NIL') {
1152 /* Address structure
1153 * With group support.
1154 * Note: Group support is useless on SMTP connections
1155 * because the protocol doesn't support it
1160 while ($i < $cnt && $read{$i} != ')')
1162 if ($read{$i} == '(')
1164 $res = $this->parseAddress($read,$i);
1167 if ($addr->host
== '' && $addr->mailbox
!= '')
1169 /* start of group */
1170 $group = $addr->mailbox
;
1171 $group_addr = $addr;
1173 } elseif ($group && $addr->host
== '' && $addr->mailbox
== '')
1176 if ($a == $j+
1) /* no group members */
1178 $group_addr->group
= $group;
1179 $group_addr->mailbox
= '';
1180 $group_addr->personal
= "$group: Undisclosed recipients;";
1181 $addr_a[] = $group_addr;
1186 $addr->group
= $group;
1200 if (count($arg_a) > 9)
1202 /* argument 1: date */
1203 $d = strtr($arg_a[0], array(' ' => ' '));
1204 $d = explode(' ', $d);
1205 $hdr->date
= getTimeStamp($d);
1206 /* argument 2: subject */
1207 if (!trim($arg_a[1]))
1209 $arg_a[1]= _("(no subject)");
1211 $hdr->subject
= $arg_a[1];
1212 /* argument 3: from */
1213 $hdr->from
= $arg_a[2][0];
1214 /* argument 4: sender */
1215 $hdr->sender
= $arg_a[3][0];
1216 /* argument 5: reply-to */
1217 $hdr->replyto
= $arg_a[4][0];
1218 /* argument 6: to */
1219 $hdr->to
= $arg_a[5];
1220 /* argument 7: cc */
1221 $hdr->cc
= $arg_a[6];
1222 /* argument 8: bcc */
1223 $hdr->bcc
= $arg_a[7];
1224 /* argument 9: in-reply-to */
1225 $hdr->inreplyto
= $arg_a[8];
1226 /* argument 10: message-id */
1227 $hdr->message_id
= $arg_a[9];
1229 return (array($hdr,$i));
1232 function parseLiteral($read, $i)
1236 while ($read{$i} != '}')
1238 $lit_cnt .= $read{$i};
1241 $lit_cnt +
=2; /* add the { and } characters */
1243 for ($j = 0; $j < $lit_cnt; $j++
)
1248 return (array($s, $i));
1251 function parseQuote($read, $i)
1255 while ($read{$i} != '"')
1257 if ($read{$i} == '\\')
1264 return (array($s, $i));
1267 function parseAddress($read, $i)
1270 while ($read{$i} != ')' )
1272 $char = strtoupper($read{$i});
1276 $res = $this->parseQuote($read,$i);
1281 $res = $this->parseLiteral($read,$i);
1287 if (strtoupper(substr($read,$i,3)) == 'NIL') {
1297 if (count($arg_a) == 4)
1299 $adr = new address_structure();
1300 $adr->personal
= $arg_a[0];
1301 $adr->adl
= $arg_a[1];
1302 $adr->mailbox
= $arg_a[2];
1303 $adr->host
= $arg_a[3];
1308 return (array($adr,$i));
1311 function parseDisposition($read,$i)
1314 while ($read{$i} != ')')
1319 $res = $this->parseQuote($read,$i);
1324 $res = $this->parseLiteral($read,$i);
1329 $res = $this->parseProperties($read,$i);
1338 if (isset($arg_a[0]))
1340 $disp = new disposition($arg_a[0]);
1341 if (isset($arg_a[1]))
1343 $disp->properties
= $arg_a[1];
1346 if (is_object($disp))
1348 return (array($disp, $i));
1351 return (array('',$i));
1355 function parseLanguage($read,$i)
1357 /* no idea how to process this one without examples */
1359 while ($read{$i} != ')')
1364 $res = $this->parseQuote($read,$i);
1369 $res = $this->parseLiteral($read,$i);
1374 $res = $this->parseProperties($read,$i);
1383 if (isset($arg_a[0]))
1385 $lang = new language($arg_a[0]);
1386 if (isset($arg_a[1]))
1388 $lang->properties
= $arg_a[1];
1391 if (is_object($lang))
1393 return (array($lang, $i));
1396 return (array('', $i));
1400 function parseParenthesis($read,$i)
1402 while ($read{$i} != ')')
1407 $res = $this->parseQuote($read,$i);
1411 $res = $this->parseLiteral($read,$i);
1415 $res = $this->parseParenthesis($read,$i);
1426 /* function to fill the message structure in case the bodystructure
1427 isn't available NOT FINISHED YET
1429 function parseMessage($read, $type0, $type1)
1434 $rfc822_header = true;
1435 $mime_header = false;
1438 $mime_header = true;
1439 $rfc822_header = false;
1445 for ($i=1; $i < $count; $i++
)
1447 $line = trim($body[$i]);
1448 if ( ( $mime_header ||
$rfc822_header) &&
1449 (preg_match("/^.*boundary=\"?(.+(?=\")|.+).*/i",$line,$reg)) )
1453 $bndreg = str_replace("\\","\\\\",$bndreg);
1454 $bndreg = str_replace("?","\\?",$bndreg);
1455 $bndreg = str_replace("+","\\+",$bndreg);
1456 $bndreg = str_replace(".","\\.",$bndreg);
1457 $bndreg = str_replace("/","\\/",$bndreg);
1458 $bndreg = str_replace("-","\\-",$bndreg);
1459 $bndreg = str_replace("(","\\(",$bndreg);
1460 $bndreg = str_replace(")","\\)",$bndreg);
1461 } elseif ( $rfc822_header && $line == '' )
1463 $rfc822_header = false;
1464 if ($msg->type0
== 'multipart')
1466 $mime_header = true;
1470 if (($line{0} == '-' ||
$rfc822_header) && isset($boundaries[0]))
1472 $cnt=count($boundaries)-1;
1473 $bnd = $boundaries[$cnt]['bnd'];
1474 $bndreg = $boundaries[$cnt]['bndreg'];
1476 $regstr = '/^--'."($bndreg)".".*".'/';
1477 if (preg_match($regstr,$line,$reg) )
1479 $bndlen = strlen($reg[1]);
1481 if (strlen($line) > ($bndlen +
3))
1483 if ($line{$bndlen+
2} == '-' && $line{$bndlen+
3} == '-')
1488 /* calc offset and return $msg */
1489 // $entStr = CalcEntity("$entStr",-1);
1490 array_pop($boundaries);
1491 $mime_header = true;
1495 $mime_header = true;
1497 // $entStr = CalcEntity("$entStr",0);
1510 function findDisplayEntity ($entity = array(), $alt_order = array('text/plain','text/html'))
1513 $type = $this->type0
.'/'.$this->type1
;
1514 if ( $type == 'multipart/alternative')
1516 $msg = $this->findAlternativeEntity($alt_order);
1517 if (count($msg->entities
) == 0)
1519 $entity[] = $msg->entity_id
;
1522 $entity = $msg->findDisplayEntity($entity, $alt_order);
1525 } else if ( $type == 'multipart/related')
1527 $msgs = $this->findRelatedEntity();
1528 for ($i = 0; $i < count($msgs); $i++
)
1531 if (count($msg->entities
) == 0)
1533 $entity[] = $msg->entity_id
;
1536 $entity = $msg->findDisplayEntity($entity,$alt_order);
1540 } else if ( $this->type0
== 'text' &&
1541 ( $this->type1
== 'plain' ||
1542 $this->type1
== 'html' ||
1543 $this->type1
== 'message') &&
1544 isset($this->entity_id
) )
1546 if (count($this->entities
) == 0)
1548 if (strtolower($this->header
->disposition
->name
) != 'attachment')
1550 $entity[] = $this->entity_id
;
1555 while ( isset($this->entities
[$i]) && !$found &&
1556 (strtolower($this->entities
[$i]->header
->disposition
->name
)
1558 ($this->entities
[$i]->type0
!= 'message' &&
1559 $this->entities
[$i]->type1
!= 'rfc822' )
1562 $entity = $this->entities
[$i]->findDisplayEntity($entity, $alt_order);
1568 function findAlternativeEntity ($alt_order)
1570 /* if we are dealing with alternative parts then we choose the best
1571 * viewable message supported by SM.
1576 for ($i = 0; $i < count($this->entities
); $i ++
)
1578 $type = $this->entities
[$i]->header
->type0
.'/'.$this->entities
[$i]->header
->type1
;
1579 if ($type == 'multipart/related')
1581 $type = $this->entities
[$i]->header
->getParameter('type');
1583 for ($j = $k; $j < count($alt_order); $j++
)
1585 if ($alt_order[$j] == $type && $j > $best_view)
1593 return $this->entities
[$ent_id];
1596 function findRelatedEntity ()
1599 for ($i = 0; $i < count($this->entities
); $i ++
)
1601 $type = $this->entities
[$i]->header
->type0
.'/'.$this->entities
[$i]->header
->type1
;
1602 if ($this->header
->getParameter('type') == $type)
1604 $msgs[] = $this->entities
[$i];
1610 function getAttachments($exclude_id=array(), $result = array())
1612 if ($this->type0
== 'message' && $this->type1
== 'rfc822')
1614 $this = $this->entities
[0];
1616 if (count($this->entities
))
1618 foreach ($this->entities
as $entity)
1621 foreach ($exclude_id as $excl)
1623 if ($entity->entity_id
== $excl)
1630 if ($entity->type0
== 'multipart' &&
1631 $entity->type1
!= 'related')
1633 $result = $entity->getAttachments($exclude_id, $result);
1634 } else if ($entity->type0
!= 'multipart')
1636 $result[] = $entity;
1643 foreach ($exclude_id as $excl)
1645 if ($this->entity_id
== $excl)
1665 function disposition($name)
1667 $this->name
= $name;
1668 $this->properties
= array();
1674 function language($name)
1676 $this->name
= $name;
1677 $this->properties
= array();
1686 function content_type($type)
1688 $pos = strpos($type,'/');
1691 $this->type0
= substr($type,0,$pos);
1692 $this->type1
= substr($type,$pos+
1);
1695 $this->type0
= $type;
1697 $this->properties
= array();