Example #1
0
 /**
  * Search contacts
  *
  * @param array   List of fields to search in
  * @param string  Search value
  * @param boolean True for strict, False for partial (fuzzy) matching
  * @param boolean True if results are requested, False if count only
  * @return array  Indexed list of contact records and 'count' value
  */
 function search($fields, $value, $strict = false, $select = true)
 {
     // special treatment for ID-based search
     if ($fields == 'ID' || $fields == $this->primary_key) {
         $ids = explode(',', $value);
         $result = new rcube_result_set();
         foreach ($ids as $id) {
             if ($rec = $this->get_record($id, true)) {
                 $result->add($rec);
                 $result->count++;
             }
         }
         return $result;
     }
     $filter = '(|';
     $wc = !$strict && $this->prop['fuzzy_search'] ? '*' : '';
     if (is_array($this->prop['search_fields'])) {
         foreach ($this->prop['search_fields'] as $k => $field) {
             $filter .= "({$field}={$wc}" . 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 .= ')';
     // avoid double-wildcard if $value is empty
     $filter = preg_replace('/\\*+/', '*', $filter);
     // add general filter to query
     if (!empty($this->prop['filter'])) {
         $filter = '(&(' . preg_replace('/^\\(|\\)$/', '', $this->prop['filter']) . ')' . $filter . ')';
     }
     // set filter string and execute search
     $this->set_search_set($filter);
     $this->_exec_search();
     if ($select) {
         $this->list_records();
     } else {
         $this->result = $this->count();
     }
     return $this->result;
 }
Example #2
0
 /**
  * Search contacts
  *
  * @param mixed   $fields   The field name of array of field names to search in
  * @param mixed   $value    Search value (or array of values when $fields is array)
  * @param int     $mode     Matching mode:
  *                          0 - partial (*abc*),
  *                          1 - strict (=),
  *                          2 - prefix (abc*)
  * @param boolean $select   True if results are requested, False if count only
  * @param boolean $nocount  (Not used)
  * @param array   $required List of fields that cannot be empty
  *
  * @return array  Indexed list of contact records and 'count' value
  */
 function search($fields, $value, $mode = 0, $select = true, $nocount = false, $required = array())
 {
     $mode = intval($mode);
     // special treatment for ID-based search
     if ($fields == 'ID' || $fields == $this->primary_key) {
         $ids = !is_array($value) ? explode(',', $value) : $value;
         $result = new rcube_result_set();
         foreach ($ids as $id) {
             if ($rec = $this->get_record($id, true)) {
                 $result->add($rec);
                 $result->count++;
             }
         }
         return $result;
     }
     // use VLV pseudo-search for autocompletion
     $rcube = rcube::get_instance();
     $list_fields = $rcube->config->get('contactlist_fields');
     if ($this->prop['vlv_search'] && $this->ready && join(',', (array) $fields) == join(',', $list_fields)) {
         $this->result = new rcube_result_set(0);
         $search_suffix = $this->prop['fuzzy_search'] && $mode != 1 ? '*' : '';
         $ldap_data = $this->ldap->search($this->base_dn, $this->prop['filter'], $this->prop['scope'], $this->prop['attributes'], array('search' => $value . $search_suffix));
         if ($ldap_data === false) {
             return $this->result;
         }
         // get all entries of this page and post-filter those that really match the query
         $search = mb_strtolower($value);
         foreach ($ldap_data as $i => $entry) {
             $rec = $this->_ldap2result($entry);
             foreach ($fields as $f) {
                 foreach ((array) $rec[$f] as $val) {
                     if ($this->compare_search_value($f, $val, $search, $mode)) {
                         $this->result->add($rec);
                         $this->result->count++;
                         break 2;
                     }
                 }
             }
         }
         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})";
             }
         }
     } else {
         foreach ((array) $fields as $idx => $field) {
             $val = is_array($value) ? $value[$idx] : $value;
             if ($attrs = $this->_map_field($field)) {
                 if (count($attrs) > 1) {
                     $filter .= '(|';
                 }
                 foreach ($attrs as $f) {
                     $filter .= "({$f}={$wp}" . rcube_ldap_generic::quote_string($val) . "{$ws})";
                 }
                 if (count($attrs) > 1) {
                     $filter .= ')';
                 }
             }
         }
     }
     $filter .= ')';
     // add required (non empty) fields filter
     $req_filter = '';
     foreach ((array) $required as $field) {
         if (in_array($field, (array) $fields)) {
             // required field is already in search filter
             continue;
         }
         if ($attrs = $this->_map_field($field)) {
             if (count($attrs) > 1) {
                 $req_filter .= '(|';
             }
             foreach ($attrs as $f) {
                 $req_filter .= "({$f}=*)";
             }
             if (count($attrs) > 1) {
                 $req_filter .= ')';
             }
         }
     }
     if (!empty($req_filter)) {
         $filter = '(&' . $req_filter . $filter . ')';
     }
     // avoid double-wildcard if $value is empty
     $filter = preg_replace('/\\*+/', '*', $filter);
     // add general filter to query
     if (!empty($this->prop['filter'])) {
         $filter = '(&(' . preg_replace('/^\\(|\\)$/', '', $this->prop['filter']) . ')' . $filter . ')';
     }
     // set filter string and execute search
     $this->set_search_set($filter);
     if ($select) {
         $this->list_records();
     } else {
         $this->result = $this->count();
     }
     return $this->result;
 }
 /**
  * Search contacts
  *
  * @param mixed   $fields   The field name of array of field names to search in
  * @param mixed   $value    Search value (or array of values when $fields is array)
  * @param int     $mode     Matching mode:
  *                          0 - partial (*abc*),
  *                          1 - strict (=),
  *                          2 - prefix (abc*)
  * @param boolean $select   True if results are requested, False if count only
  * @param boolean $nocount  (Not used)
  * @param array   $required List of fields that cannot be empty
  *
  * @return array  Indexed list of contact records and 'count' value
  */
 function search($fields, $value, $mode = 0, $select = true, $nocount = false, $required = array())
 {
     $mode = intval($mode);
     // special treatment for ID-based search
     if ($fields == 'ID' || $fields == $this->primary_key) {
         $ids = !is_array($value) ? explode(',', $value) : $value;
         $result = new rcube_result_set();
         foreach ($ids as $id) {
             if ($rec = $this->get_record($id, true)) {
                 $result->add($rec);
                 $result->count++;
             }
         }
         return $result;
     }
     // use VLV pseudo-search for autocompletion
     if ($this->prop['vlv_search'] && $this->conn && join(',', (array) $fields) == 'email,name') {
         // add general filter to query
         if (!empty($this->prop['filter']) && empty($this->filter)) {
             $this->set_search_set($this->prop['filter']);
         }
         // set VLV controls with encoded search string
         $this->_vlv_set_controls($this->prop, $this->list_page, $this->page_size, $value);
         $function = $this->_scope2func($this->prop['scope']);
         $this->ldap_result = @$function($this->conn, $this->base_dn, $this->filter ? $this->filter : '(objectclass=*)', array_values($this->fieldmap), 0, $this->page_size, (int) $this->prop['timelimit']);
         $this->result = new rcube_result_set(0);
         if (!$this->ldap_result) {
             $this->_debug("S: " . ldap_error($this->conn));
             return $this->result;
         }
         $this->_debug("S: " . ldap_count_entries($this->conn, $this->ldap_result) . " record(s)");
         // get all entries of this page and post-filter those that really match the query
         $search = mb_strtolower($value);
         $entries = ldap_get_entries($this->conn, $this->ldap_result);
         for ($i = 0; $i < $entries['count']; $i++) {
             $rec = $this->_ldap2result($entries[$i]);
             foreach ($fields as $f) {
                 foreach ((array) $rec[$f] as $val) {
                     $val = mb_strtolower($val);
                     switch ($mode) {
                         case 1:
                             $got = $val == $search;
                             break;
                         case 2:
                             $got = $search == substr($val, 0, strlen($search));
                             break;
                         default:
                             $got = strpos($val, $search) !== false;
                             break;
                     }
                     if ($got) {
                         $this->result->add($rec);
                         $this->result->count++;
                         break 2;
                     }
                 }
             }
         }
         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}" . $this->_quote_string($value) . "{$ws})";
             }
         }
     } else {
         foreach ((array) $fields as $idx => $field) {
             $val = is_array($value) ? $value[$idx] : $value;
             if ($f = $this->_map_field($field)) {
                 $filter .= "({$f}={$wp}" . $this->_quote_string($val) . "{$ws})";
             }
         }
     }
     $filter .= ')';
     // add required (non empty) fields filter
     $req_filter = '';
     foreach ((array) $required as $field) {
         if ($f = $this->_map_field($field)) {
             $req_filter .= "({$f}=*)";
         }
     }
     if (!empty($req_filter)) {
         $filter = '(&' . $req_filter . $filter . ')';
     }
     // avoid double-wildcard if $value is empty
     $filter = preg_replace('/\\*+/', '*', $filter);
     // add general filter to query
     if (!empty($this->prop['filter'])) {
         $filter = '(&(' . preg_replace('/^\\(|\\)$/', '', $this->prop['filter']) . ')' . $filter . ')';
     }
     // set filter string and execute search
     $this->set_search_set($filter);
     $this->_exec_search();
     if ($select) {
         $this->list_records();
     } else {
         $this->result = $this->count();
     }
     return $this->result;
 }