summaryrefslogtreecommitdiff
path: root/program/lib/Roundcube
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2015-03-03 14:53:02 +0100
committerThomas Bruederli <bruederli@kolabsys.com>2015-03-03 14:53:02 +0100
commit36ee2c8427298fc8735fe547d11c7e203fb3ca99 (patch)
tree5bfdf6b6633600355df25caf1ceab996716d4d61 /program/lib/Roundcube
parent83eeec6c0665ff18881ba05743b7368f9fb1c2f7 (diff)
Improve LDAP search by ignoring words order in fuzzy substring matching mode
Diffstat (limited to 'program/lib/Roundcube')
-rw-r--r--program/lib/Roundcube/rcube_ldap.php66
-rw-r--r--program/lib/Roundcube/rcube_ldap_generic.php5
2 files changed, 44 insertions, 27 deletions
diff --git a/program/lib/Roundcube/rcube_ldap.php b/program/lib/Roundcube/rcube_ldap.php
index 87dcb2bf9..aad0090f8 100644
--- a/program/lib/Roundcube/rcube_ldap.php
+++ b/program/lib/Roundcube/rcube_ldap.php
@@ -792,33 +792,24 @@ class rcube_ldap extends rcube_addressbook
return $this->result;
}
- // use AND operator for advanced searches
- $filter = is_array($value) ? '(&' : '(|';
- // set wildcards
- $wp = $ws = '';
- if (!empty($this->prop['fuzzy_search']) && $mode != 1) {
- $ws = '*';
- if (!$mode) {
- $wp = '*';
- }
- }
-
- if ($fields == '*') {
- // search_fields are required for fulltext search
- if (empty($this->prop['search_fields'])) {
- $this->set_error(self::ERROR_SEARCH, 'nofulltextsearch');
- $this->result = new rcube_result_set();
- return $this->result;
- }
- if (is_array($this->prop['search_fields'])) {
- foreach ($this->prop['search_fields'] as $field) {
- $filter .= "($field=$wp" . rcube_ldap_generic::quote_string($value) . "$ws)";
+ // advanced per-attribute search
+ if (is_array($value)) {
+ // use AND operator for advanced searches
+ $filter = '(&';
+
+ // set wildcards
+ $wp = $ws = '';
+ if (!empty($this->prop['fuzzy_search']) && $mode != 1) {
+ $ws = '*';
+ if (!$mode) {
+ $wp = '*';
}
}
- }
- else {
+
foreach ((array)$fields as $idx => $field) {
- $val = is_array($value) ? $value[$idx] : $value;
+ $val = $value[$idx];
+ if (!strlen($val))
+ continue;
if ($attrs = $this->_map_field($field)) {
if (count($attrs) > 1)
$filter .= '(|';
@@ -828,8 +819,33 @@ class rcube_ldap extends rcube_addressbook
$filter .= ')';
}
}
+
+ $filter .= ')';
+ }
+ else {
+ if ($fields == '*') {
+ // search_fields are required for fulltext search
+ if (empty($this->prop['search_fields'])) {
+ $this->set_error(self::ERROR_SEARCH, 'nofulltextsearch');
+ $this->result = new rcube_result_set();
+ return $this->result;
+ }
+ $attributes = (array)$this->prop['search_fields'];
+ }
+ else {
+ // map address book fields into ldap attributes
+ $me = $this;
+ $attributes = array();
+ array_walk($fields, function($field) use ($me, &$attributes) {
+ if ($this->coltypes[$field] && ($attrs = (array)$this->coltypes[$field]['attributes'])) {
+ $attributes = array_merge($attributes, $attrs);
+ }
+ });
+ }
+
+ // compose a full-text-like search filter
+ $filter = rcube_ldap_generic::fulltext_search_filter($value, $attributes, $mode);
}
- $filter .= ')';
// add required (non empty) fields filter
$req_filter = '';
diff --git a/program/lib/Roundcube/rcube_ldap_generic.php b/program/lib/Roundcube/rcube_ldap_generic.php
index 40adbedbe..abe16760d 100644
--- a/program/lib/Roundcube/rcube_ldap_generic.php
+++ b/program/lib/Roundcube/rcube_ldap_generic.php
@@ -336,7 +336,8 @@ class rcube_ldap_generic extends Net_LDAP3
}
$groups = array();
- $words = rcube_utils::tokenize_string($value, 1);
+ $value = str_replace('*', '', $value);
+ $words = $mode == 0 ? rcube_utils::tokenize_string($value, 1) : array($value);
// set wildcards
$wp = $ws = '';
@@ -354,7 +355,7 @@ class rcube_ldap_generic extends Net_LDAP3
$groups[] = '(|' . join('', $parts) . ')';
}
- return empty($groups) ? '' : '(&' . join('', $groups) . ')';
+ return count($groups) > 1 ? '(&' . join('', $groups) . ')' : join('', $groups);
}
}