* Mail: searching in compose now ignores custom fields as they might lead to unexpected results

This commit is contained in:
ralf 2023-05-08 15:13:00 +02:00
parent c5afac87bd
commit d045fde07c
4 changed files with 27 additions and 8 deletions

View File

@ -715,7 +715,7 @@ class Storage
{
if($col != Sql::EXTRA_VALUE &&
$col != Sql::EXTRA_TABLE.'.'.Sql::EXTRA_VALUE &&
!array_key_exists($col, $backend->db_cols))
!array_key_exists($col, $backend->db_cols) && $key !== 'search_cfs')
{
if(!($col = array_search($col, $backend->db_cols)))
{

View File

@ -414,9 +414,10 @@ class Storage extends Storage\Base
* To be or-ed to query for $_pattern in regular columns of main-table.
*
* @param string $_pattern search pattern incl. * or ? as wildcard, if no wildcards used we append and prepend one!
* @param string|string[] $_type=null only search cfs of given type(s), e.g. "url-email"
* @return string with SQL fragment running on main table: "id IN (SELECT id FROM extra-table WHERE extra_value like '$pattern')"
*/
public function cf_match($_pattern)
public function cf_match($_pattern, $_type=null)
{
static $private_cfs=null;
@ -435,9 +436,21 @@ class Storage extends Storage\Base
$this->customfields);
//error_log(__METHOD__."() private_cfs=".array2string($private_cfs));
}
if ($private_cfs)
if ($_type)
{
$sql .= ' AND '.$this->db->expression($this->extra_table, array($this->extra_key => array_keys($this->customfields)));
$cfs = [];
foreach($this->customfields as $name => $data)
{
if (in_array($data['type'], (array)$_type, true))
{
$cfs[] = $name;
}
}
if (!$cfs) return '';
}
if ($private_cfs || isset($cfs))
{
$sql .= ' AND '.$this->db->expression($this->extra_table, array($this->extra_key => $cfs ?? array_keys($this->customfields)));
}
return $sql.')';
}

View File

@ -1251,7 +1251,8 @@ class Base
* @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 =[] List of columns to search. If not provided, all columns in $this->db_cols will be considered
* @param ?bool $search_cfs =null null: do it only for Api\Storage, false: never do it
* allows to specify $search_cfs parameter with key 'search_cfs', which has precedence over $search_cfs parameter
* @param null|bool|string|string[] $search_cfs null: do it only for Api\Storage, false: never do it, or string type(s) of cfs to search, e.g. "url-email"
* @return array or column => value pairs
*/
public function search2criteria($_pattern,&$wildcard='',&$op='AND',$extra_col=null, $search_cols=[],$search_cfs=null)
@ -1284,8 +1285,13 @@ class Base
{
$search_cols = $this->get_default_search_columns();
}
if (array_key_exists('search_cfs', $search_cols))
{
$search_cfs = $search_cols['search_cfs'];
unset($search_cols['search_cfs']);
}
// Concat all fields to be searched together, so the conditions operate across the whole record
foreach($search_cols as $col)
foreach($search_cols as $key => $col)
{
$col_name = $col;
$table = $this->table_name;
@ -1381,7 +1387,7 @@ class Base
if ($search_cfs ?? is_a($this, __NAMESPACE__))
{
// add custom-field search: OR id IN (SELECT id FROM extra_table WHERE extra_value LIKE '$search_token')
$token_filter .= $this->cf_match($search_token);
$token_filter .= $this->cf_match($search_token, is_string($search_cfs) || is_array($search_cfs) ? $search_cfs : null);
}
// Compare numeric token as equality for numeric columns

View File

@ -3630,7 +3630,7 @@ class mail_compose
$search_str = implode(' +', $search); // tell contacts/so_sql to AND search patterns
//error_log(__METHOD__.__LINE__.$_searchString);
$filter = $showAccounts ? array() : array('account_id' => null);
$filter['cols_to_search'] = array('n_prefix','n_given','n_family','org_name','email','email_home', 'contact_id');
$filter['cols_to_search'] = array('n_prefix','n_given','n_family','org_name','email','email_home', 'contact_id', 'search_cfs' => false);
$cols = array('n_fn','n_prefix','n_given','n_family','org_name','email','email_home', 'contact_id', 'etag');
$contacts = $contacts_obj->search($search_str, $cols, 'n_fn', '', '%', false, 'OR', array(0,100), $filter);
$cfs_type_email = Api\Storage\Customfields::get_email_cfs('addressbook');