Roundcube Community Forum

 

Address auto-complete too aggressive

Started by ABerglund, October 28, 2009, 04:26:15 PM

Previous topic - Next topic

ABerglund

Is there a way to make the address auto-complete search only look for matches from the beginning of the strings? The current function is too aggressive in its matching. For example, if you have an address in your address book of '[email protected]' and you start with 'com' it returns every address that ENDS in '.com'.

I know of no other client with an auto-complete that searches for matches within the middle of the strings, all others that I have seen search from the beginning of the string only, and IMO that's what RC should do as well.

If this is possible to fix locally with a patch or with a small edit to a .js file, that would be fine also.
Arne Berglund
SysAdmin, Internet Services
Lane Education Service District
Eugene, OR, USA

corbosman

Apple mail works just like RC. So at least one other client does this. Probably many more.

ABerglund

Actually, it doesn't, at least not in Snow Leopard. I have entries in my Apple address book for last names of 'Sanow' and 'Moisant'. In Apple Mail if I enter 'san" the only address it fills is 'Sanow', because it searches from the beginning of the string.

But in RC for example, entering 'san' pulls up addresses like 'username@pleasanthill.k12.xx.us'. It would be far better in my opinion if it also only began at the beginning of strings for searching.
Arne Berglund
SysAdmin, Internet Services
Lane Education Service District
Eugene, OR, USA

SKaero

I think that its a good feature, but it could use a on/off switch. My Apple Mail in Leopard doesn't do it.

ABerglund

I suspect the file that would need to be changed is program/steps/mail/autocomplete.inc

It appears to be a fairly simple routine, but I don't see how to make it search from the beginning of strings (as I'd do with a ^ in Perl or grep).
Arne Berglund
SysAdmin, Internet Services
Lane Education Service District
Eugene, OR, USA

SKaero

I looked into this and found a very easy fix O0!
Open your [RC root]/program/include/rcube_contacts.php file and find:
$add_where[] = $this->db->ilike($col'%'.$value.'%');
Replace with:
$add_where[] = $this->db->ilike($col$value.'%');
That should do it!

rosali

./program/include/rcube_contacts.php:


  
/**
   * Search contacts
   *
   * @param array   List of fields to search in
   * @param string  Search value
   * @param boolean True if results are requested, False if count only
   * @return Indexed list of contact records and 'count' value
   */
  
function search($fields$value$strict=false$select=true)
  {
    if (!
is_array($fields))
      
$fields = array($fields);
      
    
$add_where = array();
    foreach (
$fields as $col)
    {
      if (
$col == 'ID' || $col == $this->primary_key)
      {
        
$ids = !is_array($value) ? explode(','$value) : $value;
        
$add_where[] = $this->primary_key.' IN ('.join(','$ids).')';
      }
      else if (
$strict)
        
$add_where[] = $this->db->quoteIdentifier($col).'='.$this->db->quote($value);
      else
        
//$add_where[] = $this->db->ilike($col, '%'.$value.'%');
        
$add_where[] = $this->db->ilike($col$value.'%');
    }
    
    if (!empty(
$add_where))
    {
      
$this->set_search_set(join(' OR '$add_where));
      if (
$select)
        
$this->list_records();
      else
        
$this->result $this->count();
    }
   
    return 
$this->result
  }



... see the commented line. I think that's what you are looking for.
Regards,
Rosali

ABerglund

Quote from: skaero;22697I looked into this and found a very easy fix O0!
Open your [RC root]/program/include/rcube_contacts.php file and find:
$add_where[] = $this->db->ilike($col'%'.$value.'%');
Replace with:
$add_where[] = $this->db->ilike($col$value.'%');
That should do it!
That's definitely an improvement, although still not quite what I'd really like. It now searches only from the beginning of the string, but only searches within the "Display name" and 'Address" columns. That's good, But I'd like to make it search the "Last name' field as well. Now that I know where the code for the search really lives, I'll look at it a but closer myself too.
Arne Berglund
SysAdmin, Internet Services
Lane Education Service District
Eugene, OR, USA

SKaero

Open your [RC root]/program/steps/mail/autocomplete.inc file and find:
if ($result $abook->search(array('email','name'), $search)) {
Replace with:
if ($result $abook->search(array('email','firstname','surname'), $search)) {

giclyzhy

Good work !
Very cool, looking great so far. Keep going, I wanna see it finished!:o

ABerglund

Quote from: skaero;22732Open your [RC root]/program/steps/mail/autocomplete.inc file and find:
if ($result $abook->search(array('email','name'), $search)) {
Replace with:
if ($result $abook->search(array('email','firstname','surname'), $search)) {
Perfect! That's exactly what we were looking for. Thank you!!
Arne Berglund
SysAdmin, Internet Services
Lane Education Service District
Eugene, OR, USA

steveprecision

Quote from: skaero;22589I think that its a good feature, but it could use a on/off switch. My Apple Mail in Leopard doesn't do it.


Yes same here

ABerglund

Quote from: skaero;22697I looked into this and found a very easy fix O0!
Open your [RC root]/program/include/rcube_contacts.php file and find:
$add_where[] = $this->db->ilike($col'%'.$value.'%');
Replace with:
$add_where[] = $this->db->ilike($col$value.'%');
That should do it!
OK, so now I've added an LDAP global book to the autocomplete search, and the LDAP book still searches for matches in the middle of the string. This change works perfectly on the SQL book, but does not seem to work on the LDAP searches. Is there any way to change this behavior as well?
Arne Berglund
SysAdmin, Internet Services
Lane Education Service District
Eugene, OR, USA

serpico7456

Quote from: ABerglund;24845the LDAP book still searches for matches in the middle of the string. This change ... does not seem to work on the LDAP searches. Is there any way to change this behavior as well?

Here is a solution I posted to the users mailing list (v 0.3.1). This will
mimic the results of popular email clients like, mail.app, thunderbird, gmail, outlook, and others:

--- rcube_ldap.php.orig 2010-03-17 15:48:38.000000000 -0500
+++ rcube_ldap.php 2010-03-17 15:50:26.000000000 -0500
@@ -325,13 +325,13 @@
     if (is_array($this->prop['search_fields']))
     {
       foreach ($this->prop['search_fields'] as $k => $field)
-        $filter .= "($field=$wc" . rcube_ldap::quote_string($value) . "$wc)";
+        $filter .= "($field=" . rcube_ldap::quote_string($value) . "$wc)";
     }
     else
     {
       foreach ((array)$fields as $field)
         if ($f = $this->_map_field($field))
-          $filter .= "($f=$wc" . rcube_ldap::quote_string($value) . "$wc)";
+          $filter .= "($f=" . rcube_ldap::quote_string($value) . "$wc)";
     }
     $filter .= ')';