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 &$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 &$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 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 * @return array or column => value pairs
*/ */
public function search2criteria($pattern,&$wildcard='',&$op='AND',$extra_col=null, $search_cols = array()) 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_types = array('auto', 'int', 'float', 'double');
$numeric_columns = array(); $numeric_columns = array();
$skip_columns_with = array('_id', 'modified', 'modifier', 'status', 'cat_id', 'owner');
if(!$search_cols) if(!$search_cols)
{ {
$search_cols = is_null($this->columns_to_search) ? $this->db_cols : $this->columns_to_search; $search_cols = $this->get_default_search_columns();
// 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;
}
}
}
}
}
} }
if(!$search_cols) if(!$search_cols)
{ {
@ -1141,7 +1122,7 @@ class so_sql
$numeric_filter = array(); $numeric_filter = array();
foreach($numeric_columns as $col) foreach($numeric_columns as $col)
{ {
if(!$wildcard) if($wildcard == '')
{ {
// Token has a wildcard from user, use LIKE // Token has a wildcard from user, use LIKE
$numeric_filter[] = "($col IS NOT NULL AND CAST($col AS CHAR) 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)"; $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; $criteria[$op][] = $token_filter;
@ -1187,6 +1171,41 @@ class so_sql
return array('(' . $result . ')'); 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 * extract the requested columns from $only_keys and $extra_cols param of a search
* *
@ -1267,8 +1286,7 @@ class so_sql
$op = 'AND'; $op = 'AND';
if ($query['search']) if ($query['search'])
{ {
$wildcard = '%'; $criteria = $query['search'];
$criteria = is_null($this->columns_to_search) ? $this->search2criteria($query['search'],$wildcard,$op) : $query['search'];
} }
$rows = $this->search($criteria,$only_keys,$query['order']?$query['order'].' '.$query['sort']:'',$extra_cols, $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'], $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)) if ($criteria && is_array($criteria))
{ {
$join .= $this->extra_join;
// check if we search in the custom fields // check if we search in the custom fields
if (isset($criteria[$this->extra_value])) 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->capabilities[egw_db::CAPABILITY_CASE_INSENSITIV_LIKE]. ' ' .
$this->db->quote($wildcard.$criteria[$this->extra_value].$wildcard); $this->db->quote($wildcard.$criteria[$this->extra_value].$wildcard);
unset($criteria[$this->extra_value]); unset($criteria[$this->extra_value]);
$join .= $this->extra_join;
} }
// replace ambiguous auto-id with (an exact match of) table_name.autoid // replace ambiguous auto-id with (an exact match of) table_name.autoid
if (isset($criteria[$this->autoinc_id])) 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 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 * Function to test if $field is a custom field: check for the prefix
* *