Update of /cvsroot/squirrelmail/squirrelmail/functions In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18058/functions Modified Files: file_prefs.php forms.php imap_asearch.php imap_mailbox.php imap_messages.php mailbox_display.php rfc822address.php Log Message: Rewrite of internal message caching Added paginator support for asearch Added next/prev links in read_body to walk through search results Added individual sort settings / mailbox Added what I forgot to mention Index: file_prefs.php =================================================================== RCS file: /cvsroot/squirrelmail/squirrelmail/functions/file_prefs.php,v retrieving revision 1.32 retrieving revision 1.33 diff -u -w -r1.32 -r1.33 Index: forms.php =================================================================== RCS file: /cvsroot/squirrelmail/squirrelmail/functions/forms.php,v retrieving revision 1.7 retrieving revision 1.8 diff -u -w -r1.7 -r1.8 Index: imap_asearch.php =================================================================== RCS file: /cvsroot/squirrelmail/squirrelmail/functions/imap_asearch.php,v retrieving revision 1.26 retrieving revision 1.27 diff -u -w -r1.26 -r1.27 --- imap_asearch.php 5 May 2004 19:27:45 -0000 1.26 +++ imap_asearch.php 31 May 2004 20:07:43 -0000 1.27 @@ -194,10 +194,10 @@ /** Encode a string to quoted or literal as defined in rfc 3501 * - * - § 4.3 String: + * - 4.3 String: * A quoted string is a sequence of zero or more 7-bit characters, * excluding CR and LF, with double quote (<">) characters at each end. - * - § 9. Formal Syntax: + * - 9. Formal Syntax: * quoted-specials = DQUOTE / "\" * @param string $what string to encode * @param string $charset search charset used @@ -207,7 +207,6 @@ { if (strtoupper($charset) == 'ISO-2022-JP') // This should be now handled in imap_utf7_local? $what = mb_convert_encoding($what, 'JIS', 'auto'); -//if (ereg("[\"\\\r\n\x80-\xff]", $what)) if (preg_match('/["\\\\\r\n\x80-\xff]/', $what)) return '{' . strlen($what) . "}\r\n" . $what; // 4.3 literal form return '"' . $what . '"'; // 4.3 quoted string form @@ -348,15 +347,15 @@ $search_charset = ''; /* 6.4.4 try OPTIONAL [CHARSET] specification first */ if ($search_charset != '') - $query = 'SEARCH CHARSET "' . strtoupper($search_charset) . '" ALL ' . $search_string; + $query = 'SEARCH CHARSET "' . strtoupper($search_charset) . '" ' . $search_string; else - $query = 'SEARCH ALL ' . $search_string; + $query = 'SEARCH ' . $search_string; s_debug_dump('C:', $query); $readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE); /* 6.4.4 try US-ASCII charset if we tried an OPTIONAL [CHARSET] and received a tagged NO response (SHOULD be [BADCHARSET]) */ if (($search_charset != '') && (strtoupper($response) == 'NO')) { - $query = 'SEARCH CHARSET US-ASCII ALL ' . $search_string; + $query = 'SEARCH CHARSET US-ASCII ' . $search_string; s_debug_dump('C:', $query); $readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE); } @@ -364,15 +363,7 @@ sqimap_asearch_error_box($response, $query, $message); return array(); } - - // Keep going till we find the * SEARCH response - foreach ($readin as $readin_part) { - s_debug_dump('S:', $readin_part); - if (substr($readin_part, 0, 9) == '* SEARCH ') { - //EIMS returns multiple SEARCH responses, and this allowed according to Mark Crispin - $messagelist = sqimap_array_merge_unique($messagelist, preg_split("/ /", substr($readin_part, 9))); - } - } + $messagelist = parseUidList($readin,'SEARCH'); if (empty($messagelist)) //Empty search response, ie '* SEARCH' return array(); @@ -384,168 +375,6 @@ } /** - * Run the imap SORT command as defined in - * @link http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-13.txt - * @param resource $imapConnection the current imap stream - * @param string $search_string the full search expression as defined in rfc 3501 - * @param string $search_charset mandatory charset - * @param string $sort_criteria the full sort criteria expression eg "SUBJECT REVERSE DATE" - * @return array an IDs or UIDs array of matching messages or an empty array - */ -function sqimap_run_sort($imapConnection, $search_string, $search_charset, $sort_criteria) -{ - if ($search_charset == '') - $search_charset = 'US-ASCII'; - $query = 'SORT (' . $sort_criteria . ') "' . strtoupper($search_charset) . '" ALL ' . $search_string; - s_debug_dump('C:', $query); - $readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE); - s_debug_dump('S:', $response); - - /* 6.4 try US-ASCII charset if we received a tagged NO response (SHOULD be [BADCHARSET]) */ - if (($search_charset != 'US-ASCII') && (strtoupper($response) == 'NO')) { - s_debug_dump('S:', $readin); - $query = 'SORT (' . $sort_criteria . ') US-ASCII ALL ' . $search_string; - s_debug_dump('C:', $query); - $readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE); - s_debug_dump('S:', $response); - } - - if (strtoupper($response) != 'OK') { - s_debug_dump('S:', $readin); -// sqimap_asearch_error_box($response, $query, $message); -// return array(); - return sqimap_run_search($imapConnection, $search_string, $search_charset); // Fell back to standard search - } - - /* Keep going till we find the * SORT response */ - foreach ($readin as $readin_part) { - s_debug_dump('S:', $readin_part); - if (substr($readin_part, 0, 7) == '* SORT ') { - //SORT returns untagged responses - $messagelist = sqimap_array_merge_unique($messagelist, preg_split("/ /", substr($readin_part, 7))); - } - } - - if (empty($messagelist)) //Empty search response, ie '* SORT' - return array(); - - $cnt = count($messagelist); - for ($q = 0; $q < $cnt; $q++) - $id[$q] = trim($messagelist[$q]); - return $id; -} - -/** - * Run the imap THREAD command as defined in - * @link http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-13.txt - * @param resource $imapConnection the current imap stream - * @param string $search_string the full search expression as defined in rfc 3501 - * @param string $search_charset mandatory charset - * @param string $thread_algorithm the threading algorithm "ORDEREDSUBJECT" or "REFERENCES" - * @return array an IDs or UIDs array of matching messages or an empty array - * @global array thread_new will be used by thread view in mailbox_display - * @global array server_sort_array will be used by thread view in mailbox_display - */ -function sqimap_run_thread($imapConnection, $search_string, $search_charset, $thread_algorithm) -{ - global $thread_new, $server_sort_array; - - if (sqsession_is_registered('thread_new')) - sqsession_unregister('thread_new'); - if (sqsession_is_registered('server_sort_array')) - sqsession_unregister('server_sort_array'); - - $thread_new = array(); - $thread_new[0] = ""; - - $server_sort_array = array(); - - if ($search_charset == '') - $search_charset = 'US-ASCII'; - $query = 'THREAD ' . $thread_algorithm . ' "' . strtoupper($search_charset) . '" ALL ' . $search_string; - s_debug_dump('C:', $query); - $readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE); - s_debug_dump('S:', $response); - - /* 6.4 try US-ASCII charset if we received a tagged NO response (SHOULD be [BADCHARSET]) */ - if (($search_charset != 'US-ASCII') && (strtoupper($response) == 'NO')) { - s_debug_dump('S:', $readin); - $query = 'THREAD ' . $thread_algorithm . ' US-ASCII ALL ' . $search_string; - s_debug_dump('C:', $query); - $readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE); - s_debug_dump('S:', $response); - } - - if (strtoupper($response) != 'OK') { - s_debug_dump('S:', $readin); - if (empty($response)) { //imap server closed connection. We can't go further. -/* we should at this point: - - warn the user that the THREAD call has failed - - (offer him a way to) disconnect it permanently in the prefs - - perform the regular search instead or provide a way to do it in one click -*/ - global $sort, $mailbox, $php_self; - $message = _("The imap server failed to handle threading."); - $unthread = _("Click here to unset thread view for this mailbox and start again."); - if (preg_match('/^(.+)\?.+$/', $php_self, $regs)) - $source_url = $regs[1]; - else - $source_url = $php_self; - $link = '<a href=' . $source_url . '?sort=' . $sort . '&start_messages=1&set_thread=0&mailbox=' . urlencode($mailbox) . '>' . $unthread . '</a>'; - sqimap_asearch_error_box($response, $query, $message, $link); - return array(); - } - return sqimap_run_search($imapConnection, $search_string, $search_charset); // Fell back to standard search - } - - /* Keep going till we find the * THREAD response */ - foreach ($readin as $readin_part) { - s_debug_dump('S:', $readin_part); - if (substr($readin_part, 0, 9) == '* THREAD ') { - $thread_temp = preg_split("//", substr($readin_part, 9), -1, PREG_SPLIT_NO_EMPTY); - break; // Should be the last anyway - } - } - - if (empty($thread_temp)) //Empty search response, ie '* THREAD' - return array(); - - $char_count = count($thread_temp); - $counter = 0; - $k = 0; - for ($i=0;$i<$char_count;$i++) { - if ($thread_temp[$i] != ')' && $thread_temp[$i] != '(') { - $thread_new[$k] = $thread_new[$k] . $thread_temp[$i]; - } - elseif ($thread_temp[$i] == '(') { - $thread_new[$k] .= $thread_temp[$i]; - $counter++; - } - elseif ($thread_temp[$i] == ')') { - if ($counter > 1) { - $thread_new[$k] .= $thread_temp[$i]; - $counter = $counter - 1; - } - else { - $thread_new[$k] .= $thread_temp[$i]; - $k++; - $thread_new[$k] = ""; - $counter = $counter - 1; - } - } - } - sqsession_register($thread_new, 'thread_new'); - $thread_new = array_reverse($thread_new); - $thread_list = implode(" ", $thread_new); - $thread_list = str_replace("(", " ", $thread_list); - $thread_list = str_replace(")", " ", $thread_list); - $thread_list = preg_split("/\s/", $thread_list, -1, PREG_SPLIT_NO_EMPTY); - $server_sort_array = $thread_list; - sqsession_register($server_sort_array, 'server_sort_array'); - return $thread_list; -} - -/** * @global bool allow_charset_search user setting * @global array languages sm languages array * @global string squirrelmail_language user language setting @@ -602,7 +431,7 @@ } /** - * Performs the search, given all the criteria, merging results for every mailbox + * Create the search query strings for all given criteria and merge results for every mailbox * @param resource $imapConnection * @param array $mailbox_array (reference) * @param array $biop_array (reference) @@ -612,27 +441,19 @@ * @param array $exclude_array (reference) * @param array $sub_array (reference) * @param array $mboxes_array selectable unformatted mailboxes names (reference) - * @global bool allow_server_sort comes from config.php - * @global integer sort sm internal sort order - * @global bool allow_thread_sort comes from config.php - * @global bool thread_sort_messages does it really need to global? - * @global integer sort_by_ref thread by references - * @global string data_dir - * @global string username * @return array array(mailbox => array(UIDs)) */ function sqimap_asearch($imapConnection, &$mailbox_array, &$biop_array, &$unop_array, &$where_array, &$what_array, &$exclude_array, &$sub_array, &$mboxes_array) { - global $allow_server_sort, $sort, $allow_thread_sort, $thread_sort_messages, $sort_by_ref; - global $data_dir, $username; $search_charset = sqimap_asearch_get_charset(); $mbox_msgs = array(); + $mbox_search = array(); $search_string = ''; $cur_mailbox = $mailbox_array[0]; $cur_biop = ''; /* Start with ALL */ /* We loop one more time than the real array count, so the last search gets fired */ - for ($cur_crit = 0; $cur_crit <= count($where_array); $cur_crit++) { + for ($cur_crit=0,$iCnt=count($where_array); $cur_crit <= $iCnt; ++$cur_crit) { if (empty($exclude_array[$cur_crit])) { $next_mailbox = $mailbox_array[$cur_crit]; if ($next_mailbox != $cur_mailbox) { @@ -644,61 +465,52 @@ else $search_mboxes = array($cur_mailbox); foreach ($search_mboxes as $cur_mailbox) { - s_debug_dump('C:SELECT:', $cur_mailbox); - sqimap_mailbox_select($imapConnection, $cur_mailbox); - $thread_sort_messages = $allow_thread_sort && getPref($data_dir, $username, 'thread_' . $cur_mailbox); - if ($thread_sort_messages) { - if ($sort_by_ref == 1) - $thread_algorithm = 'REFERENCES'; - else - $thread_algorithm = 'ORDEREDSUBJECT'; - $found_msgs = sqimap_run_thread($imapConnection, $search_string, $search_charset, $thread_algorithm); + if (isset($mbox_search[$cur_mailbox])) { + $mbox_search[$cur_mailbox]['search'] .= ' ' . $search_string; + } else { + $mbox_search[$cur_mailbox]['search'] = $search_string; } - else - if (($allow_server_sort) && ($sort < 6)) { - $sort_criteria = sqimap_asearch_get_sort_criteria($cur_mailbox, $sort); - $found_msgs = sqimap_run_sort($imapConnection, $search_string, $search_charset, $sort_criteria); - } - else - $found_msgs = sqimap_run_search($imapConnection, $search_string, $search_charset); - if (isset($mbox_msgs[$cur_mailbox])) { - if ($cur_biop == 'OR') /* Merge with previous results */ - $mbox_msgs[$cur_mailbox] = sqimap_array_merge_unique($mbox_msgs[$cur_mailbox], $found_msgs); - else /* Intersect previous results */ - $mbox_msgs[$cur_mailbox] = array_values(array_intersect($found_msgs, $mbox_msgs[$cur_mailbox])); - } - else /* No previous results */ - $mbox_msgs[$cur_mailbox] = $found_msgs; - if (empty($mbox_msgs[$cur_mailbox])) /* Can happen with intersect, and we need at the end a contiguous array */ - unset($mbox_msgs[$cur_mailbox]); + $mbox_search[$cur_mailbox]['charset'] = $search_charset; } $cur_mailbox = $next_mailbox; $search_string = ''; + } - if (isset($where_array[$cur_crit])) { + if (isset($where_array[$cur_crit]) && empty($exclude_array[$cur_crit])) { $criteria = sqimap_asearch_build_criteria($where_array[$cur_crit], $what_array[$cur_crit], $search_charset); if (!empty($criteria)) { + //$criteria = 'ALL '. $criteria; $unop = $unop_array[$cur_crit]; - if (!empty($unop)) + if (!empty($unop)) { $criteria = $unop . ' ' . $criteria; + } else { + $criteria = 'ALL ' . $criteria; + } /* We need to infix the next non-excluded criteria's biop if it's the same mailbox */ $next_biop = ''; for ($next_crit = $cur_crit+1; $next_crit <= count($where_array); $next_crit++) { if (empty($exclude_array[$next_crit])) { - if (asearch_nz($mailbox_array[$next_crit]) == $cur_mailbox) + if (asearch_nz($mailbox_array[$next_crit]) == $cur_mailbox) { $next_biop = asearch_nz($biop_array[$next_crit]); - break; + if ($next_biop == 'OR' || $next_biop == 'ALL') { + $next_criterium = sqimap_asearch_build_criteria($where_array[$next_crit], $what_array[$next_crit], $search_charset); + // unset something + $exclude_array[$next_crit] = true; + $criteria .= $next_biop . ' '. $next_criterium; + } } } - if ($next_biop == 'OR') - $criteria = $next_biop . ' ' . $criteria; + } + //if ($next_biop == 'OR') + // $criteria = $next_biop . ' ' . $criteria; $search_string .= $criteria; - $cur_biop = asearch_nz($biop_array[$cur_crit]); + //$cur_biop = asearch_nz($biop_array[$cur_crit]); } } + } } - return $mbox_msgs; + return ($mbox_search); } ?> Index: imap_mailbox.php =================================================================== RCS file: /cvsroot/squirrelmail/squirrelmail/functions/imap_mailbox.php,v retrieving revision 1.233 retrieving revision 1.234 diff -u -w -r1.233 -r1.234 --- imap_mailbox.php 24 May 2004 19:55:20 -0000 1.233 +++ imap_mailbox.php 31 May 2004 20:07:43 -0000 1.234 @@ -247,44 +247,6 @@ return $cnt; } - -/** - * Expunge specified message - * - * We'll use this wrapper function to - * remove the message with the matching UID .. the order - * won't be changed - the array element for the message - * will just be removed. - */ - -function sqimap_mailbox_expunge_dmn($imapConnection, &$aMailbox, $message_id) { - $cnt = 0; - - if ($aMailbox['AUTO_EXPUNGE']) { - $cnt = sqimap_mailbox_expunge($imapConnection, $aMailbox['NAME'], true); - } else { - return $cnt; - } - $error = ''; - $message_id = (int) $message_id; // we use strickt array_search - if (is_array($aMailbox['UIDSET'])) { - $key = array_search($message_id,$aMailbox['UIDSET'],true); - if ($key !== false && !is_null($key)) { - unset($aMailbox['UIDSET'][$key]); - $aMailbox['UIDSET'] = array_values($aMailbox['UIDSET']); - // adapt the exists count to avoid triggering of a new sort - $aMailbox['EXISTS'] -= 1; - } else { - $aMailbox['UIDSET'] = get_sorted_msgs_list($imapConnection,$aMailbox,$error); - } - } else { - $aMailbox['UIDSET'] = get_sorted_msgs_list($imapConnection,$aMailbox,$error); - } - sqsession_register($aMailbox,'aLastSelectedMailbox'); - sqsession_register($aMailbox['UIDSET'],'server_sort_array'); //fix me, use aMailbox instead - return $cnt; -} - /** * Checks whether or not the specified mailbox exists */ Index: imap_messages.php =================================================================== RCS file: /cvsroot/squirrelmail/squirrelmail/functions/imap_messages.php,v retrieving revision 1.171 retrieving revision 1.172 diff -u -w -r1.171 -r1.172 --- imap_messages.php 26 May 2004 01:18:42 -0000 1.171 +++ imap_messages.php 31 May 2004 20:07:44 -0000 1.172 @@ -36,6 +36,11 @@ function sqimap_msgs_list_copy ($imap_stream, $id, $mailbox) { $msgs_id = sqimap_message_list_squisher($id); $read = sqimap_run_command ($imap_stream, "COPY $msgs_id " . sqimap_encode_mailbox_name($mailbox), true, $response, $message, TRUE); + if ($response == 'OK') { + return true; + } else { + return false; + } } /** @@ -47,8 +52,11 @@ */ function sqimap_msgs_list_move ($imap_stream, $id, $mailbox) { $msgs_id = sqimap_message_list_squisher($id); - $read = sqimap_run_command ($imap_stream, "COPY $msgs_id " . sqimap_encode_mailbox_name($mailbox), true, $response, $message, TRUE); - $read = sqimap_run_command ($imap_stream, "STORE $msgs_id +FLAGS (\\Deleted)", true, $response,$message, TRUE); + if (sqimap_msgs_list_copy ($imap_stream, $id, $mailbox)) { + return sqimap_toggle_flag($imap_stream, $id, '\\Deleted', true, true); + } else { + return false; + } } @@ -72,13 +80,19 @@ } function sqimap_msgs_list_delete ($imap_stream, $mailbox, $id, $bypass_trash=false) { + // FIX ME, remove globals by introducing an associative array with properties + // as 4th argument as replacement for the bypass_trash var global $move_to_trash, $trash_folder; - $msgs_id = sqimap_message_list_squisher($id); + $bRes = true; if (($move_to_trash == true) && ($bypass_trash != true) && (sqimap_mailbox_exists($imap_stream, $trash_folder) && ($mailbox != $trash_folder)) ) { - $read = sqimap_run_command ($imap_stream, "COPY $msgs_id " . sqimap_encode_mailbox_name($trash_folder), true, $response, $message, TRUE); + $bRes = sqimap_msgs_list_copy ($imap_stream, $id, $trash_folder); + } + if ($bRes) { + return sqimap_toggle_flag($imap_stream, $id, '\\Deleted', true, true); + } else { + return false; } - $read = sqimap_run_command ($imap_stream, "STORE $msgs_id +FLAGS (\\Deleted)", true, $response, $message, TRUE); } @@ -92,7 +106,9 @@ function sqimap_toggle_flag($imap_stream, $id, $flag, $set, $handle_errors) { $msgs_id = sqimap_message_list_squisher($id); $set_string = ($set ? '+' : '-'); - $read = sqimap_run_command ($imap_stream, "STORE $msgs_id ".$set_string."FLAGS ($flag)", $handle_errors, $response, $message, TRUE); + $aResponse = sqimap_run_command_list($imap_stream, "STORE $msgs_id ".$set_string."FLAGS ($flag)", $handle_errors, $response, $message, TRUE); + // parse the fetch response + return parseFetch($aResponse); } /** @deprecated */ @@ -131,13 +147,13 @@ /** * Retrieves an array with a sorted uid list. Sorting is done on the imap server -* +* @link http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-13.txt * @param resource $imap_stream IMAP socket connection * @param string $sSortField Field to sort on * @param bool $reverse Reverse order search * @return array $id sorted uid list */ -function sqimap_get_sort_order ($imap_stream, $sSortField,$reverse) { +function sqimap_get_sort_order ($imap_stream, $sSortField, $reverse, $search='ALL') { global $default_charset, $sent_folder; @@ -149,22 +165,33 @@ if ($reverse) { $sSortField = 'REVERSE '.$sSortField; } - $query = "SORT ($sSortField) ".strtoupper($default_charset).' ALL'; - $sort_test = sqimap_run_command ($imap_stream, $query, true, $response, $message, TRUE); + $query = "SORT ($sSortField) ".strtoupper($default_charset)." $search"; + // FIX ME sqimap_run_command should return the parsed data accessible by $aDATA['SORT'] + $aData = sqimap_run_command ($imap_stream, $query, false, $response, $message, TRUE); + /* fallback to default charset */ + if ($response == 'NO' && strpos($message,'[BADCHARSET]') !== false) { + $query = "SORT ($sSortField) US-ASCII $search"; + $aData = sqimap_run_command ($imap_stream, $query, true, $response, $message, TRUE); } - if (isset($sort_test[0])) { - for ($i=0,$iCnt=count($sort_test);$i<$iCnt;++$i) { - if (preg_match("/^\* SORT (.+)$/", $sort_test[$i], $regs)) { - $id = preg_split("/ /", trim($regs[1])); - break; } + + if ($response == 'OK') { + return parseUidList($aData,'SORT'); + } else { + return false; + } +} + +function parseUidList($aData,$sCommand) { + $aUid = array(); + if (isset($aData) && count($aData)) { + for ($i=0,$iCnt=count($aData);$i<$iCnt;++$i) { + if (preg_match("/^\* $sCommand (.+)$/", $aData[$i], $aMatch)) { + $aUid += preg_split("/ /", trim($aMatch[1])); } } - if (!preg_match("/OK/", $response)) { - return false; - } else { - return $id; } + return array_unique($aUid); } /** @@ -175,12 +202,15 @@ * @param bool $reverse Reverse order search * @return array $aUid sorted uid list */ -function get_squirrel_sort ($imap_stream, $sSortField, $reverse = false) { +function get_squirrel_sort ($imap_stream, $sSortField, $reverse = false, $aUid = NULL) { + if ($aUID === NULL) { + + } if ($sSortField != 'RFC822.SIZE' && $sSortField != 'INTERNALDATE') { - $msgs = sqimap_get_small_header_list($imap_stream, false, '*', + $msgs = sqimap_get_small_header_list($imap_stream, $aUid, array($sSortField), array()); } else { - $msgs = sqimap_get_small_header_list($imap_stream, false, '*', + $msgs = sqimap_get_small_header_list($imap_stream, $aUid, array(), array($sSortField)); } $aUid = array(); @@ -213,7 +243,7 @@ $walk = true; } foreach ($msgs as $item) { - $aUid[$item['ID']] = $item[$sSortField]; + $aUid[$item['UID']] = $item[$sSortField]; } natcasesort($aUid); $aUid = array_keys($aUid); @@ -239,7 +269,7 @@ $sSortField = 'SIZE'; } foreach ($msgs as $item) { - $aUid[$item['ID']] = (isset($item[$sSortField])) ? $item[$sSortField] : 0; + $aUid[$item['UID']] = (isset($item[$sSortField])) ? $item[$sSortField] : 0; } if ($reverse) { arsort($aUid,SORT_NUMERIC); @@ -380,26 +410,25 @@ /** * Returns an array with each element as a string representing one * message-thread as returned by the IMAP server. +* @link http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-13.txt */ -function get_thread_sort ($imap_stream) { +function get_thread_sort ($imap_stream, $search='ALL') { global $thread_new, $sort_by_ref, $default_charset, $server_sort_array, $indent_array; - if (sqsession_is_registered('thread_new')) { - sqsession_unregister('thread_new'); - } - if (sqsession_is_registered('indent_array')) { - sqsession_unregister('indent_array'); - } - if (sqsession_is_registered('server_sort_array')) { - sqsession_unregister('server_sort_array'); - } + $thread_temp = array (); if ($sort_by_ref == 1) { $sort_type = 'REFERENCES'; } else { $sort_type = 'ORDEREDSUBJECT'; } - $query = "THREAD $sort_type ".strtoupper($default_charset)." ALL"; + $query = "THREAD $sort_type ".strtoupper($default_charset)." $search"; + + $thread_test = sqimap_run_command ($imap_stream, $query, false, $response, $message, TRUE); + /* fallback to default charset */ + if ($response == 'NO' && strpos($message,'[BADCHARSET]') !== false) { + $query = "THREAD $sort_type US-ASCII $search"; $thread_test = sqimap_run_command ($imap_stream, $query, true, $response, $message, TRUE); + } if (isset($thread_test[0])) { for ($i=0,$iCnt=count($thread_test);$i<$iCnt;++$i) { if (preg_match("/^\* THREAD (.+)$/", $thread_test[$i], $regs)) { @@ -452,7 +481,7 @@ } } } - sqsession_register($thread_new, 'thread_new'); + $thread_new = array_reverse($thread_new); /* place the threads after each other in one string */ $thread_list = implode(" ", $thread_new); @@ -462,10 +491,7 @@ $server_sort_array = $thread_list; $indent_array = get_parent_level ($thread_new); - sqsession_register($indent_array, 'indent_array'); - - sqsession_register($server_sort_array, 'server_sort_array'); - return $thread_list; + return array($thread_list,$indent_array); } @@ -532,17 +558,17 @@ } } -function sqimap_get_small_header_list ($imap_stream, $msg_list, $show_num=false, +function sqimap_get_small_header_list ($imap_stream, $msg_list, $aHeaderFields = array('Date', 'To', 'Cc', 'From', 'Subject', 'X-Priority', 'Content-Type'), $aFetchItems = array('FLAGS', 'RFC822.SIZE', 'INTERNALDATE')) { - $messages = array(); + $aMessageList = array(); $read_list = array(); $bUidFetch = ! in_array('UID', $aFetchItems, true); /* Get the small headers for each message in $msg_list */ - if ($show_num != '999999' && $show_num != '*' ) { + if ($msg_list !== NULL) {//$show_num != -1 && $show_num != '*' ) { $msgs_str = sqimap_message_list_squisher($msg_list); /* * We need to return the data in the same order as the caller supplied @@ -551,15 +577,14 @@ */ if ($bUidFetch) { for ($i = 0; $i < sizeof($msg_list); $i++) { - $messages["$msg_list[$i]"] = array(); + $aMessageList["$msg_list[$i]"] = array(); } } } else { $msgs_str = '1:*'; + $aId = array(); } - - /* * Create the query */ @@ -574,11 +599,14 @@ $sFetchItems .= ' BODY.PEEK[HEADER.FIELDS ('.$sHeaderFields.')]'; } $query .= trim($sFetchItems) . ')'; + $aResponse = sqimap_run_command_list ($imap_stream, $query, true, $response, $message, $bUidFetch); + $aMessages = parseFetch($aResponse,$aMessageList); + array_reverse($aMessages); + return $aMessages; +} - $read_list = sqimap_run_command_list ($imap_stream, $query, true, $response, $message, $bUidFetch); - $i = 0; - - foreach ($read_list as $r) { +function parseFetch($aResponse,$aMessageList = array()) { + foreach ($aResponse as $r) { $msg = array(); // use unset because we do isset below $read = implode('',$r); @@ -590,6 +618,7 @@ /* extract the message id */ $i_space = strpos($read,' ',2); $id = substr($read,2,$i_space-2); + $msg['ID'] = $id; $fetch = substr($read,$i_space+1,5); if (!is_numeric($id) && $fetch !== 'FETCH') { $msg['ERROR'] = $read; // htmlspecialchars should be done just before display. this is backend code @@ -711,15 +740,15 @@ } } $msgi ="$unique_id"; - $msg['ID'] = $unique_id; + $msg['UID'] = $unique_id; - $messages[$msgi] = $msg; + $aMessageList[$msgi] = $msg; ++$msgi; } - array_reverse($messages); - return $messages; + return $aMessageList; } + function sqimap_parse_envelope($read, &$i, &$msg) { $arg_no = 0; $arg_a = array(); Index: mailbox_display.php =================================================================== RCS file: /cvsroot/squirrelmail/squirrelmail/functions/mailbox_display.php,v retrieving revision 1.399 retrieving revision 1.400 diff -u -w -r1.399 -r1.400 --- mailbox_display.php 24 May 2004 19:55:20 -0000 1.399 +++ mailbox_display.php 31 May 2004 20:07:44 -0000 1.400 @@ -19,6 +19,7 @@ require_once(SM_PATH . 'class/html.class.php'); require_once(SM_PATH . 'functions/imap_mailbox.php'); require_once(SM_PATH . 'functions/imap_messages.php'); +require_once(SM_PATH . 'functions/imap_asearch.php'); require_once(SM_PATH . 'functions/mime.php'); require_once(SM_PATH . 'functions/forms.php'); @@ -28,6 +29,11 @@ define('PG_SEL_MAX', 10); /** [...1193 lines suppressed...] + $body = implode('', $body_a); + $body .= "\r\n"; + + $localfilename = GenerateRandomString(32, 'FILE', 7); + $full_localfilename = "$hashed_attachment_dir/$localfilename"; + + $fp = fopen( $full_localfilename, 'wb'); + fwrite ($fp, $body); + fclose($fp); + $composeMessage->initAttachment('message/rfc822',$subject.'.msg', + $full_localfilename); + } + } + + $compose_messages[$composesession] = $composeMessage; + sqsession_register($compose_messages,'compose_messages'); + return $composesession; +} + ?> Index: rfc822address.php =================================================================== RCS file: /cvsroot/squirrelmail/squirrelmail/functions/rfc822address.php,v retrieving revision 1.1 retrieving revision 1.2 diff -u -w -r1.1 -r1.2 --- rfc822address.php 26 May 2004 00:35:03 -0000 1.1 +++ rfc822address.php 31 May 2004 20:07:44 -0000 1.2 @@ -29,15 +29,15 @@ **/ function parseRFC822Address($sAddress,$aProps) { - $aPropsDefault = array ( - 'domain' => '', // - 'limit' => 0, // limits returned addresses - 'abooklookup' => false); // callback function for addressbook lookup - - $aProps = is_array($aProps) ? array_merge($aPropsDefault,$aProps) : $aPropsDefault; +// $aPropsDefault = array ( +// 'domain' => '', // +// 'limit' => 0, // limits returned addresses +// 'abooklookup' => false); // callback function for addressbook lookup +// +// $aProps = is_array($aProps) ? array_merge($aPropsDefault,$aProps) : $aPropsDefault; - $cbLookup = $aProps['abooklookup']; - $sDomain = $aProps['domain']; +// $cbLookup = $aProps['abooklookup']; +// $sDomain = $aProps['domain']; $iLimit = $aProps['limit']; $aTokens = _getAddressTokens($sAddress); |