Source for file imap_messages.php

Documentation is available at imap_messages.php

  1. <?php
  2.  
  3. /**
  4.  * imap_messages.php
  5.  *
  6.  * This implements functions that manipulate messages
  7.  * NOTE: Quite a few functions in this file are obsolete
  8.  *
  9.  * @copyright &copy; 1999-2006 The SquirrelMail Project Team
  10.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  11.  * @version $Id: imap_messages.php,v 1.134.2.31 2006/09/30 10:15:11 tokul Exp $
  12.  * @package squirrelmail
  13.  * @subpackage imap
  14.  */
  15.  
  16.  
  17. /**
  18.  * Moves a set of messages ($id) to another mailbox ($mailbox)
  19.  * WARNING: function name does not match performed operation.
  20.  * Function performs message copy and flags existing messages
  21.  * as deleted
  22.  */
  23. function sqimap_msgs_list_copy($imap_stream, $id, $mailbox) {
  24.     global $uid_support;
  25.     $msgs_id = sqimap_message_list_squisher($id);
  26.     $read = sqimap_run_command ($imap_stream, "COPY $msgs_id \"$mailbox\"", true, $response, $message, $uid_support);
  27.     $read = sqimap_run_command ($imap_stream, "STORE $msgs_id +FLAGS (\\Deleted)", true, $response, $message, $uid_support);
  28. }
  29.  
  30.  
  31. /**
  32.  * Deletes a message and move it to trash or expunge the mailbox
  33.  */
  34. function sqimap_msgs_list_delete($imap_stream, $mailbox, $id) {
  35.     global $move_to_trash, $trash_folder, $uid_support;
  36.     $msgs_id = sqimap_message_list_squisher($id);
  37.     if (($move_to_trash == true) && (sqimap_mailbox_exists($imap_stream, $trash_folder) && ($mailbox != $trash_folder))) {
  38.         /**
  39.          * turn off internal error handling (third argument = false) and
  40.          * ignore copy to trash errors (allows to delete messages when overquota)
  41.          */
  42.         $read = sqimap_run_command ($imap_stream, "COPY $msgs_id \"$trash_folder\"", false, $response, $message, $uid_support);
  43.     }
  44.     $read = sqimap_run_command ($imap_stream, "STORE $msgs_id +FLAGS (\\Deleted)", true, $response, $message, $uid_support);
  45. }
  46.  
  47.  
  48. /**
  49.  * Sort the message list and crunch to be as small as possible
  50.  * (overflow could happen, so make it small if possible)
  51.  */
  52. function sqimap_message_list_squisher($messages_array) {
  53.     if( !is_array( $messages_array ) ) {
  54.         return $messages_array;
  55.     }
  56.  
  57.     sort($messages_array, SORT_NUMERIC);
  58.     $msgs_str = '';
  59.     while ($messages_array) {
  60.         $start = array_shift($messages_array);
  61.         $end = $start;
  62.         while (isset($messages_array[0]) && $messages_array[0] == $end + 1) {
  63.             $end = array_shift($messages_array);
  64.         }
  65.         if ($msgs_str != '') {
  66.             $msgs_str .= ',';
  67.         }
  68.         $msgs_str .= $start;
  69.         if ($start != $end) {
  70.             $msgs_str .= ':' . $end;
  71.         }
  72.     }
  73.     return $msgs_str;
  74. }
  75.  
  76.  
  77. /**
  78.  * Returns the references header lines
  79.  */
  80. function get_reference_header($imap_stream, $message) {
  81.     global $uid_support;
  82.     $responses = array ();
  83.     $results = array();
  84.     $references = "";
  85.     $responses = sqimap_run_command_list ($imap_stream, "FETCH $message BODY[HEADER.FIELDS (References)]", true, $response, $message, $uid_support);
  86.     if (!eregi("^\\* ([0-9]+) FETCH", $responses[0][0], $regs)) {
  87.         $responses = array ();
  88.     }
  89.     return $responses;
  90. }
  91.  
  92.  
  93. /**
  94.  * Get sort order from server and return it as the $id array for mailbox_display
  95.  */
  96. function sqimap_get_sort_order($imap_stream, $sort, $mbxresponse) {
  97.     global  $default_charset, $thread_sort_messages,
  98.             $internal_date_sort, $server_sort_array,
  99.             $sent_folder, $mailbox, $uid_support;
  100.  
  101.     if (sqsession_is_registered('server_sort_array')) {
  102.         sqsession_unregister('server_sort_array');
  103.     }
  104.  
  105.     $sort_on = array();
  106.     $reverse = 0;
  107.     $server_sort_array = array();
  108.     $sort_test = array();
  109.     $sort_query = '';
  110.  
  111.     if ($sort == 6) {
  112.         if ($uid_support) {
  113.             if (isset($mbxresponse['UIDNEXT']) && $mbxresponse['UIDNEXT']) {
  114.                 $uidnext = $mbxresponse['UIDNEXT']-1;
  115.             } else {
  116.                 $uidnext = '*';
  117.             }
  118.             $query = "SEARCH UID 1:$uidnext";
  119.             $uids = sqimap_run_command_list ($imap_stream, $query, true, $response, $message, true);
  120.             if (isset($uids[0])) {
  121.                 for ($i=0,$iCnt=count($uids);$i<$iCnt;++$i) {
  122.                     for ($j = 0, $jCnt=count($uids[$i]);$j<$jCnt;++$j) {
  123.                         if (preg_match("/^\* SEARCH (.+)$/", $uids[$i][$j], $regs)) {
  124.                             $server_sort_array += preg_split("/ /", trim($regs[1]));
  125.                         }
  126.                     }
  127.                 }
  128.             }
  129.             if (!preg_match("/OK/", $response)) {
  130.                 $server_sort_array = 'no';
  131.             }
  132.         } else {
  133.             $qty = $mbxresponse['EXISTS'];
  134.             $server_sort_array = range(1, $qty);
  135.         }
  136.         $server_sort_array = array_reverse($server_sort_array);
  137.         sqsession_register($server_sort_array, 'server_sort_array');
  138.         return $server_sort_array;
  139.     }
  140.  
  141.     $sort_on = array (0=> 'DATE',
  142.                       1=> 'DATE',
  143.                       2=> 'FROM',
  144.                       3=> 'FROM',
  145.                       4=> 'SUBJECT',
  146.                       5=> 'SUBJECT');
  147.     if ($internal_date_sort == true) {
  148.         $sort_on[0] = 'ARRIVAL';
  149.         $sort_on[1] = 'ARRIVAL';
  150.     }
  151.     if ($sent_folder == $mailbox) {
  152.         $sort_on[2] = 'TO';
  153.         $sort_on[3] = 'TO';
  154.     }
  155.     if (!empty($sort_on[$sort])) {
  156.         $query = "SORT ($sort_on[$sort]) ".strtoupper($default_charset).' ALL';
  157.         $sort_test = sqimap_run_command_list ($imap_stream, $query, true, $response, $message, $uid_support);
  158.     }
  159.     if (isset($sort_test[0])) {
  160.       for ($i=0,$iCnt=count($sort_test);$i<$iCnt;++$i) {
  161.         for ($j = 0, $jCnt=count($sort_test[$i]);$j<$jCnt;++$j) {
  162.             if (preg_match("/^\* SORT (.+)$/", $sort_test[$i][$j], $regs)) {
  163.                 $server_sort_array += preg_split("/ /", trim($regs[1]));
  164.             }
  165.         }
  166.       }
  167.     }
  168.  
  169.     if ($sort == 0 || $sort == 2 || $sort == 4) {
  170.        $server_sort_array = array_reverse($server_sort_array);
  171.     }
  172.     if (!preg_match("/OK/", $response)) {
  173.        $server_sort_array = 'no';
  174.     }
  175.     sqsession_register($server_sort_array, 'server_sort_array');
  176.     return $server_sort_array;
  177. }
  178.  
  179.  
  180. /**
  181.  * Get sort order from server if server does not have the SORT extension
  182.  * and return it as array for mailbox_display.
  183.  *
  184.  * @param  resource $imap_stream 
  185.  * @param  array    $mbxresponse response from a sqimap_mailbox_select
  186.  * @return array    $php_sort_array
  187.  */
  188. function sqimap_get_php_sort_order($imap_stream, $mbxresponse) {
  189.     global $uid_support;
  190.  
  191.     if (sqsession_is_registered('php_sort_array')) {
  192.         sqsession_unregister('php_sort_array');
  193.     }
  194.  
  195.     $php_sort_array = array();
  196.  
  197.     if ($uid_support) {
  198.         if (isset($mbxresponse['UIDNEXT']) && $mbxresponse['UIDNEXT']) {
  199.                 $uidnext = $mbxresponse['UIDNEXT']-1;
  200.         } else {
  201.             $uidnext = '*';
  202.         }
  203.         $query = "SEARCH UID 1:$uidnext";
  204.         $uids = sqimap_run_command ($imap_stream, $query, true, $response, $message, true);
  205.         if (isset($uids[0])) {
  206.             $php_sort_array = array();
  207.             // EIMS workaround. EIMS returns the result as multiple untagged SEARCH responses
  208.             foreach($uids as $line) {
  209.                 if (preg_match("/^\* SEARCH (.+)$/", $line, $regs)) {
  210.                      $php_sort_array += preg_split("/ /", trim($regs[1]));
  211.                 }
  212.             }
  213.         }
  214.         if (!preg_match("/OK/", $response)) {
  215.             $php_sort_array = 'no';
  216.         }
  217.     } else {
  218.        $qty = $mbxresponse['EXISTS'];
  219.        $php_sort_array = range(1, $qty);
  220.     }
  221.     sqsession_register($php_sort_array, 'php_sort_array');
  222.     return $php_sort_array;
  223. }
  224.  
  225.  
  226. /**
  227.  * Returns an indent array for printMessageinfo()
  228.  * This represents the amount of indent needed (value),
  229.  * for this message number (key)
  230.  */
  231. function get_parent_level($imap_stream) {
  232.     global $sort_by_ref, $default_charset, $thread_new;
  233.         $parent = "";
  234.         $child = "";
  235.         $cutoff = 0;
  236.  
  237.     /* loop through the threads and take unwanted characters out
  238.        of the thread string then chop it up
  239.      */
  240.     for ($i=0;$i<count($thread_new);$i++) {
  241.         $thread_new[$i] = preg_replace("/\s\(/", "(", $thread_new[$i]);
  242.         $thread_new[$i] = preg_replace("/(\d+)/", "$1|", $thread_new[$i]);
  243.         $thread_new[$i] = preg_split("/\|/", $thread_new[$i], -1, PREG_SPLIT_NO_EMPTY);
  244.     }
  245.     $indent_array = array();
  246.     if (!$thread_new) {
  247.         $thread_new = array();
  248.     }
  249.     /* looping through the parts of one message thread */
  250.  
  251.     for ($i=0;$i<count($thread_new);$i++) {
  252.         /* first grab the parent, it does not indent */
  253.  
  254.         if (isset($thread_new[$i][0])) {
  255.             if (preg_match("/(\d+)/", $thread_new[$i][0], $regs)) {
  256.                 $parent = $regs[1];
  257.             }
  258.         }
  259.         $indent_array[$parent] = 0;
  260.  
  261.         /*
  262.          * now the children, checking each thread portion for
  263.          * ),(, and space, adjusting the level and space values
  264.          * to get the indent level
  265.          */
  266.         $level = 0;
  267.         $spaces = array();
  268.         $spaces_total = 0;
  269.         $indent = 0;
  270.         $fake = FALSE;
  271.         for ($k=1;$k<(count($thread_new[$i]))-1;$k++) {
  272.             $chars = count_chars($thread_new[$i][$k], 1);
  273.             if (isset($chars['40'])) {       /* testing for ( */
  274.                 $level += $chars['40'];
  275.             }
  276.             if (isset($chars['41'])) {      /* testing for ) */
  277.                 $level -= $chars['41'];
  278.                 $spaces[$level] = 0;
  279.                 /* if we were faking lets stop, this portion
  280.                  * of the thread is over
  281.                  */
  282.                 if ($level == $cutoff) {
  283.                     $fake = FALSE;
  284.                 }
  285.             }
  286.             if (isset($chars['32'])) {      /* testing for space */
  287.                 if (!isset($spaces[$level])) {
  288.                     $spaces[$level] = 0;
  289.                 }
  290.                 $spaces[$level] += $chars['32'];
  291.             }
  292.             for ($x=0;$x<=$level;$x++) {
  293.                 if (isset($spaces[$x])) {
  294.                     $spaces_total += $spaces[$x];
  295.                 }
  296.             }
  297.             $indent = $level + $spaces_total;
  298.             /* must have run into a message that broke the thread
  299.              * so we are adjusting for that portion
  300.              */
  301.             if ($fake == TRUE) {
  302.                 $indent = $indent +1;
  303.             }
  304.             if (preg_match("/(\d+)/", $thread_new[$i][$k], $regs)) {
  305.                 $child = $regs[1];
  306.             }
  307.             /* the thread must be broken if $indent == 0
  308.              * so indent the message once and start faking it
  309.              */
  310.             if ($indent == 0) {
  311.                 $indent = 1;
  312.                 $fake = TRUE;
  313.                 $cutoff = $level;
  314.             }
  315.             /* dont need abs but if indent was negative
  316.              * errors would occur
  317.              */
  318.             $indent_array[$child] = abs($indent);
  319.             $spaces_total = 0;
  320.         }
  321.     }
  322.     return $indent_array;
  323. }
  324.  
  325.  
  326. /**
  327.  * Returns an array with each element as a string representing one
  328.  * message-thread as returned by the IMAP server.
  329.  */
  330. function get_thread_sort($imap_stream) {
  331.     global $thread_new, $sort_by_ref, $default_charset, $server_sort_array, $uid_support;
  332.     if (sqsession_is_registered('thread_new')) {
  333.         sqsession_unregister('thread_new');
  334.     }
  335.     if (sqsession_is_registered('server_sort_array')) {
  336.         sqsession_unregister('server_sort_array');
  337.     }
  338.     $thread_temp = array ();
  339.     if ($sort_by_ref == 1) {
  340.         $sort_type = 'REFERENCES';
  341.     } else {
  342.         $sort_type = 'ORDEREDSUBJECT';
  343.     }
  344.     $query = "THREAD $sort_type ".strtoupper($default_charset)." ALL";
  345.  
  346.     $thread_test = sqimap_run_command ($imap_stream, $query, true, $response, $message, $uid_support);
  347.     if (isset($thread_test[0])) {
  348.         for ($i=0,$iCnt=count($thread_test);$i<$iCnt;++$i) {
  349.             if (preg_match("/^\* THREAD (.+)$/", $thread_test[$i], $regs)) {
  350.                 $thread_list = trim($regs[1]);
  351.                 break;
  352.             }
  353.         }
  354.     } else {
  355.         $thread_list = "";
  356.     }
  357.     if (!preg_match("/OK/", $response)) {
  358.         $server_sort_array = 'no';
  359.         return $server_sort_array;
  360.     }
  361.     if (isset($thread_list)) {
  362.         $thread_temp = preg_split("//", $thread_list, -1, PREG_SPLIT_NO_EMPTY);
  363.     }
  364.  
  365.     $char_count = count($thread_temp);
  366.     $counter = 0;
  367.     $thread_new = array();
  368.     $k = 0;
  369.     $thread_new[0] = "";
  370.     for ($i=0;$i<$char_count;$i++) {
  371.         if ($thread_temp[$i] != ')' && $thread_temp[$i] != '(') {
  372.             $thread_new[$k] = $thread_new[$k] . $thread_temp[$i];
  373.         } elseif ($thread_temp[$i] == '(') {
  374.             $thread_new[$k] .= $thread_temp[$i];
  375.             $counter++;
  376.         } elseif ($thread_temp[$i] == ')') {
  377.             if ($counter > 1) {
  378.                 $thread_new[$k] .= $thread_temp[$i];
  379.                 $counter = $counter - 1;
  380.             } else {
  381.                 $thread_new[$k] .= $thread_temp[$i];
  382.                 $k++;
  383.                 $thread_new[$k] = "";
  384.                 $counter = $counter - 1;
  385.             }
  386.         }
  387.     }
  388.  
  389.     sqsession_register($thread_new, 'thread_new');
  390.     $thread_new = array_reverse($thread_new);
  391.     $thread_list = implode(" ", $thread_new);
  392.     $thread_list = str_replace("(", " ", $thread_list);
  393.     $thread_list = str_replace(")", " ", $thread_list);
  394.     $thread_list = preg_split("/\s/", $thread_list, -1, PREG_SPLIT_NO_EMPTY);
  395.     $server_sort_array = $thread_list;
  396.  
  397.     sqsession_register($server_sort_array, 'server_sort_array');
  398.     return $thread_list;
  399. }
  400.  
  401.  
  402. function elapsedTime($start) {
  403.     $stop = gettimeofday();
  404.     $timepassed =  1000000 * ($stop['sec'] - $start['sec']) + $stop['usec'] - $start['usec'];
  405.     return $timepassed;
  406. }
  407.  
  408.  
  409. /**
  410.  * Parses a string in an imap response. String starts with " or { which means it
  411.  * can handle double quoted strings and literal strings
  412.  *
  413.  * @param string $read imap response
  414.  * @param integer $i (reference) offset in string
  415.  * @return string $s parsed string without the double quotes or literal count
  416.  */
  417. function parseString($read,&$i) {
  418.     $char = $read{$i};
  419.     $s = '';
  420.     if ($char == '"') {
  421.         $iPos = ++$i;
  422.         while (true) {
  423.             $iPos = strpos($read,'"',$iPos);
  424.             if (!$iPos) break;
  425.             if ($iPos && $read{$iPos -1} != '\\') {
  426.                 $s = substr($read,$i,($iPos-$i));
  427.                 $i = $iPos;
  428.                 break;
  429.             }
  430.             $iPos++;
  431.             if ($iPos > strlen($read)) {
  432.                 break;
  433.             }
  434.         }
  435.     } else if ($char == '{') {
  436.         $lit_cnt = '';
  437.         ++$i;
  438.         $iPos = strpos($read,'}',$i);
  439.         if ($iPos) {
  440.             $lit_cnt = substr($read, $i, $iPos - $i);
  441.             $i += strlen($lit_cnt) + 3; /* skip } + \r + \n */
  442.             /* Now read the literal */
  443.             $s = ($lit_cnt ? substr($read,$i,$lit_cnt): '');
  444.             $i += $lit_cnt;
  445.             /* temp bugfix (SM 1.5 will have a working clean version)
  446.                too much work to implement that version right now */
  447.             --$i;
  448.         } else { /* should never happen */
  449.             $i += 3; /* } + \r + \n */
  450.             $s = '';
  451.         }
  452.     } else {
  453.         return false;
  454.     }
  455.     ++$i;
  456.     return $s;
  457. }
  458.  
  459.  
  460. /**
  461.  * Parses a string containing an array from an imap response. String starts with ( and end with )
  462.  *
  463.  * @param string $read imap response
  464.  * @param integer $i (reference) offset in string
  465.  * @return array $a
  466.  */
  467. function parseArray($read,&$i) {
  468.     $i = strpos($read,'(',$i);
  469.     $i_pos = strpos($read,')',$i);
  470.     $s = substr($read,$i+1,$i_pos - $i -1);
  471.     $a = explode(' ',$s);
  472.     if ($i_pos) {
  473.         $i = $i_pos+1;
  474.         return $a;
  475.     } else {
  476.         return false;
  477.     }
  478. }
  479.  
  480. /**
  481.  * Normalise the different Priority headers into a uniform value,
  482.  * namely that of the X-Priority header (1, 3, 5). Supports:
  483.  * Prioirty, X-Priority, Importance.
  484.  * X-MS-Mail-Priority is not parsed because it always coincides
  485.  * with one of the other headers.
  486.  *
  487.  * DUPLICATE CODE ALERT:
  488.  * NOTE: this is actually a duplicate from the function in
  489.  * class/mime/Rfc822Header.php.
  490.  */
  491. function parsePriority($sValue) {
  492.     $aValue=split('/\w/',trim($sValue));
  493.     $value = strtolower(array_shift($aValue));
  494.     if ( is_numeric($value) ) {
  495.         return $value;
  496.     }
  497.     if ( $value == 'urgent' || $value == 'high' ) {
  498.         return 1;
  499.     } elseif ( $value == 'non-urgent' || $value == 'low' ) {
  500.         return 5;
  501.     }
  502.     return 3;
  503. }
  504.  
  505.  
  506. /**
  507.  * Retrieves a list with headers, flags, size or internaldate from the imap server
  508.  */
  509. function sqimap_get_small_header_list($imap_stream, $msg_list, $show_num=false) {
  510.     global $squirrelmail_language, $color, $data_dir, $username, $imap_server_type;
  511.     global $uid_support, $allow_server_sort;
  512.     /* Get the small headers for each message in $msg_list */
  513.     $maxmsg = sizeof($msg_list);
  514.     if ($show_num != '999999') {
  515.         $msgs_str = sqimap_message_list_squisher($msg_list);
  516.     } else {
  517.         $msgs_str = '1:*';
  518.     }
  519.     $messages = array();
  520.     $read_list = array();
  521.  
  522.     /*
  523.      * We need to return the data in the same order as the caller supplied
  524.      * in $msg_list, but IMAP servers are free to return responses in
  525.      * whatever order they wish... So we need to re-sort manually
  526.      */
  527.     for ($i = 0; $i < sizeof($msg_list); $i++) {
  528.         $messages["$msg_list[$i]"] = array();
  529.     }
  530.  
  531.     $internaldate = getPref($data_dir, $username, 'internal_date_sort', SMPREF_ON);
  532.     if ($internaldate) {
  533.         $query = "FETCH $msgs_str (FLAGS UID RFC822.SIZE INTERNALDATE BODY.PEEK[HEADER.FIELDS (Date To Cc From Subject X-Priority Importance Priority Content-Type)])";
  534.     } else {
  535.         $query = "FETCH $msgs_str (FLAGS UID RFC822.SIZE BODY.PEEK[HEADER.FIELDS (Date To Cc From Subject X-Priority Importance Priority Content-Type)])";
  536.     }
  537.     $read_list = sqimap_run_command_list ($imap_stream, $query, true, $response, $message, $uid_support);
  538.     $i = 0;
  539.  
  540.     foreach ($read_list as $r) {
  541.         /* initialize/reset vars */
  542.         $subject = _("(no subject)");
  543.         $from = _("Unknown Sender");
  544.         $priority = 0;
  545.         $messageid = '<>';
  546.         $type = array('','');
  547.         $cc = $to = $inrepto = '';
  548.         $size = 0;
  549.  
  550.         // use unset because we do isset below
  551.         unset($date);
  552.  
  553.         $flag_seen = $flag_answered = $flag_deleted = $flag_flagged = false;
  554.  
  555.         $read = implode('',$r);
  556.  
  557.         /*
  558.          * #id<space>FETCH<space>(
  559.          */
  560.  
  561.         /* extract the message id */
  562.         $i_space = strpos($read,' ',2);
  563.         $id = substr($read,2,$i_space-2);
  564.         $fetch = substr($read,$i_space+1,5);
  565.         if (!is_numeric($id) && $fetch !== 'FETCH') {
  566.             set_up_language($squirrelmail_language);
  567.             echo '<br /><b><font color="'.$color[2].'">' .
  568.                  _("ERROR: Could not complete request.") .
  569.                  '</b><br />' .
  570.                  _("Unknown response from IMAP server:") . ' 1.' .
  571.                  htmlspecialchars($read) . "</font><br />\n";
  572.                  break;
  573.         }
  574.         $i = strpos($read,'(',$i_space+5);
  575.         $read = substr($read,$i+1);
  576.         $i_len = strlen($read);
  577.         $i = 0;
  578.         while ($i < $i_len && $i !== false) {
  579.             /* get argument */
  580.             $read = trim(substr($read,$i));
  581.             $i_len = strlen($read);
  582.             $i = strpos($read,' ');
  583.             $arg = substr($read,0,$i);
  584.             ++$i;
  585.             switch ($arg)
  586.             {
  587.             case 'UID':
  588.                 $i_pos = strpos($read,' ',$i);
  589.                 if (!$i_pos) {
  590.                     $i_pos = strpos($read,')',$i);
  591.                 }
  592.                 if ($i_pos) {
  593.                     $unique_id = substr($read,$i,$i_pos-$i);
  594.                     $i = $i_pos+1;
  595.                 } else {
  596.                     break 3;
  597.                 }
  598.                 break;
  599.             case 'FLAGS':
  600.                 $flags = parseArray($read,$i);
  601.                 if (!$flags) break 3;
  602.                 foreach ($flags as $flag) {
  603.                     $flag = strtolower($flag);
  604.                     switch ($flag)
  605.                     {
  606.                     case '\\seen': $flag_seen = true; break;
  607.                     case '\\answered': $flag_answered = true; break;
  608.                     case '\\deleted': $flag_deleted = true; break;
  609.                     case '\\flagged': $flag_flagged = true; break;
  610.                     default: break;
  611.                     }
  612.                 }
  613.                 break;
  614.             case 'RFC822.SIZE':
  615.                 $i_pos = strpos($read,' ',$i);
  616.                 if (!$i_pos) {
  617.                     $i_pos = strpos($read,')',$i);
  618.                 }
  619.                 if ($i_pos) {
  620.                     $size = substr($read,$i,$i_pos-$i);
  621.                     $i = $i_pos+1;
  622.                 } else {
  623.                     break 3;
  624.                 }
  625.  
  626.                 break;
  627.             case 'INTERNALDATE':
  628.                 $date = parseString($read,$i);
  629.                 //if ($tmpdate === false) break 3;
  630.                 //$tmpdate = str_replace('  ',' ',$tmpdate);
  631.                 //$tmpdate = explode(' ',$tmpdate);
  632.                 //$date = str_replace('-',' ',$tmpdate[0]) . " " .
  633.                 //                            $tmpdate[1] . ' ' . $tmpdate[2];
  634.                 break;
  635.             case 'BODY.PEEK[HEADER.FIELDS':
  636.             case 'BODY[HEADER.FIELDS':
  637.                 $i = strpos($read,'{',$i);
  638.                 $header = parseString($read,$i);
  639.                 if ($header === false) break 2;
  640.                 /* First we replace all \r\n by \n, and unfold the header */
  641.                 $hdr = trim(str_replace(array("\r\n", "\n\t", "\n "),array("\n", ' ', ' '), $header));
  642.                 /* Now we can make a new header array with */
  643.                 /* each element representing a headerline  */
  644.                 $hdr = explode("\n" , $hdr);
  645.                 foreach ($hdr as $line) {
  646.                     $pos = strpos($line, ':');
  647.                     if ($pos > 0) {
  648.                         $field = strtolower(substr($line, 0, $pos));
  649.                         if (!strstr($field,' ')) { /* valid field */
  650.                             $value = trim(substr($line, $pos+1));
  651.                             switch($field)
  652.                             {
  653.                             case 'to': $to = $value; break;
  654.                             case 'cc': $cc = $value; break;
  655.                             case 'from': $from = $value; break;
  656.                             case 'date': $date = $value; break;
  657.                             case 'x-priority':
  658.                             case 'importance':
  659.                             case 'priority':
  660.                                 $priority = parsePriority($value); break;
  661.                             case 'subject':
  662.                                 $subject = $value;
  663.                                 if ($subject == "") {
  664.                                     $subject = _("(no subject)");
  665.                                 }
  666.                                 break;
  667.                             case 'content-type':
  668.                                 $type = $value;
  669.                                 if ($pos = strpos($type, ";")) {
  670.                                     $type = substr($type, 0, $pos);
  671.                                 }
  672.                                 $type = explode("/", $type);
  673.                                 if(!is_array($type)) {
  674.                                     $type[0] = 'text';
  675.                                 }
  676.                                 break;
  677.                             default: break;
  678.                             }
  679.                         }
  680.                     }
  681.                 }
  682.                 break;
  683.             default:
  684.                 ++$i;
  685.                 break;
  686.             }
  687.         }
  688.         if (isset($date)) {
  689.             $date = str_replace('  ', ' ', $date);
  690.             $tmpdate  = explode(' ', trim($date));
  691.         } else {
  692.             $tmpdate = $date = array();
  693.         }
  694.         if ($uid_support) {
  695.             $msgi ="$unique_id";
  696.             $messages[$msgi]['ID'] = $unique_id;
  697.         } else {
  698.             $msgi = "$id";
  699.             $messages[$msgi]['ID'] = $id;
  700.         }
  701.         $messages[$msgi]['TIME_STAMP'] = getTimeStamp($tmpdate);
  702.         $messages[$msgi]['DATE_STRING'] = getDateString($messages[$msgi]['TIME_STAMP']);
  703.         $messages[$msgi]['FROM'] = $from; //parseAddress($from);
  704.         $messages[$msgi]['SUBJECT'] = $subject;
  705. //        if (handleAsSent($mailbox)) {
  706.             $messages[$msgi]['TO'] = $to; //parseAddress($to);
  707. //        }
  708.         $messages[$msgi]['PRIORITY'] = $priority;
  709.         $messages[$msgi]['CC'] = $cc; //parseAddress($cc);
  710.         $messages[$msgi]['SIZE'] = $size;
  711.         $messages[$msgi]['TYPE0'] = $type[0];
  712.         $messages[$msgi]['FLAG_DELETED'] = $flag_deleted;
  713.         $messages[$msgi]['FLAG_ANSWERED'] = $flag_answered;
  714.         $messages[$msgi]['FLAG_SEEN'] = $flag_seen;
  715.         $messages[$msgi]['FLAG_FLAGGED'] = $flag_flagged;
  716.  
  717.         /* non server sort stuff */
  718.         if (!$allow_server_sort) {
  719.            $from = parseAddress($from);
  720.            if ($from[0][1]) {
  721.               $from = decodeHeader($from[0][1]);
  722.            } else {
  723.               $from = $from[0][0];
  724.            }
  725.            $messages[$msgi]['FROM-SORT'] = $from;
  726.            $subject_sort = strtolower(decodeHeader($subject));
  727.            if (preg_match("/^(vedr|sv|re|aw):\s*(.*)$/si", $subject_sort, $matches)){
  728.                 $messages[$msgi]['SUBJECT-SORT'] = $matches[2];
  729.            } else {
  730.                $messages[$msgi]['SUBJECT-SORT'] = $subject_sort;
  731.            }
  732.         }
  733.         ++$msgi;
  734.     }
  735.     array_reverse($messages);
  736.     $new_messages = array();
  737.     foreach ($messages as $i =>$message) {
  738.         $new_messages[] = $message;
  739.     }
  740.     return $new_messages;
  741. }
  742.  
  743.  
  744. /**
  745.  * Obsolete?
  746.  */
  747. function sqimap_get_headerfield($imap_stream, $field) {
  748.     global $uid_support, $squirrelmail_language;
  749.     $sid = sqimap_session_id(false);
  750.  
  751.     $results = array();
  752.     $read_list = array();
  753.  
  754.     $query = "FETCH 1:* (UID BODY.PEEK[HEADER.FIELDS ($field)])";
  755.     $readin_list = sqimap_run_command_list ($imap_stream, $query, true, $response, $message, $uid_support);
  756.     $i = 0;
  757.  
  758.     foreach ($readin_list as $r) {
  759.         $r = implode('',$r);
  760.         /* first we unfold the header */
  761.         $r = str_replace(array("\r\n", "\n\t","\n\s"),array("\n",'',''),$r);
  762.         /*
  763.          * now we can make a new header array with each element representing
  764.          * a headerline
  765.          */
  766.         $r = explode("\n" , $r);
  767.         if (!$uid_support) {
  768.             if (!preg_match("/^\\*\s+([0-9]+)\s+FETCH/iAU",$r[0], $regs)) {
  769.                 set_up_language($squirrelmail_language);
  770.                 echo '<br /><b><font color="'.$color[2].'">' .
  771.                       _("ERROR: Could not complete request.") .
  772.                       '</b><br />' .
  773.                       _("Unknown response from IMAP server:") . ' 1.' .
  774.                       $r[0] . "</font><br />\n";
  775.             } else {
  776.                 $id = $regs[1];
  777.             }
  778.         } else {
  779.             if (!preg_match("/^\\*\s+([0-9]+)\s+FETCH.*UID\s+([0-9]+)\s+/iAU",$r[0], $regs)) {
  780.                 set_up_language($squirrelmail_language);
  781.                 echo '<br /><b><font color="'.$color[2].'">' .
  782.                      _("ERROR: Could not complete request.") .
  783.                      '</b><br />' .
  784.                      _("Unknown response from IMAP server:") . ' 1.' .
  785.                      $r[0] . "</font><br />\n";
  786.             } else {
  787.                 $id = $regs[2];
  788.             }
  789.         }
  790.         $field = $r[1];
  791.         $field = substr($field,strlen($field)+2);
  792.         $result[] = array($id,$field);
  793.     }
  794.     return $result;
  795. }
  796.  
  797.  
  798. /**
  799.  * Returns a message array with all the information about a message.
  800.  * See the documentation folder for more information about this array.
  801.  */
  802. function sqimap_get_message($imap_stream, $id, $mailbox) {
  803.     global $uid_support;
  804.  
  805.     // typecast to int to prohibit 1:* msgs sets
  806.     $id = (int) $id;
  807.     $flags = array();
  808.     $read = sqimap_run_command($imap_stream, "FETCH $id (FLAGS BODYSTRUCTURE)", true, $response, $message, $uid_support);
  809.     if ($read) {
  810.         if (preg_match('/.+FLAGS\s\((.*)\)\s/AUi',$read[0],$regs)) {
  811.             if (trim($regs[1])) {
  812.                 $flags = preg_split('/ /', $regs[1],-1,PREG_SPLIT_NO_EMPTY);
  813.             }
  814.         }
  815.     } else {
  816.         /* the message was not found, maybe the mailbox was modified? */
  817.         global $sort, $startMessage, $color;
  818.  
  819.         $errmessage = _("The server couldn't find the message you requested.") .
  820.             '<p>'._("Most probably your message list was out of date and the message has been moved away or deleted (perhaps by another program accessing the same mailbox).");
  821.         /* this will include a link back to the message list */
  822.         error_message($errmessage, $mailbox, $sort, (int) $startMessage, $color);
  823.         exit;
  824.     }
  825.     $bodystructure = implode('',$read);
  826.     $msg =  mime_structure($bodystructure,$flags);
  827.     $read = sqimap_run_command($imap_stream, "FETCH $id BODY[HEADER]", true, $response, $message, $uid_support);
  828.     $rfc822_header = new Rfc822Header();
  829.     $rfc822_header->parseHeader($read);
  830.     $msg->rfc822_header = $rfc822_header;
  831.     return $msg;
  832. }
  833.  
  834.  
  835. /**
  836.  * Wrapper function that reformats the header information.
  837.  * Obsolete?
  838.  */
  839. function sqimap_get_message_header($imap_stream, $id, $mailbox) {
  840.     global $uid_support;
  841.     $read = sqimap_run_command ($imap_stream, "FETCH $id BODY[HEADER]", true, $response, $message, $uid_support);
  842.     $header = sqimap_get_header($imap_stream, $read);
  843.     $header->id = $id;
  844.     $header->mailbox = $mailbox;
  845.     return $header;
  846. }
  847.  
  848.  
  849. /**
  850.  * Wrapper function that reformats the entity header information.
  851.  * Obsolete?
  852.  */
  853. function sqimap_get_ent_header($imap_stream, $id, $mailbox, $ent) {
  854.     global $uid_support;
  855.     $read = sqimap_run_command ($imap_stream, "FETCH $id BODY[$ent.HEADER]", true, $response, $message, $uid_support);
  856.     $header = sqimap_get_header($imap_stream, $read);
  857.     $header->id = $id;
  858.     $header->mailbox = $mailbox;
  859.     return $header;
  860. }
  861.  
  862.  
  863. /**
  864.  * Function to get the mime headers
  865.  * Obsolete?
  866.  */
  867. function sqimap_get_mime_ent_header($imap_stream, $id, $mailbox, $ent) {
  868.     global $uid_support;
  869.     $read = sqimap_run_command ($imap_stream, "FETCH $id:$id BODY[$ent.MIME]", true, $response, $message, $uid_support);
  870.     $header = sqimap_get_header($imap_stream, $read);
  871.     $header->id = $id;
  872.     $header->mailbox = $mailbox;
  873.     return $header;
  874. }
  875.  
  876.  
  877. /**
  878.  * Copies specified messages to specified folder
  879.  *
  880.  * This function is removed from SquirrelMail 1.5.1 and later versions.
  881.  * @param stream $imap_stream IMAP connection resource
  882.  * @param string $start starting message id or uid.
  883.  * @param string $end end message id or uid
  884.  * @param string $mailbox target mailbox
  885.  * @param boolean $handle_errors (since 1.4.8) handle errors
  886.  * @return boolean (since 1.4.8) true, if message copy command was successful.
  887.  *   false on error.
  888.  * @since 0.4
  889.  * @deprecated Use sqimap_msgs_list_copy() instead.
  890.  */
  891. function sqimap_messages_copy($imap_stream, $start, $end, $mailbox, $handle_errors=true) {
  892.     global $uid_support;
  893.     $read = sqimap_run_command ($imap_stream, "COPY $start:$end \"$mailbox\"", $handle_errors, $response, $message, $uid_support);
  894.     return ($response == 'OK');
  895. }
  896.  
  897.  
  898. /**
  899.  * Deletes specified messages and moves them to trash if possible
  900.  * Obsolete
  901.  */
  902. function sqimap_messages_delete($imap_stream, $start, $end, $mailbox) {
  903.     global $move_to_trash, $trash_folder, $auto_expunge, $uid_support;
  904.  
  905.     if (($move_to_trash == true) && (sqimap_mailbox_exists($imap_stream, $trash_folder) && ($mailbox != $trash_folder))) {
  906.         /**
  907.          * turn off internal error handling (fifth argument = false) and
  908.          * ignore copy to trash errors (allows to delete messages when overquota)
  909.          */
  910.         sqimap_messages_copy ($imap_stream, $start, $end, $trash_folder, false);
  911.     }
  912.     sqimap_messages_flag ($imap_stream, $start, $end, "Deleted", true);
  913. }
  914.  
  915.  
  916. /**
  917.  * Sets the specified messages with specified flag
  918.  */
  919. function sqimap_messages_flag($imap_stream, $start, $end, $flag, $handle_errors) {
  920.     global $uid_support;
  921.     $read = sqimap_run_command ($imap_stream, "STORE $start:$end +FLAGS (\\$flag)", $handle_errors, $response, $message, $uid_support);
  922. }
  923.  
  924.  
  925. /* Remove specified flag from specified messages */
  926. function sqimap_messages_remove_flag($imap_stream, $start, $end, $flag, $handle_errors) {
  927.     global $uid_support;
  928.     $read = sqimap_run_command ($imap_stream, "STORE $start:$end -FLAGS (\\$flag)", $handle_errors, $response, $message, $uid_support);
  929. }
  930.  
  931.  
  932. function sqimap_toggle_flag($imap_stream, $id, $flag, $set, $handle_errors) {
  933.     global $uid_support;
  934.     $msgs_id = sqimap_message_list_squisher($id);
  935.     $set_string = ($set ? '+' : '-');
  936.     $read = sqimap_run_command ($imap_stream, "STORE $msgs_id ".$set_string."FLAGS ($flag)", $handle_errors, $response, $message, $uid_support);
  937. }
  938.  
  939.  
  940. /**
  941.  * Obsolete?
  942.  */
  943. function sqimap_get_small_header($imap_stream, $id, $sent) {
  944.     $res = sqimap_get_small_header_list($imap_stream, $id, $sent);
  945.     return $res[0];
  946. }
  947.  
  948. ?>

Documentation generated on Sat, 07 Oct 2006 16:31:48 +0300 by phpDocumentor 1.3.0RC6