From c2d47d51b70b0ffbc4203a91f4e38381fa48d751 Mon Sep 17 00:00:00 2001 From: alex-brainstorm Date: Sat, 1 Nov 2003 17:29:18 +0000 Subject: [PATCH] SORT and THREAD handling in search git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@6077 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- functions/imap_asearch.php | 162 +++++++++++++++++++++++++++++++++++-- src/search.php | 104 +++++++++++++++--------- 2 files changed, 222 insertions(+), 44 deletions(-) diff --git a/functions/imap_asearch.php b/functions/imap_asearch.php index d2555578..d1c5edfe 100644 --- a/functions/imap_asearch.php +++ b/functions/imap_asearch.php @@ -82,6 +82,7 @@ $imap_error_titles = array( ); // why can't this just use sqimap_error_box() ? +// It does, indeed I isolated sqimap_error_box() as a stand-alone function just for this purpose ;) function sqimap_asearch_error_box($response, $query, $message) { global $imap_error_titles; @@ -269,10 +270,9 @@ function sqimap_run_search($imapConnection, $search_string, $search_charset) unset($messagelist); - /* Keep going till we find the SEARCH response */ + /* Keep going till we find the * SEARCH response */ foreach ($readin as $readin_part) { s_debug_dump('S:', $readin_part); - /* Check to see if a SEARCH response was received */ if (substr($readin_part, 0, 9) == '* SEARCH ') { $messagelist = preg_split("/ /", substr($readin_part, 9)); break; // Should be the last anyway @@ -301,6 +301,129 @@ function sqimap_run_search($imapConnection, $search_string, $search_charset) return $id; } +function sqimap_run_sort($imapConnection, $search_string, $search_charset, $sort_criteria) +{ + global $uid_support; + + 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, $uid_support); + + /* 6.4 try US-ASCII charset if we received a tagged NO response (SHOULD be [BADCHARSET]) */ + if (($search_charset != 'US-ASCII') && (strtoupper($response) == 'NO')) { + $query = 'SORT (' . $sort_criteria . ') US-ASCII ALL ' . $search_string; + s_debug_dump('C:', $query); + $readin = sqimap_run_command($imapConnection, $query, false, $response, $message, $uid_support); + } + + if (strtoupper($response) != 'OK') { +// 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 ') { + $messagelist = preg_split("/ /", substr($readin_part, 7)); + break; // Should be the last anyway + } + } + + 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; +} + +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(); + + global $uid_support; + + 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, $uid_support); + + /* 6.4 try US-ASCII charset if we received a tagged NO response (SHOULD be [BADCHARSET]) */ + if (($search_charset != 'US-ASCII') && (strtoupper($response) == 'NO')) { + $query = 'THREAD ' . $thread_algorithm . ' US-ASCII ALL ' . $search_string; + s_debug_dump('C:', $query); + $readin = sqimap_run_command($imapConnection, $query, false, $response, $message, $uid_support); + } + + if (strtoupper($response) != 'OK') { +// 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 * 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; +} + function sqimap_asearch_get_charset() { global $allow_charset_search, $languages, $squirrelmail_language; @@ -310,6 +433,20 @@ function sqimap_asearch_get_charset() return ''; } +function sqimap_asearch_get_sort_criteria($mailbox, $sort_by) +{ + global $internal_date_sort, $sent_folder; + + $sort_opcodes = array ('DATE', 'FROM', 'SUBJECT'); + if ($internal_date_sort == true) + $sort_opcodes[0] = 'ARRIVAL'; +// if (handleAsSent($mailbox)) +// if (isSentFolder($mailbox)) + if ($mailbox == $sent_folder) + $sort_opcodes[1] = 'TO'; + return (($sort_by % 2) ? '' : 'REVERSE ') . $sort_opcodes[$sort_by >> 1]; +} + /* replaces $mbox_msgs[$search_mailbox] = array_values(array_unique(array_merge($mbox_msgs[$search_mailbox], sqimap_run_search($imapConnection, $search_string, $search_charset))));*/ function sqimap_array_merge_unique($to, $from) { @@ -324,6 +461,9 @@ function sqimap_array_merge_unique($to, $from) function sqimap_asearch($imapConnection, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $mboxes_array) { + global $allow_server_sort, $sort, $allow_thread_sort, $thread_sort_messages; + global $data_dir, $username; + $search_charset = sqimap_asearch_get_charset(); $mbox_msgs = array(); $search_string = ''; @@ -342,14 +482,26 @@ function sqimap_asearch($imapConnection, $mailbox_array, $biop_array, $unop_arra 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) { + $thread_algorithm = 'REFERENCES'; + $found_msgs = sqimap_run_thread($imapConnection, $search_string, $search_charset, $thread_algorithm); + } + 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], sqimap_run_search($imapConnection, $search_string, $search_charset)); + $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(sqimap_run_search($imapConnection, $search_string, $search_charset), $mbox_msgs[$cur_mailbox])); + $mbox_msgs[$cur_mailbox] = array_values(array_intersect($found_msgs, $mbox_msgs[$cur_mailbox])); } else /* No previous results */ - $mbox_msgs[$cur_mailbox] = sqimap_run_search($imapConnection, $search_string, $search_charset); + $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]); } diff --git a/src/search.php b/src/search.php index a7f2f004..5e63fe67 100644 --- a/src/search.php +++ b/src/search.php @@ -189,7 +189,7 @@ function asearch_forget_recent($data_dir, $username, $forget_index) asearch_write_recent($data_dir, $username, $recent_array); } -function asearch_recent_exists($recent_array, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array) +function asearch_find_recent($recent_array, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array) { global $recent_prefkeys; @@ -210,10 +210,10 @@ function asearch_recent_exists($recent_array, $mailbox_array, $biop_array, $unop $what_string == $recent_array['asearch_recent_what'][$recent_num] && $exclude_string == $recent_array['asearch_recent_exclude'][$recent_num] ) - return TRUE; + return $recent_num; } } - return FALSE; + return -1; } /* push a recent search */ @@ -224,15 +224,19 @@ function asearch_push_recent($data_dir, $username, $mailbox_array, $biop_array, $recent_max = getPref($data_dir, $username, 'search_memory', 0); if ($recent_max > 0) { $recent_array = asearch_read_recent($data_dir, $username); - if (!asearch_recent_exists($recent_array, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array)) { - $input = array($where_array, $mailbox_array, $what_array, $biop_array, $unop_array, $exclude_array); - $i = 0; + $recent_found = asearch_find_recent($recent_array, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array); + if ($recent_found >= 0) { // Remove identical recent foreach ($recent_prefkeys as $key) { - array_unshift($recent_array[$key], asearch_serialize($input[$i])); - $i++; + array_splice($recent_array[$key], $recent_found, 1); } - asearch_write_recent($data_dir, $username, $recent_array); - } + } + $input = array($where_array, $mailbox_array, $what_array, $biop_array, $unop_array, $exclude_array); + $i = 0; + foreach ($recent_prefkeys as $key) { + array_unshift($recent_array[$key], asearch_serialize($input[$i])); + $i++; + } + asearch_write_recent($data_dir, $username, $recent_array); } } @@ -571,22 +575,36 @@ function asearch_print_form($imapConnection, $boxes, $mailbox_array, $biop_array /* print the $msgs messages from $mailbox mailbox */ /* this is almost the original code */ -function asearch_print_mailbox_msgs($msgs, $mailbox, $cnt, $imapConnection, $where, $what, $usecache = false, $newsort = false) +function asearch_print_mailbox_msgs($imapConnection, $mailbox, $msgs, $cnt, $sort, $color, $where, $what) { - global $sort, $color; - if ($cnt > 0) { - $msort = calc_msort($msgs, $sort); - $showbox = asearch_get_mailbox_display($mailbox); - echo html_tag('div', '' . _("Folder:") . ' '. $showbox.'','center') . "\n"; + global $allow_server_sort, $allow_thread_sort, $thread_sort_messages; + + $thread_sort_messages = 0; + if ($allow_thread_sort) { + global $data_dir, $username; + $thread_sort_messages = getPref($data_dir, $username, 'thread_' . $mailbox); + $msort = $msgs; + $real_sort = 6; + } + elseif ($allow_server_sort) { + $msort = $msgs; + $real_sort = 6; + } + else { + $msort = calc_msort($msgs, $sort); + $real_sort = $sort; + } + $mailbox_display = asearch_get_mailbox_display($mailbox); + echo html_tag('div', '' . _("Folder:") . ' '. $mailbox_display . '','center') . "\n"; $msg_cnt_str = get_msgcnt_str(1, $cnt, $cnt); - $toggle_all = get_selectall_link(1, $sort); + $toggle_all = get_selectall_link(1, $real_sort); echo ''; echo ''; echo ''; @@ -597,8 +615,8 @@ function asearch_print_mailbox_msgs($msgs, $mailbox, $cnt, $imapConnection, $whe echo '
'; - mail_message_listing_beginning($imapConnection, $mailbox, $sort, $msg_cnt_str, $toggle_all, 1); + mail_message_listing_beginning($imapConnection, $mailbox, $real_sort, $msg_cnt_str, $toggle_all, 1); echo '
'; echo ' '; echo '
'; - printHeader($mailbox, 6, $color, false); - displayMessageArray($imapConnection, $cnt, 1, $msort, $mailbox, $sort, $color, $cnt, $where, $what); + printHeader($mailbox, $sort, $color, !$thread_sort_messages); + displayMessageArray($imapConnection, $cnt, 1, $msort, $mailbox, $real_sort, $color, $cnt, $where, $what); echo '
'; echo ' '; @@ -611,8 +629,6 @@ function asearch_print_mailbox_msgs($msgs, $mailbox, $cnt, $imapConnection, $whe } /* ------------------------ main ------------------------ */ -global $allow_thread_sort; - /* get globals we may need */ sqgetGlobalVar('username', $username, SQ_SESSION); sqgetGlobalVar('key', $key, SQ_COOKIE); @@ -753,8 +769,21 @@ else $exclude_array = array(); /* Used by recent and saved stuff */ -if (isset($_GET['rownum'])) { +if (isset($_GET['rownum'])) $submit_rownum = strip_tags($_GET['rownum']); + +/* Change global sort */ +if (sqgetGlobalVar('newsort', $newsort, SQ_GET)) { + setPref($data_dir, $username, 'sort', $newsort); + $sort = $newsort; + sqsession_register($sort, 'sort'); + asearch_edit_last($data_dir, $username); +} + +/* Change mailbox threading */ +if (sqgetGlobalVar('set_thread', $set_thread, SQ_GET)) { + setPref($data_dir, $username, 'thread_' . $mailbox_array[0], ($set_thread == 1) ? 1 : 0 ); + asearch_edit_last($data_dir, $username); } /* end of get globals */ @@ -810,7 +839,9 @@ else { break; case 'search_recent': $submit = $search_button_text; - /*nobreak;*/ + asearch_edit_recent($data_dir, $username, $submit_rownum); + asearch_push_recent($data_dir, $username, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array); + break; case 'edit_recent': /* no link to do this, yet */ asearch_edit_recent($data_dir, $username, $submit_rownum); break; @@ -819,7 +850,9 @@ else { break; case 'search_saved': $submit = $search_button_text; - /*nobreak;*/ + asearch_edit_saved($data_dir, $username, $submit_rownum); + asearch_push_recent($data_dir, $username, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array); + break; case 'edit_saved': asearch_edit_saved($data_dir, $username, $submit_rownum); break; @@ -876,12 +909,6 @@ if (!$search_silent) { asearch_print_form($imapConnection, $boxes, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array); } -/* This deserves a comment, at least. What is it for exactly? */ -if (isset($newsort)) { - $sort = $newsort; - sqsession_register($sort, 'sort'); -} - /********************************************************************* * Check to see if we can use cache or not. Currently the only time * * when you will not use it is when a link on the left hand frame is * @@ -903,12 +930,11 @@ if ($submit == $search_button_text) { if ($query_error != '') echo '
' . html_tag('div', asearch_get_error_display($color, $query_error), 'center') . "\n"; else { - // Temporarily unset thread sort because it is meaningless in search results - $old_allow_thread_sort = FALSE; - if ($allow_thread_sort == TRUE) { - $old_allow_thread_sort = $allow_thread_sort; - $allow_thread_sort = FALSE; - } + + // Disable thread sort for now if there is more than one mailbox + global $allow_thread_sort; + $old_allow_thread_sort = $allow_thread_sort; + $allow_thread_sort = (count(array_unique($mailbox_array)) <= 1); $boxcount = count($boxes); for ($boxnum=0; $boxnum<$boxcount; $boxnum++) { @@ -928,11 +954,11 @@ if ($submit == $search_button_text) { $what = asearch_serialize($what_array);*/ $where = $where_array[0]; $what = $what_array[0]; - asearch_print_mailbox_msgs($msgs, $mailbox, count($msgs), $imapConnection, urlencode($where), urlencode($what), false, false); + asearch_print_mailbox_msgs($imapConnection, $mailbox, $msgs, count($msgs), $sort, $color, urlencode($where), urlencode($what)); } } - $allow_thread_sort = $old_allow_thread_sort; + $allow_thread_sort = $old_allow_thread_sort; // Restore thread sort } } -- 2.25.1