Changeset 2049 in subversion


Ignore:
Timestamp:
Nov 13, 2008 5:30:06 AM (5 years ago)
Author:
alec
Message:
  • Added message status filter + fixes for r2046 (searching with SORT)
Location:
trunk/roundcubemail
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/CHANGELOG

    r2046 r2049  
    55---------- 
    66- Use SORT for searching on servers with SORT capability 
     7- Added message status filter 
    78 
    892008/11/06 (alec) 
  • trunk/roundcubemail/program/include/rcube_imap.php

    r2046 r2049  
    6262  var $skip_deleted = FALSE; 
    6363  var $search_set = NULL; 
    64   var $search_subject = ''; 
    6564  var $search_string = ''; 
    6665  var $search_charset = ''; 
     
    283282   * Save a set of message ids for future message listing methods 
    284283   * 
    285    * @param  array  List of IMAP fields to search in 
    286    * @param  string Search string 
    287    * @param  array  List of message ids or NULL if empty 
    288    */ 
    289   function set_search_set($subject, $str=null, $msgs=null, $charset=null, $sort_field=null) 
    290     { 
    291     if (is_array($subject) && $str == null && $msgs == null) 
    292       list($subject, $str, $msgs, $charset, $sort_field) = $subject; 
     284   * @param  string  IMAP Search query 
     285   * @param  array   List of message ids or NULL if empty 
     286   * @param  string  Charset of search string 
     287   * @param  string  Sorting field 
     288   */ 
     289  function set_search_set($str=null, $msgs=null, $charset=null, $sort_field=null) 
     290    { 
     291    if ($msgs == null) 
     292      list($str, $msgs, $charset, $sort_field) = $str; 
    293293    if ($msgs != null && !is_array($msgs)) 
    294294      $msgs = split(',', $msgs); 
    295295       
    296     $this->search_subject = $subject; 
    297296    $this->search_string = $str; 
    298297    $this->search_set = (array)$msgs; 
     
    308307  function get_search_set() 
    309308    { 
    310     return array($this->search_subject, $this->search_string, $this->search_set, $this->search_charset, $this->search_sort_field); 
     309    return array($this->search_string, $this->search_set, $this->search_charset, $this->search_sort_field); 
    311310    } 
    312311 
     
    655654      { 
    656655      // reset search set if sorting field has been changed 
    657       if ($sort_field && $this->search_sort_field != $sort_field) 
    658         { 
    659         $msgs = $this->search('', $this->search_subject, $this->search_string, $this->search_charset, $sort_field); 
     656      if ($this->sort_field && $this->search_sort_field != $this->sort_field) 
     657        { 
     658        $msgs = $this->search('', $this->search_string, $this->search_charset, $this->sort_field); 
    660659        } 
    661660 
     
    784783   
    785784  /** 
    786    * Return sorted array of message UIDs 
     785   * Return sorted array of message IDs (not UIDs) 
    787786   * 
    788787   * @param string Mailbox to get index from 
     
    802801    { 
    803802      $this->cache[$key] = $a_msg_headers = array(); 
    804       $this->_fetch_headers($mailbox, join(',', $this->search_set), $a_msg_headers, NULL); 
    805  
    806       foreach (iil_SortHeaders($a_msg_headers, $this->sort_field, $this->sort_order) as $i => $msg) 
    807         $this->cache[$key][] = $msg->uid; 
     803       
     804      if ($this->get_capability('sort')) 
     805        { 
     806        if ($this->sort_field && $this->search_sort_field != $this->sort_field) 
     807          $this->search('', $this->search_string, $this->search_charset, $this->sort_field); 
     808 
     809        if ($this->sort_order == 'DESC') 
     810          $this->cache[$key] = array_reverse($this->search_set); 
     811        else 
     812          $this->cache[$key] = $this->search_set; 
     813        } 
     814      else 
     815        { 
     816        // TODO: see list_header_set (fetch only one header field needed for sorting) 
     817        $this->_fetch_headers($mailbox, join(',', $this->search_set), $a_msg_headers, NULL); 
     818 
     819        foreach (iil_SortHeaders($a_msg_headers, $this->sort_field, $this->sort_order) as $i => $msg) 
     820          $this->cache[$key][] = $msg->id; 
     821        } 
    808822    } 
    809823 
     
    826840    // fetch complete message index 
    827841    $msg_count = $this->_messagecount($mailbox); 
    828     if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, '', TRUE))) 
     842    if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, ''))) 
    829843      { 
    830844      if ($this->sort_order == 'DESC') 
     
    832846 
    833847      $this->cache[$key] = $a_index; 
    834  
    835848      } 
    836849    else 
    837850      { 
    838851      $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:$msg_count", $this->sort_field); 
    839       $a_uids = iil_C_FetchUIDs($this->conn, $mailbox); 
    840      
     852 
    841853      if ($this->sort_order=="ASC") 
    842854        asort($a_index); 
     
    844856        arsort($a_index); 
    845857         
    846       $i = 0; 
    847       $this->cache[$key] = array(); 
    848       foreach ($a_index as $index => $value) 
    849         $this->cache[$key][$i++] = $a_uids[$index]; 
     858      $this->cache[$key] = $a_index; 
    850859      } 
    851860 
     
    907916   * 
    908917   * @param  string  mailbox name to search in 
    909    * @param  string  search criteria (ALL, TO, FROM, SUBJECT, etc) 
    910918   * @param  string  search string 
    911919   * @param  string  search string charset 
     
    914922   * @access public 
    915923   */ 
    916   function search($mbox_name='', $criteria='ALL', $str=NULL, $charset=NULL, $sort_field=NULL) 
     924  function search($mbox_name='', $str=NULL, $charset=NULL, $sort_field=NULL) 
    917925    { 
    918926    $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox; 
    919     $search = ''; 
    920  
    921     // have an array of criterias => create search string 
    922     if (is_array($criteria) && count($criteria) > 1) 
    923       $search .= 'OR'; 
    924  
    925     $criteria = (array) $criteria; 
    926     foreach($criteria as $idx => $crit) 
    927       if ($str) 
    928         $search .= sprintf(" (%s {%d}\r\n%s)", $crit, strlen($str), $str); 
    929       else 
    930         $search .= '('. $crit .')'; 
    931  
    932     $results = $this->_search_index($mailbox, $search, $charset, $sort_field); 
     927 
     928    $results = $this->_search_index($mailbox, $str, $charset, $sort_field); 
    933929 
    934930    // try search with ISO charset (should be supported by server) 
    935931    if (empty($results) && !empty($charset) && $charset!='ISO-8859-1') 
    936       $results = $this->search($mbox_name, $criteria, rcube_charset_convert($str, $charset, 'ISO-8859-1'), 'ISO-8859-1', $sort_field); 
    937  
    938     $this->set_search_set($criteria, $str, $results, $charset, $sort_field); 
     932      { 
     933        // convert strings to ISO-8859-1 
     934        if(preg_match_all('/\{([0-9]+)\}\r\n/', $str, $matches, PREG_OFFSET_CAPTURE)) 
     935          { 
     936          $last = 0; $res = ''; 
     937          foreach($matches[1] as $m) 
     938            { 
     939            $string_offset = $m[1] + strlen($m[0]) + 4; // {}\r\n 
     940            $string = substr($str, $string_offset - 1, $m[0]); 
     941            $string = rcube_charset_convert($string, $charset, 'ISO-8859-1'); 
     942            $res .= sprintf("%s{%d}\r\n%s", substr($str, $last, $m[1] - $last - 1), strlen($string), $string); 
     943            $last = $m[0] + $string_offset - 1; 
     944            } 
     945            if ($last < strlen($str)) 
     946              $res .= substr($str, $last, strlen($str)-$last); 
     947          } 
     948        else // strings for conversion not found 
     949          $res = $str; 
     950           
     951        $results = $this->search($mbox_name, $res, 'ISO-8859-1', $sort_field); 
     952      } 
     953 
     954    $this->set_search_set($str, $results, $charset, $sort_field); 
    939955 
    940956    return $results; 
    941     }     
     957    } 
    942958 
    943959 
     
    975991  function refresh_search() 
    976992    { 
    977     if (!empty($this->search_subject) && !empty($this->search_string)) 
    978       $this->search_set = $this->search('', $this->search_subject, $this->search_string, $this->search_charset, $this->search_sort_field); 
     993    if (!empty($this->search_string)) 
     994      $this->search_set = $this->search('', $this->search_string, $this->search_charset, $this->search_sort_field); 
    979995       
    980996    return $this->get_search_set(); 
  • trunk/roundcubemail/program/js/app.js

    r2040 r2049  
    267267        this.set_page_buttons(); 
    268268         
    269         if (this.env.address_sources && !this.env.address_sources[this.env.source].readonly) 
     269        if (this.env.address_sources && this.env.address_sources[this.env.source] && !this.env.address_sources[this.env.source].readonly) 
    270270          this.enable_command('add', true); 
    271271         
     
    14151415    }; 
    14161416 
     1417  // list messages of a specific mailbox using filter 
     1418  this.filter_mailbox = function(filter) 
     1419    { 
     1420      var search; 
     1421      if (this.gui_objects.qsearchbox) 
     1422        search = this.gui_objects.qsearchbox.value; 
     1423       
     1424      this.message_list.clear(); 
     1425 
     1426      // reset vars 
     1427      this.env.current_page = 1; 
     1428      this.set_busy(true, 'searching'); 
     1429      this.http_request('search', '_filter='+filter 
     1430            + (search ? '&_q='+urlencode(search) : '') 
     1431            + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : ''), true); 
     1432    } 
     1433 
     1434 
    14171435  // list messages of a specific mailbox 
    14181436  this.list_mailbox = function(mbox, page, sort) 
     
    22842302 
    22852303  // send remote request to search mail or contacts 
    2286   this.qsearch = function(value) 
     2304  this.qsearch = function(value, addurl) 
    22872305    { 
    22882306    if (value != '') 
     
    22932311        this.contact_list.clear(true); 
    22942312        this.show_contentframe(false); 
    2295       } 
     2313        } 
     2314 
     2315      if (this.gui_objects.search_filter) 
     2316        addurl = '&_filter=' + this.gui_objects.search_filter.value; 
    22962317 
    22972318      // reset vars 
    22982319      this.env.current_page = 1; 
    22992320      this.set_busy(true, 'searching'); 
    2300       this.http_request('search', '_q='+urlencode(value)+(this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : '')+(this.env.source ? '&_source='+urlencode(this.env.source) : ''), true); 
     2321      this.http_request('search', '_q='+urlencode(value) 
     2322            +(this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : '') 
     2323            +(this.env.source ? '&_source='+urlencode(this.env.source) : '') 
     2324            +(addurl ? addurl : ''), true); 
    23012325      } 
    23022326    return true; 
  • trunk/roundcubemail/program/steps/mail/func.inc

    r2047 r2049  
    12931293 
    12941294 
     1295function rcmail_search_filter($attrib) 
     1296{ 
     1297  global $OUTPUT; 
     1298 
     1299  if (!strlen($attrib['id'])) 
     1300    $attrib['id'] = 'rcmlistfilter'; 
     1301 
     1302  $attrib['onchange'] = JS_OBJECT_NAME.'.filter_mailbox(this.value)'; 
     1303   
     1304  /* 
     1305    RFC3501 (6.4.4): 'ALL', 'RECENT',  
     1306    'ANSWERED', 'DELETED', 'FLAGGED', 'SEEN', 
     1307    'UNANSWERED', 'UNDELETED', 'UNFLAGGED', 'UNSEEN', 
     1308    'NEW', // = (RECENT UNSEEN) 
     1309    'OLD' // = NOT RECENT 
     1310  */ 
     1311 
     1312  $select_filter = new html_select($attrib); 
     1313  $select_filter->add(rcube_label('all'), 'ALL'); 
     1314  $select_filter->add(rcube_label('unread'), 'UNSEEN'); 
     1315  $select_filter->add(rcube_label('flagged'), 'FLAGGED'); 
     1316  $select_filter->add(rcube_label('unanswered'), 'UNANSWERED'); 
     1317 
     1318  $out = $select_filter->show($_SESSION['search_filter']); 
     1319 
     1320  $OUTPUT->add_gui_object('search_filter', $attrib['id']); 
     1321 
     1322  return $out;                                                                           
     1323} 
     1324 
    12951325// register UI objects 
    12961326$OUTPUT->add_handlers(array( 
     
    13051335  'messagepartframe' => 'rcmail_message_part_frame', 
    13061336  'messagepartcontrols' => 'rcmail_message_part_controls', 
     1337  'searchfilter' => 'rcmail_search_filter', 
    13071338  'searchform' => array($OUTPUT, 'search_form'), 
    13081339)); 
  • trunk/roundcubemail/program/steps/mail/list.inc

    r1748 r2049  
    4242$mbox_name = $IMAP->get_mailbox_name(); 
    4343 
     44// initialize searching result if search_filter is used 
     45if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') 
     46{ 
     47  $search_request = md5($mbox_name.$_SESSION['search_filter']); 
     48 
     49  $IMAP->search($mbox_name, $_SESSION['search_filter'], RCMAIL_CHARSET, $sort_col); 
     50  $_SESSION['search'][$search_request] = $IMAP->get_search_set(); 
     51  $OUTPUT->set_env('search_request', $search_request); 
     52} 
     53                               
     54 
    4455// fetch message headers 
    4556if ($IMAP->messagecount($mbox_name, 'ALL', !empty($_REQUEST['_refresh']))) 
     
    5667$OUTPUT->command('set_mailboxname', rcmail_get_mailbox_name_text()); 
    5768 
    58  
    59  
    6069// add message rows 
    6170if (isset($a_headers) && count($a_headers)) 
  • trunk/roundcubemail/program/steps/mail/search.inc

    r2046 r2049  
    2727// get search string 
    2828$str = get_input_value('_q', RCUBE_INPUT_GET); 
     29$filter = get_input_value('_filter', RCUBE_INPUT_GET); 
    2930$mbox = get_input_value('_mbox', RCUBE_INPUT_GET); 
    30 $search_request = md5($mbox.$str); 
     31$search_request = md5($mbox.$filter.$str); 
    3132 
     33// add list filter string 
     34$search_str = $filter && $filter != 'ALL' ? $filter : ''; 
     35 
     36$_SESSION['search_filter'] = $filter; 
    3237 
    3338// Check the search string for type of search 
    34 if (preg_match("/^from:/i", $str)) 
     39if (preg_match("/^from:.*/i", $str)) 
    3540{ 
    3641  list(,$srch) = explode(":", $str); 
    37   $subject =  "HEADER FROM"; 
     42  $subject = "HEADER FROM"; 
    3843  $search = trim($srch); 
    3944} 
    40 else if (preg_match("/^to:/i", $str)) 
     45else if (preg_match("/^to.*:/i", $str)) 
    4146{ 
    4247  list(,$srch) = explode(":", $str); 
     
    4449  $search = trim($srch); 
    4550} 
    46 else if (preg_match("/^cc:/i", $str)) 
     51else if (preg_match("/^cc:.*/i", $str)) 
    4752{ 
    4853  list(,$srch) = explode(":", $str); 
     
    5055  $search = trim($srch); 
    5156} 
    52 else if (preg_match("/^subject:/i", $str)) 
     57else if (preg_match("/^subject:.*/i", $str)) 
    5358{ 
    5459  list(,$srch) = explode(":", $str); 
     
    5661  $search = trim($srch); 
    5762} 
    58 else if (preg_match("/^body:/i", $str)) 
     63else if (preg_match("/^body:.*/i", $str)) 
    5964{ 
    6065  list(,$srch) = explode(":", $str); 
     
    6368} 
    6469// search in subject and sender by default 
    65 else 
     70else if(trim($str)) 
    6671{ 
    6772  $from = ($mbox == $CONFIG['sent_mbox'] || $mbox == $CONFIG['drafts_mbox']) ? "TO" : "FROM"; 
     
    7075} 
    7176 
     77if ($subject && !is_array($subject)) 
     78  $search_str .= sprintf(" %s {%d}\r\n%s", $subject, strlen($search), $search); 
     79else if ($subject) { 
     80  $search_str .= ' OR'; 
     81  foreach($subject as $sub) 
     82    $search_str .= sprintf(" (%s {%d}\r\n%s)", $sub, strlen($search), $search); 
     83} 
     84 
     85$search_str = trim($search_str); 
     86 
    7287// execute IMAP search 
    73 $result = $IMAP->search($mbox, $subject, $search, $imap_charset, $_SESSION['sort_col']); 
     88$result = $IMAP->search($mbox, $search_str, $imap_charset, $_SESSION['sort_col']); 
    7489$count = 0; 
    7590 
  • trunk/roundcubemail/program/steps/mail/show.inc

    r2010 r2049  
    111111    // Only if we use custom sorting 
    112112    $a_msg_index = $IMAP->message_index(NULL, $_SESSION['sort_col'], $_SESSION['sort_order']); 
    113   
    114     $MESSAGE->index = array_search((string)$MESSAGE->uid, $a_msg_index, TRUE); 
    115     $prev = isset($a_msg_index[$MESSAGE->index-1]) ? $a_msg_index[$MESSAGE->index-1] : -1 ; 
    116     $first = count($a_msg_index)>0 ? $a_msg_index[0] : -1; 
    117     $next = isset($a_msg_index[$MESSAGE->index+1]) ? $a_msg_index[$MESSAGE->index+1] : -1 ; 
    118     $last = count($a_msg_index)>0 ? $a_msg_index[count($a_msg_index)-1] : -1; 
     113 
     114    $MESSAGE->index = array_search($IMAP->get_id($MESSAGE->uid), $a_msg_index); 
     115 
     116    $prev = isset($a_msg_index[$MESSAGE->index-1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index-1]) : -1 ; 
     117    $first = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[0]) : -1; 
     118    $next = isset($a_msg_index[$MESSAGE->index+1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index+1]) : -1 ; 
     119    $last = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[count($a_msg_index)-1]) : -1; 
    119120    } 
    120121  else 
     
    131132  if ($prev > 0) 
    132133    $OUTPUT->set_env('prev_uid', $prev); 
    133   if ($first >0) 
     134  if ($first > 0) 
    134135    $OUTPUT->set_env('first_uid', $first); 
    135136  if ($next > 0) 
    136137    $OUTPUT->set_env('next_uid', $next); 
    137   if ($last >0) 
     138  if ($last > 0) 
    138139    $OUTPUT->set_env('last_uid', $last); 
    139140 
  • trunk/roundcubemail/skins/default/common.css

    r1966 r2049  
    329329{ 
    330330  position: absolute; 
    331   top: 60px; 
     331  top: 55px; 
    332332  right: 20px; 
    333333  width: 182px; 
  • trunk/roundcubemail/skins/default/mail.css

    r2042 r2049  
    55{ 
    66  position: absolute; 
    7   top: 45px; 
     7  top: 47px; 
    88  left: 200px; 
    99  right: 200px; 
     
    2525} 
    2626 
     27#messagetoolbar select.searchfilter 
     28{ 
     29  position: relative; 
     30  bottom: 10px; 
     31} 
     32 
    2733#messagetoolbar select.mboxlist 
    2834{ 
    2935  position: absolute; 
    3036  left: 375px; 
    31   top: 10px; 
     37  top: 8px; 
    3238} 
    3339 
  • trunk/roundcubemail/skins/default/templates/mail.html

    r2014 r2049  
    119119<roundcube:button command="delete" imageSel="/images/buttons/delete_sel.png" imageAct="/images/buttons/delete_act.png" imagePas="/images/buttons/delete_pas.png" width="32" height="32" title="deletemessage" /> 
    120120<roundcube:button command="print" imageSel="/images/buttons/print_sel.png" imageAct="/images/buttons/print_act.png" imagePas="/images/buttons/print_pas.png" width="32" height="32" title="printmessage" /> 
     121<roundcube:object name="searchfilter" id="searchfilter" class="searchfilter" /> 
    121122 
    122123<div id="markmessagemenu"> 
Note: See TracChangeset for help on using the changeset viewer.