Add extra search functionality to custom fields.

This commit is contained in:
Nathan Gray 2010-04-01 19:59:50 +00:00
parent f1646e34df
commit d22773d04d
2 changed files with 84 additions and 26 deletions

View File

@ -1016,6 +1016,7 @@ class so_sql
* @param string &$wildcard='' on return wildcard char to use, if pattern does not already contain wildcards!
* @param string &$op='AND' on return boolean operation to use, if pattern does not start with ! we use OR else AND
* @param string $extra_col=null extra column to search
* @param array $search_cols=array() List of columns to search. If not provided, all columns in $this->db_cols will be considered
* @return array or column => value pairs
*/
public function search2criteria($pattern,&$wildcard='',&$op='AND',$extra_col=null, $search_cols = array())
@ -1038,30 +1039,10 @@ class so_sql
*/
$numeric_types = array('auto', 'int', 'float', 'double');
$numeric_columns = array();
$skip_columns_with = array('_id', 'modified', 'modifier', 'status', 'cat_id', 'owner');
if(!$search_cols)
{
$search_cols = is_null($this->columns_to_search) ? $this->db_cols : $this->columns_to_search;
// Skip some numeric columns that don't make sense to search if we have to default to all columns
if(is_null($this->columns_to_search))
{
foreach($search_cols as $key => $col)
{
if(in_array($this->table_def['fd'][$col]['type'], $numeric_types))
{
foreach($skip_columns_with as $bad)
{
if(strpos($col, $bad) !== false)
{
unset($search_cols[$key]);
continue 2;
}
}
}
}
}
$search_cols = $this->get_default_search_columns();
}
if(!$search_cols)
{
@ -1141,7 +1122,7 @@ class so_sql
$numeric_filter = array();
foreach($numeric_columns as $col)
{
if(!$wildcard)
if($wildcard == '')
{
// Token has a wildcard from user, use LIKE
$numeric_filter[] = "($col IS NOT NULL AND CAST($col AS CHAR) LIKE " .
@ -1152,7 +1133,10 @@ class so_sql
$numeric_filter[] = "($col IS NOT NULL AND $col = $token)";
}
}
$token_filter = '(' . $token_filter . ' OR ' . implode(' OR ', $numeric_filter) . ')';
if(count($numeric_filter) > 0)
{
$token_filter = '(' . $token_filter . ' OR ' . implode(' OR ', $numeric_filter) . ')';
}
}
$criteria[$op][] = $token_filter;
@ -1187,6 +1171,41 @@ class so_sql
return array('(' . $result . ')');
}
/**
* Get a default list of columns to search
* This is to be used as a fallback, for when the extending class does not define
* $this->columns_to_search. All the columns are considered, and any with $skip_columns_with in
* their name are discarded because these columns are expected to be foreign keys or other numeric
* values with no meaning to the user.
*
* @return array of column names
*/
protected function get_default_search_columns()
{
$skip_columns_with = array('_id', 'modified', 'modifier', 'status', 'cat_id', 'owner');
$search_cols = is_null($this->columns_to_search) ? $this->db_cols : $this->columns_to_search;
// Skip some numeric columns that don't make sense to search if we have to default to all columns
if(is_null($this->columns_to_search))
{
foreach($search_cols as $key => $col)
{
if(in_array($this->table_def['fd'][$col]['type'], $numeric_types))
{
foreach($skip_columns_with as $bad)
{
if(strpos($col, $bad) !== false)
{
unset($search_cols[$key]);
continue 2;
}
}
}
}
}
return $search_cols;
}
/**
* extract the requested columns from $only_keys and $extra_cols param of a search
*
@ -1267,8 +1286,7 @@ class so_sql
$op = 'AND';
if ($query['search'])
{
$wildcard = '%';
$criteria = is_null($this->columns_to_search) ? $this->search2criteria($query['search'],$wildcard,$op) : $query['search'];
$criteria = $query['search'];
}
$rows = $this->search($criteria,$only_keys,$query['order']?$query['order'].' '.$query['sort']:'',$extra_cols,
$wildcard,false,$op,$query['num_rows']?array((int)$query['start'],$query['num_rows']):(int)$query['start'],

View File

@ -421,6 +421,8 @@ class so_sql_cf extends so_sql
}
if ($criteria && is_array($criteria))
{
$join .= $this->extra_join;
// check if we search in the custom fields
if (isset($criteria[$this->extra_value]))
{
@ -432,7 +434,6 @@ class so_sql_cf extends so_sql
$this->db->capabilities[egw_db::CAPABILITY_CASE_INSENSITIV_LIKE]. ' ' .
$this->db->quote($wildcard.$criteria[$this->extra_value].$wildcard);
unset($criteria[$this->extra_value]);
$join .= $this->extra_join;
}
// replace ambiguous auto-id with (an exact match of) table_name.autoid
if (isset($criteria[$this->autoinc_id]))
@ -507,6 +508,45 @@ class so_sql_cf extends so_sql
return parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join,$need_full_no_count);
}
/**
* Return criteria array for a given search pattern
* Reimplemented to search custom fields
*
* @param string $pattern search pattern incl. * or ? as wildcard, if no wildcards used we append and prepend one!
* @param string &$wildcard='' on return wildcard char to use, if pattern does not already contain wildcards!
* @param string &$op='AND' on return boolean operation to use, if pattern does not start with ! we use OR else AND
* @param string $extra_col=null extra column to search
* @param array $search_cols=array() List of columns to search. If not provided, all columns in $this->db_cols will be considered
* @return array or column => value pairs
*/
public function search2criteria($pattern,&$wildcard='',&$op='AND',$extra_col=null, $search_cols = array())
{
// This function can get called multiple times. Make sure it doesn't re-process.
if (empty($pattern) || is_array($pattern)) return $pattern;
if(strpos($pattern, 'CONCAT') !== false)
{
return $pattern;
}
$pattern = trim($pattern);
$filter = array();
if(!$search_cols)
{
$search_cols = $this->get_default_search_columns();
}
// Add in custom field column, if it is not already there
if(!in_array($this->extra_table.'.'.$this->extra_value, $search_cols))
{
$search_cols[] = $this->extra_table.'.'.$this->extra_value;
}
// Let parent deal with the normal stuff
$criteria = parent::search2criteria($pattern, $wildcard, $op, $extra_col, $search_cols);
return $criteria;
}
/**
* Function to test if $field is a custom field: check for the prefix
*