squirrelmail-webmail  1.4.22
About: SquirrelMail is a standards-based webmail package with strong MIME support, address books, and folder manipulation (written in PHP4).
  Fossies Dox: squirrelmail-webmail-1.4.22.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

Message.class.php
Go to the documentation of this file.
1 <?php
2 
27 class Message {
32  var $rfc822_header = '';
42  var $mime_header = '';
46  var $flags = '';
51  var $type0='';
56  var $type1='';
61  var $entities = array();
66  var $entity_id = '';
75  var $entity;
79  var $parent = '';
83  var $decoded_body='';
88  var $is_seen = 0;
93  var $is_answered = 0;
98  var $is_deleted = 0;
103  var $is_flagged = 0;
108  var $is_mdnsent = 0;
113  var $body_part = '';
119  var $offset = 0;
125  var $length = 0;
131  var $att_local_name = '';
132 
136  function setEnt($ent) {
137  $this->entity_id= $ent;
138  }
139 
144  function addEntity ($msg) {
145  $this->entities[] = $msg;
146  }
147 
153  function getFilename() {
154  $filename = '';
156  if (is_object($header->disposition)) {
157  $filename = $header->disposition->getProperty('filename');
158  if (trim($filename) == '') {
159  $name = decodeHeader($header->disposition->getProperty('name'));
160  if (!trim($name)) {
161  $name = $header->getParameter('name');
162  if(!trim($name)) {
163  if (!trim( $header->id )) {
164  $filename = 'untitled-[' . $this->entity_id . ']' . '.' . strtolower($header->type1);
165  } else {
166  $filename = 'cid: ' . $header->id . '.' . strtolower($header->type1);
167  }
168  } else {
169  $filename = $name;
170  }
171  } else {
172  $filename = $name;
173  }
174  }
175  } else {
176  $filename = $header->getParameter('filename');
177  if (!trim($filename)) {
178  $filename = $header->getParameter('name');
179  if (!trim($filename)) {
180  if (!trim( $header->id )) {
181  $filename = 'untitled-[' . $this->entity_id . ']' . '.' . strtolower($header->type1);
182  } else {
183  $filename = 'cid: ' . $header->id . '.' . strtolower($header->type1);
184  }
185  }
186  }
187  }
188  return $filename;
189  }
190 
197  function addRFC822Header($read) {
198  $header = new Rfc822Header();
199  $this->rfc822_header = $header->parseHeader($read);
200  }
201 
206  function getEntity($ent) {
207  $cur_ent = $this->entity_id;
208  $msg = $this;
209  if (($cur_ent == '') || ($cur_ent == '0')) {
210  $cur_ent_a = array();
211  } else {
212  $cur_ent_a = explode('.', $this->entity_id);
213  }
214  $ent_a = explode('.', $ent);
215 
216  for ($i = 0,$entCount = count($ent_a) - 1; $i < $entCount; ++$i) {
217  if (isset($cur_ent_a[$i]) && ($cur_ent_a[$i] != $ent_a[$i])) {
218  $msg = $msg->parent;
219  $cur_ent_a = explode('.', $msg->entity_id);
220  --$i;
221  } else if (!isset($cur_ent_a[$i])) {
222  if (isset($msg->entities[($ent_a[$i]-1)])) {
223  $msg = $msg->entities[($ent_a[$i]-1)];
224  } else {
225  $msg = $msg->entities[0];
226  }
227  }
228  if (($msg->type0 == 'message') && ($msg->type1 == 'rfc822')) {
229  /*this is a header for a message/rfc822 entity */
230  $msg = $msg->entities[0];
231  }
232  }
233 
234  if (($msg->type0 == 'message') && ($msg->type1 == 'rfc822')) {
235  /*this is a header for a message/rfc822 entity */
236  $msg = $msg->entities[0];
237  }
238 
239  if (isset($msg->entities[($ent_a[$entCount])-1])) {
240  if (is_object($msg->entities[($ent_a[$entCount])-1])) {
241  $msg = $msg->entities[($ent_a[$entCount]-1)];
242  }
243  }
244 
245  return $msg;
246  }
247 
252  function setBody($s) {
253  $this->body_part = $s;
254  }
255 
259  function clean_up() {
260  $msg = $this;
261  $msg->body_part = '';
262 
263  foreach ($msg->entities as $m) {
264  $m->clean_up();
265  }
266  }
267 
271  function getMailbox() {
272  $msg = $this;
273  while (is_object($msg->parent)) {
274  $msg = $msg->parent;
275  }
276  return $msg->mailbox;
277  }
278 
279  /*
280  * Bodystructure parser, a recursive function for generating the
281  * entity-tree with all the mime-parts.
282  *
283  * It follows RFC2060 and stores all the described fields in the
284  * message object.
285  *
286  * Question/Bugs:
287  *
288  * Ask for me (Marc Groot Koerkamp, stekkel@users.sourceforge.net)
289  * @param string $read
290  * @param integer $i
291  * @param mixed $sub_msg
292  * @return object Message object
293  * @todo define argument and return types
294  */
295  function parseStructure($read, &$i, $sub_msg = '') {
296  $msg = Message::parseBodyStructure($read, $i, $sub_msg);
297  if($msg) $msg->setEntIds($msg,false,0);
298  return $msg;
299  }
300 
308  function setEntIds(&$msg,$init=false,$i=0) {
309  $iCnt = count($msg->entities);
310  if ($init !==false) {
311  $iEntSub = $i+1;
312  if ($msg->parent->type0 == 'message' &&
313  $msg->parent->type1 == 'rfc822' &&
314  $msg->type0 == 'multipart') {
315  $iEntSub = '0';
316  }
317  if ($init) {
318  $msg->entity_id = "$init.$iEntSub";
319  } else {
320  $msg->entity_id = $iEntSub;
321  }
322  } else if ($iCnt) {
323  $msg->entity_id='0';
324  } else {
325  $msg->entity_id='1';
326  }
327  for ($i=0;$i<$iCnt;++$i) {
328  $msg->entities[$i]->parent =& $msg;
329  if (strrchr($msg->entity_id, '.') != '.0') {
330  $msg->entities[$i]->setEntIds($msg->entities[$i],$msg->entity_id,$i);
331  } else {
332  $msg->entities[$i]->setEntIds($msg->entities[$i],$msg->parent->entity_id,$i);
333  }
334  }
335  }
336 
345  function parseBodyStructure($read, &$i, $sub_msg = '') {
346  $arg_no = 0;
347  $arg_a = array();
348  if ($sub_msg) {
349  $message = $sub_msg;
350  } else {
351  $message = new Message();
352  }
353 
354  for ($cnt = strlen($read); $i < $cnt; ++$i) {
355  $char = strtoupper($read{$i});
356  switch ($char) {
357  case '(':
358  switch($arg_no) {
359  case 0:
360  if (!isset($msg)) {
361  $msg = new Message();
362  $hdr = new MessageHeader();
363  $hdr->type0 = 'text';
364  $hdr->type1 = 'plain';
365  $hdr->encoding = '7bit';
366  } else {
367  $msg->header->type0 = 'multipart';
368  $msg->type0 = 'multipart';
369  while ($read{$i} == '(') {
370  $msg->addEntity($msg->parseBodyStructure($read, $i, $msg));
371  }
372  }
373  break;
374  case 1:
375  /* multipart properties */
376  ++$i;
377  $arg_a[] = $msg->parseProperties($read, $i);
378  ++$arg_no;
379  break;
380  case 2:
381  if (isset($msg->type0) && ($msg->type0 == 'multipart')) {
382  ++$i;
383  $arg_a[] = $msg->parseDisposition($read, $i);
384  } else { /* properties */
385  $arg_a[] = $msg->parseProperties($read, $i);
386  }
387  ++$arg_no;
388  break;
389  case 3:
390  if (isset($msg->type0) && ($msg->type0 == 'multipart')) {
391  ++$i;
392  $arg_a[]= $msg->parseLanguage($read, $i);
393  }
394  case 7:
395  if (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822')) {
396  $msg->header->type0 = $arg_a[0];
397  $msg->header->type1 = $arg_a[1];
398  $msg->type0 = $arg_a[0];
399  $msg->type1 = $arg_a[1];
400  $rfc822_hdr = new Rfc822Header();
401  $msg->rfc822_header = $msg->parseEnvelope($read, $i, $rfc822_hdr);
402  while (($i < $cnt) && ($read{$i} != '(')) {
403  ++$i;
404  }
405  $msg->addEntity($msg->parseBodyStructure($read, $i,$msg));
406  }
407  break;
408  case 8:
409  ++$i;
410  $arg_a[] = $msg->parseDisposition($read, $i);
411  ++$arg_no;
412  break;
413  case 9:
414  ++$i;
415  if (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822'))) {
416  $arg_a[] = $msg->parseDisposition($read, $i);
417  } else {
418  $arg_a[] = $msg->parseLanguage($read, $i);
419  }
420  ++$arg_no;
421  break;
422  case 10:
423  if (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822'))) {
424  ++$i;
425  $arg_a[] = $msg->parseLanguage($read, $i);
426  } else {
427  $i = $msg->parseParenthesis($read, $i);
428  $arg_a[] = ''; /* not yet described in rfc2060 */
429  }
430  ++$arg_no;
431  break;
432  default:
433  /* unknown argument, skip this part */
434  $i = $msg->parseParenthesis($read, $i);
435  $arg_a[] = '';
436  ++$arg_no;
437  break;
438  } /* switch */
439  break;
440  case '"':
441  /* inside an entity -> start processing */
442  $arg_s = $msg->parseQuote($read, $i);
443  ++$arg_no;
444  if ($arg_no < 3) {
445  $arg_s = strtolower($arg_s); /* type0 and type1 */
446  }
447  $arg_a[] = $arg_s;
448  break;
449  case 'n':
450  case 'N':
451  /* probably NIL argument */
452  $tmpnil = strtoupper(substr($read, $i, 4));
453  if ($tmpnil == 'NIL ' || $tmpnil == 'NIL)') {
454  $arg_a[] = '';
455  ++$arg_no;
456  $i += 2;
457  }
458  break;
459  case '{':
460  /* process the literal value */
461  $arg_a[] = $msg->parseLiteral($read, $i);
462  ++$arg_no;
463  break;
464  case '0':
465  case is_numeric($read{$i}):
466  /* process integers */
467  if ($read{$i} == ' ') { break; }
468  ++$arg_no;
469  if (preg_match('/^([0-9]+).*/',substr($read,$i), $regs)) {
470  $i += strlen($regs[1])-1;
471  $arg_a[] = $regs[1];
472  } else {
473  $arg_a[] = 0;
474  }
475  break;
476  case ')':
477  $multipart = (isset($msg->type0) && ($msg->type0 == 'multipart'));
478  if (!$multipart) {
479  $shifted_args = (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822')));
480  $hdr->type0 = $arg_a[0];
481  $hdr->type1 = $arg_a[1];
482 
483  $msg->type0 = $arg_a[0];
484  $msg->type1 = $arg_a[1];
485  $arr = $arg_a[2];
486  if (is_array($arr)) {
487  $hdr->parameters = $arg_a[2];
488  }
489  $hdr->id = str_replace('<', '', str_replace('>', '', $arg_a[3]));
490  $hdr->description = $arg_a[4];
491  $hdr->encoding = strtolower($arg_a[5]);
492  $hdr->entity_id = $msg->entity_id;
493  $hdr->size = $arg_a[6];
494  if ($shifted_args) {
495  $hdr->lines = $arg_a[7];
496  $s = 1;
497  } else {
498  $s = 0;
499  }
500  $hdr->md5 = (isset($arg_a[7+$s]) ? $arg_a[7+$s] : $hdr->md5);
501  $hdr->disposition = (isset($arg_a[8+$s]) ? $arg_a[8+$s] : $hdr->disposition);
502  $hdr->language = (isset($arg_a[9+$s]) ? $arg_a[9+$s] : $hdr->language);
503  $msg->header = $hdr;
504  } else {
505  $hdr->type0 = 'multipart';
506  $hdr->type1 = $arg_a[0];
507  $msg->type0 = 'multipart';
508  $msg->type1 = $arg_a[0];
509  $hdr->parameters = (isset($arg_a[1]) ? $arg_a[1] : $hdr->parameters);
510  $hdr->disposition = (isset($arg_a[2]) ? $arg_a[2] : $hdr->disposition);
511  $hdr->language = (isset($arg_a[3]) ? $arg_a[3] : $hdr->language);
512  $msg->header = $hdr;
513  }
514  return $msg;
515  default: break;
516  } /* switch */
517  } /* for */
518  } /* parsestructure */
519 
525  function parseProperties($read, &$i) {
526  $properties = array();
527  $prop_name = '';
528 
529  for (; $read{$i} != ')'; ++$i) {
530  $arg_s = '';
531  if ($read{$i} == '"') {
532  $arg_s = $this->parseQuote($read, $i);
533  } else if ($read{$i} == '{') {
534  $arg_s = $this->parseLiteral($read, $i);
535  }
536 
537  if ($arg_s != '') {
538  if ($prop_name == '') {
539  $prop_name = strtolower($arg_s);
540  $properties[$prop_name] = '';
541  } else if ($prop_name != '') {
542  $properties[$prop_name] = $arg_s;
543  $prop_name = '';
544  }
545  }
546  }
547  return $properties;
548  }
549 
556  function parseEnvelope($read, &$i, $hdr) {
557  $arg_no = 0;
558  $arg_a = array();
559  ++$i;
560  for ($cnt = strlen($read); ($i < $cnt) && ($read{$i} != ')'); ++$i) {
561  $char = strtoupper($read{$i});
562  switch ($char) {
563  case '"':
564  $arg_a[] = $this->parseQuote($read, $i);
565  ++$arg_no;
566  break;
567  case '{':
568  $arg_a[] = $this->parseLiteral($read, $i);
569  /* temp bugfix (SM 1.5 will have a working clean version)
570  too much work to implement that version right now */
571 // --$i;
572  ++$arg_no;
573  break;
574  case 'N':
575  /* probably NIL argument */
576  if (strtoupper(substr($read, $i, 3)) == 'NIL') {
577  $arg_a[] = '';
578  ++$arg_no;
579  $i += 2;
580  }
581  break;
582  case '(':
583  /* Address structure (with group support)
584  * Note: Group support is useless on SMTP connections
585  * because the protocol doesn't support it
586  */
587  $addr_a = array();
588  $group = '';
589  $a=0;
590  for (; $i < $cnt && $read{$i} != ')'; ++$i) {
591  if ($read{$i} == '(') {
592  $addr = $this->parseAddress($read, $i);
593  if (($addr->host == '') && ($addr->mailbox != '')) {
594  /* start of group */
595  $group = $addr->mailbox;
596  $group_addr = $addr;
597  $j = $a;
598  } else if ($group && ($addr->host == '') && ($addr->mailbox == '')) {
599  /* end group */
600  if ($a == ($j+1)) { /* no group members */
601  $group_addr->group = $group;
602  $group_addr->mailbox = '';
603  $group_addr->personal = "$group: Undisclosed recipients;";
604  $addr_a[] = $group_addr;
605  $group ='';
606  }
607  } else {
608  $addr->group = $group;
609  $addr_a[] = $addr;
610  }
611  ++$a;
612  }
613  }
614  $arg_a[] = $addr_a;
615  break;
616  default: break;
617  }
618  }
619 
620  if (count($arg_a) > 9) {
621  $d = strtr($arg_a[0], array(' ' => ' '));
622  $d_parts = explode(' ', $d);
623  if (!$arg_a[1]) $arg_a[1] = _("(no subject)");
624 
625  $hdr->date = getTimeStamp($d_parts); /* argument 1: date */
626  $hdr->date_unparsed = strtr($d,'<>',' '); /* original date */
627  $hdr->subject = $arg_a[1]; /* argument 2: subject */
628  $hdr->from = is_array($arg_a[2]) ? $arg_a[2][0] : ''; /* argument 3: from */
629  $hdr->sender = is_array($arg_a[3]) ? $arg_a[3][0] : ''; /* argument 4: sender */
630  $hdr->reply_to = is_array($arg_a[4]) ? $arg_a[4][0] : ''; /* argument 5: reply-to */
631  $hdr->to = $arg_a[5]; /* argument 6: to */
632  $hdr->cc = $arg_a[6]; /* argument 7: cc */
633  $hdr->bcc = $arg_a[7]; /* argument 8: bcc */
634  $hdr->in_reply_to = $arg_a[8]; /* argument 9: in-reply-to */
635  $hdr->message_id = $arg_a[9]; /* argument 10: message-id */
636  }
637  return $hdr;
638  }
639 
646  function parseLiteral($read, &$i) {
647  $lit_cnt = '';
648  ++$i;
649  $iPos = strpos($read,'}',$i);
650  if ($iPos) {
651  $lit_cnt = substr($read, $i, $iPos - $i);
652  $i += strlen($lit_cnt) + 3; /* skip } + \r + \n */
653  /* Now read the literal */
654  $s = ($lit_cnt ? substr($read,$i,$lit_cnt): '');
655  $i += $lit_cnt;
656  /* temp bugfix (SM 1.5 will have a working clean version)
657  too much work to implement that version right now */
658  --$i;
659  } else { /* should never happen */
660  $i += 3; /* } + \r + \n */
661  $s = '';
662  }
663  return $s;
664  }
665 
682  function parseQuote($read, &$i) {
683  $s = '';
684  $iPos = ++$i;
685  $iPosStart = $iPos;
686  while (true) {
687  $iPos = strpos($read,'"',$iPos);
688  if (!$iPos) break;
689  if ($iPos && $read{$iPos -1} != '\\') {
690  $s = substr($read,$i,($iPos-$i));
691  $i = $iPos;
692  break;
693  } else if ($iPos > 1 && $read{$iPos -1} == '\\' && $read{$iPos-2} == '\\') {
694  // This is an unique situation where the fast detection of the string
695  // fails. If the quote string ends with \\ then we need to iterate
696  // through the entire string to make sure we detect the unexcaped
697  // double quotes correctly.
698  $s = '';
699  $bEscaped = false;
700  $k = 0;
701  for ($j=$iPosStart,$iCnt=strlen($read);$j<$iCnt;++$j) {
702  $cChar = $read{$j};
703  switch ($cChar) {
704  case '\\':
705  $bEscaped = !$bEscaped;
706  $s .= $cChar;
707  break;
708  case '"':
709  if ($bEscaped) {
710  $s .= $cChar;
711  $bEscaped = false;
712  } else {
713  $i = $j;
714  break 3;
715  }
716  break;
717  default:
718  if ($bEscaped) {
719  $bEscaped = false;
720  }
721  $s .= $cChar;
722  break;
723  }
724  }
725  }
726  ++$iPos;
727  if ($iPos > strlen($read)) {
728  break;
729  }
730  }
731  return $s;
732  }
733 
739  function parseAddress($read, &$i) {
740  $arg_a = array();
741  for (; $read{$i} != ')'; ++$i) {
742  $char = strtoupper($read{$i});
743  switch ($char) {
744  case '"': $arg_a[] = $this->parseQuote($read, $i); break;
745  case '{': $arg_a[] = $this->parseLiteral($read, $i); break;
746  case 'n':
747  case 'N':
748  if (strtoupper(substr($read, $i, 3)) == 'NIL') {
749  $arg_a[] = '';
750  $i += 2;
751  }
752  break;
753  default: break;
754  }
755  }
756 
757  if (count($arg_a) == 4) {
758  $adr = new AddressStructure();
759  $adr->personal = $arg_a[0];
760  $adr->adl = $arg_a[1];
761  $adr->mailbox = $arg_a[2];
762  $adr->host = $arg_a[3];
763  } else {
764  $adr = '';
765  }
766  return $adr;
767  }
768 
774  function parseDisposition($read, &$i) {
775  $arg_a = array();
776  for (; $read{$i} != ')'; ++$i) {
777  switch ($read{$i}) {
778  case '"': $arg_a[] = $this->parseQuote($read, $i); break;
779  case '{': $arg_a[] = $this->parseLiteral($read, $i); break;
780  case '(': $arg_a[] = $this->parseProperties($read, $i); break;
781  default: break;
782  }
783  }
784 
785  if (isset($arg_a[0])) {
786  $disp = new Disposition($arg_a[0]);
787  if (isset($arg_a[1])) {
788  $disp->properties = $arg_a[1];
789  }
790  }
791  return (is_object($disp) ? $disp : '');
792  }
793 
799  function parseLanguage($read, &$i) {
800  /* no idea how to process this one without examples */
801  $arg_a = array();
802 
803  for (; $read{$i} != ')'; ++$i) {
804  switch ($read{$i}) {
805  case '"': $arg_a[] = $this->parseQuote($read, $i); break;
806  case '{': $arg_a[] = $this->parseLiteral($read, $i); break;
807  case '(': $arg_a[] = $this->parseProperties($read, $i); break;
808  default: break;
809  }
810  }
811 
812  if (isset($arg_a[0])) {
813  $lang = new Language($arg_a[0]);
814  if (isset($arg_a[1])) {
815  $lang->properties = $arg_a[1];
816  }
817  }
818  return (is_object($lang) ? $lang : '');
819  }
820 
827  function parseParenthesis($read, $i) {
828  for ($i++; $read{$i} != ')'; ++$i) {
829  switch ($read{$i}) {
830  case '"': $this->parseQuote($read, $i); break;
831  case '{': $this->parseLiteral($read, $i); break;
832  case '(': $this->parseProperties($read, $i); break;
833  default: break;
834  }
835  }
836  return $i;
837  }
838 
849  switch ($type0) {
850  case 'message':
851  $rfc822_header = true;
852  $mime_header = false;
853  break;
854  case 'multipart':
855  $rfc822_header = false;
856  $mime_header = true;
857  break;
858  default: return $read;
859  }
860 
861  for ($i = 1; $i < $count; ++$i) {
862  $line = trim($body[$i]);
863  if (($mime_header || $rfc822_header) &&
864  (preg_match("/^.*boundary=\"?(.+(?=\")|.+).*/i", $line, $reg))) {
865  $bnd = $reg[1];
866  $bndreg = $bnd;
867  $bndreg = str_replace("\\", "\\\\", $bndreg);
868  $bndreg = str_replace("?", "\\?", $bndreg);
869  $bndreg = str_replace("+", "\\+", $bndreg);
870  $bndreg = str_replace(".", "\\.", $bndreg);
871  $bndreg = str_replace("/", "\\/", $bndreg);
872  $bndreg = str_replace("-", "\\-", $bndreg);
873  $bndreg = str_replace("(", "\\(", $bndreg);
874  $bndreg = str_replace(")", "\\)", $bndreg);
875  } else if ($rfc822_header && $line == '') {
876  $rfc822_header = false;
877  if ($msg->type0 == 'multipart') {
878  $mime_header = true;
879  }
880  }
881 
882  if ((($line{0} == '-') || $rfc822_header) && isset($boundaries[0])) {
883  $cnt = count($boundaries)-1;
884  $bnd = $boundaries[$cnt]['bnd'];
885  $bndreg = $boundaries[$cnt]['bndreg'];
886 
887  $regstr = '/^--'."($bndreg)".".*".'/';
888  if (preg_match($regstr, $line, $reg)) {
889  $bndlen = strlen($reg[1]);
890  $bndend = false;
891  if (strlen($line) > ($bndlen + 3)) {
892  if (($line{$bndlen+2} == '-') && ($line{$bndlen+3} == '-')) {
893  $bndend = true;
894  }
895  }
896  if ($bndend) {
897  /* calc offset and return $msg */
898  //$entStr = CalcEntity("$entStr", -1);
899  array_pop($boundaries);
900  $mime_header = true;
901  $bnd_end = true;
902  } else {
903  $mime_header = true;
904  $bnd_end = false;
905  //$entStr = CalcEntity("$entStr", 0);
906  ++$content_indx;
907  }
908  } else {
909  if ($header) { }
910  }
911  }
912  }
913  }
914 
921  function findDisplayEntity($entity = array(), $alt_order = array('text/plain', 'text/html'), $strict=false) {
922  $found = false;
923  if ($this->type0 == 'multipart') {
924  if($this->type1 == 'alternative') {
925  $msg = $this->findAlternativeEntity($alt_order);
926  if ( ! is_null($msg) ) {
927  if (count($msg->entities) == 0) {
928  $entity[] = $msg->entity_id;
929  } else {
930  $entity = $msg->findDisplayEntity($entity, $alt_order, $strict);
931  }
932  $found = true;
933  }
934  } else if ($this->type1 == 'related') { /* RFC 2387 */
935  $msgs = $this->findRelatedEntity();
936  foreach ($msgs as $msg) {
937  if (count($msg->entities) == 0) {
938  $entity[] = $msg->entity_id;
939  } else {
940  $entity = $msg->findDisplayEntity($entity, $alt_order, $strict);
941  }
942  }
943  if (count($msgs) > 0) {
944  $found = true;
945  }
946  } else { /* Treat as multipart/mixed */
947  foreach ($this->entities as $ent) {
948  if(!(is_object($ent->header->disposition) && strtolower($ent->header->disposition->name) == 'attachment') &&
949  (!isset($ent->header->parameters['filename'])) &&
950  (!isset($ent->header->parameters['name'])) &&
951  (($ent->type0 != 'message') && ($ent->type1 != 'rfc822'))) {
952  $entity = $ent->findDisplayEntity($entity, $alt_order, $strict);
953  $found = true;
954  }
955  }
956  }
957  } else { /* If not multipart, then just compare with each entry from $alt_order */
958  $type = $this->type0.'/'.$this->type1;
959 // $alt_order[] = "message/rfc822";
960  foreach ($alt_order as $alt) {
961  if( ($alt == $type) && isset($this->entity_id) ) {
962  if ((count($this->entities) == 0) &&
963  (!isset($this->header->parameters['filename'])) &&
964  (!isset($this->header->parameters['name'])) &&
965  (isset($this->header->disposition) && is_object($this->header->disposition) &&
966  strtolower($this->header->disposition->name) != 'attachment')) {
968  $found = true;
969  }
970  }
971  }
972  }
973  if(!$found) {
974  foreach ($this->entities as $ent) {
975  if(!(is_object($ent->header->disposition) && strtolower($ent->header->disposition->name) == 'attachment') &&
976  (($ent->type0 != 'message') && ($ent->type1 != 'rfc822'))) {
977  $entity = $ent->findDisplayEntity($entity, $alt_order, $strict);
978  $found = true;
979  }
980  }
981  }
982  if(!$strict && !$found) {
983  if (($this->type0 == 'text') &&
984  in_array($this->type1, array('plain', 'html', 'message')) &&
985  isset($this->entity_id)) {
986  if (count($this->entities) == 0) {
987  if (!is_object($this->header->disposition) || strtolower($this->header->disposition->name) != 'attachment') {
989  }
990  }
991  }
992  }
993  return $entity;
994  }
995 
1000  function findAlternativeEntity($alt_order) {
1001  /* If we are dealing with alternative parts then we */
1002  /* choose the best viewable message supported by SM. */
1003  $best_view = 0;
1004  $entity = null;
1005  foreach($this->entities as $ent) {
1006  $type = $ent->header->type0 . '/' . $ent->header->type1;
1007  if ($type == 'multipart/related') {
1008  $type = $ent->header->getParameter('type');
1009  // Mozilla bug. Mozilla does not provide the parameter type.
1010  if (!$type) $type = 'text/html';
1011  }
1012  $altCount = count($alt_order);
1013  for ($j = $best_view; $j < $altCount; ++$j) {
1014  if (($alt_order[$j] == $type) && ($j >= $best_view)) {
1015  $best_view = $j;
1016  $entity = $ent;
1017  }
1018  }
1019  }
1020  return $entity;
1021  }
1022 
1026  function findRelatedEntity() {
1027  $msgs = array();
1028  $related_type = $this->header->getParameter('type');
1029  // Mozilla bug. Mozilla does not provide the parameter type.
1030  if (!$related_type) $related_type = 'text/html';
1031  $entCount = count($this->entities);
1032  for ($i = 0; $i < $entCount; ++$i) {
1033  $type = $this->entities[$i]->header->type0.'/'.$this->entities[$i]->header->type1;
1034  if ($related_type == $type) {
1035  $msgs[] = $this->entities[$i];
1036  }
1037  }
1038  return $msgs;
1039  }
1040 
1046  function getAttachments($exclude_id=array(), $result = array()) {
1047 /*
1048  if (($this->type0 == 'message') &&
1049  ($this->type1 == 'rfc822') &&
1050  ($this->entity_id) ) {
1051  $this = $this->entities[0];
1052  }
1053 */
1054  if (count($this->entities)) {
1055  foreach ($this->entities as $entity) {
1056  $exclude = false;
1057  foreach ($exclude_id as $excl) {
1058  if ($entity->entity_id === $excl) {
1059  $exclude = true;
1060  }
1061  }
1062 
1063  if (!$exclude) {
1064  if ($entity->type0 == 'multipart') {
1065  $result = $entity->getAttachments($exclude_id, $result);
1066  } else if ($entity->type0 != 'multipart') {
1067  $result[] = $entity;
1068  }
1069  }
1070  }
1071  } else {
1072  $exclude = false;
1073  foreach ($exclude_id as $excl) {
1074  $exclude = $exclude || ($this->entity_id == $excl);
1075  }
1076 
1077  if (!$exclude) {
1078  $result[] = $this;
1079  }
1080  }
1081  return $result;
1082  }
1083 
1090  function initAttachment($type, $name, $location) {
1091  $attachment = new Message();
1092  $mime_header = new MessageHeader();
1093  $mime_header->setParameter('name', $name);
1094  $pos = strpos($type, '/');
1095  if ($pos > 0) {
1096  $mime_header->type0 = substr($type, 0, $pos);
1097  $mime_header->type1 = substr($type, $pos+1);
1098  } else {
1099  $mime_header->type0 = $type;
1100  }
1101  $attachment->att_local_name = $location;
1102  $disposition = new Disposition('attachment');
1103  $disposition->properties['filename'] = $name;
1104  $mime_header->disposition = $disposition;
1105  $attachment->mime_header = $mime_header;
1106  $this->entities[]=$attachment;
1107  }
1108 
1113  function purgeAttachments() {
1114  if ($this->att_local_name) {
1115  global $username, $attachment_dir;
1116  $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
1117  if ( file_exists($hashed_attachment_dir . '/' . $this->att_local_name) ) {
1118  unlink($hashed_attachment_dir . '/' . $this->att_local_name);
1119  }
1120  }
1121  // recursively delete attachments from entities contained in this object
1122  for ($i=0, $entCount=count($this->entities);$i< $entCount; ++$i) {
1123  $this->entities[$i]->purgeAttachments();
1124  }
1125  }
1126 }
1127 
AddressStructure
Definition: AddressStructure.class.php:23
$body
if(isset($ldap_server) && $ldap_server[0] &&! extension_loaded('ldap')) $body
Definition: bug_report.php:106
Message\$entity
$entity
Definition: Message.class.php:75
Message\getMailbox
getMailbox()
Definition: Message.class.php:271
$cnt
$cnt
Definition: options_identities.php:86
Message\$is_flagged
$is_flagged
Definition: Message.class.php:103
Message\$is_mdnsent
$is_mdnsent
Definition: Message.class.php:108
$count
$count
Definition: message_details_bottom.php:97
Message\findRelatedEntity
findRelatedEntity()
Definition: Message.class.php:1026
Message\initAttachment
initAttachment($type, $name, $location)
Definition: Message.class.php:1090
$location
if(sqgetGlobalVar('return', $temp, SQ_POST)) if(sqgetGlobalVar('mailtodata', $mailtodata, SQ_GET)) $location
Definition: compose.php:144
Message\$offset
$offset
Definition: Message.class.php:119
Message\$type1
$type1
Definition: Message.class.php:56
Message\$parent
$parent
Definition: Message.class.php:79
Message\$body_part
$body_part
Definition: Message.class.php:113
Message\parseBodyStructure
parseBodyStructure($read, &$i, $sub_msg='')
Definition: Message.class.php:345
Message\addRFC822Header
addRFC822Header($read)
Definition: Message.class.php:197
Message\setEntIds
setEntIds(&$msg, $init=false, $i=0)
Definition: Message.class.php:308
Message\$mime_header
$mime_header
Definition: Message.class.php:42
$bnd_end
$bnd_end
Definition: message_details_bottom.php:83
Message\getFilename
getFilename()
Definition: Message.class.php:153
$username
global $username
Definition: validate.php:55
Message\parseLanguage
parseLanguage($read, &$i)
Definition: Message.class.php:799
Message\parseStructure
parseStructure($read, &$i, $sub_msg='')
Definition: Message.class.php:295
rfc822_header
$composeMessage rfc822_header
Definition: compose.php:363
Message\clean_up
clean_up()
Definition: Message.class.php:259
Message\$type0
$type0
Definition: Message.class.php:51
Message\findAlternativeEntity
findAlternativeEntity($alt_order)
Definition: Message.class.php:1000
Message\$rfc822_header
$rfc822_header
Definition: Message.class.php:32
Message\$is_answered
$is_answered
Definition: Message.class.php:93
Message\$entities
$entities
Definition: Message.class.php:61
$message
$message
Definition: download.php:54
Message\parseMessage
parseMessage($read, $type0, $type1)
Definition: Message.class.php:848
Message\$is_deleted
$is_deleted
Definition: Message.class.php:98
Message\parseLiteral
parseLiteral($read, &$i)
Definition: Message.class.php:646
Message\$length
$length
Definition: Message.class.php:125
Message\addEntity
addEntity($msg)
Definition: Message.class.php:144
getHashedDir
getHashedDir($username, $dir, $hash_dirs='')
Definition: prefs.php:109
Message\$decoded_body
$decoded_body
Definition: Message.class.php:83
Rfc822Header
Definition: Rfc822Header.class.php:26
$attachment_dir
$attachment_dir
Definition: config_default.php:517
Message\setEnt
setEnt($ent)
Definition: Message.class.php:136
Message\purgeAttachments
purgeAttachments()
Definition: Message.class.php:1113
Message\$att_local_name
$att_local_name
Definition: Message.class.php:131
Message\$parent_ent
$parent_ent
Definition: Message.class.php:71
Message\setBody
setBody($s)
Definition: Message.class.php:252
$j
for($i=0; $i< $numboxes; $i++) $j
Definition: empty_trash.php:72
Message\parseEnvelope
parseEnvelope($read, &$i, $hdr)
Definition: Message.class.php:556
MessageHeader
Definition: MessageHeader.class.php:25
Message\parseDisposition
parseDisposition($read, &$i)
Definition: Message.class.php:774
Message\parseParenthesis
parseParenthesis($read, $i)
Definition: Message.class.php:827
decodeHeader
decodeHeader($string, $utfencode=true, $htmlsave=true, $decide=false)
Definition: mime.php:633
$filename
if(isset($override_type0)) if(isset($override_type1)) $filename
Definition: download.php:97
$boundaries
$boundaries
Definition: message_details_bottom.php:86
_
_($str)
Definition: gettext.php:160
$content_indx
$content_indx
Definition: message_details_bottom.php:94
$read
$read
Definition: message_details_bottom.php:75
Message\getEntity
getEntity($ent)
Definition: Message.class.php:206
Message\parseProperties
parseProperties($read, &$i)
Definition: Message.class.php:525
Message
Definition: Message.class.php:27
Message\$flags
$flags
Definition: Message.class.php:46
Message\parseQuote
parseQuote($read, &$i)
Definition: Message.class.php:682
Message\$is_seen
$is_seen
Definition: Message.class.php:88
Message\findDisplayEntity
findDisplayEntity($entity=array(), $alt_order=array('text/plain', 'text/html'), $strict=false)
Definition: Message.class.php:921
Disposition
Definition: Disposition.class.php:24
Message\parseAddress
parseAddress($read, &$i)
Definition: Message.class.php:739
$header
$header
Definition: message_details_bottom.php:81
getTimeStamp
getTimeStamp($dateParts)
Definition: date.php:395
$msgs
if(isset($sendreceipt)) $msgs[$passed_id]['FLAG_SEEN']
Definition: read_body.php:852
Language
Definition: Language.class.php:24
Message\$reply_rfc822_header
$reply_rfc822_header
Definition: Message.class.php:37
Message\$entity_id
$entity_id
Definition: Message.class.php:66
Message\getAttachments
getAttachments($exclude_id=array(), $result=array())
Definition: Message.class.php:1046