mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 01:13:25 +01:00
Fix addressbook_bo::find_contact()
This commit is contained in:
parent
8a7f0d35f4
commit
ff3e461823
@ -95,6 +95,7 @@ class addressbook_bo extends addressbook_so
|
||||
* @var boolean
|
||||
*/
|
||||
var $log = false;
|
||||
var $logfile = '/tmp/log-addressbook_bo';
|
||||
|
||||
/**
|
||||
* Number and message of last error or false if no error, atm. only used for saving
|
||||
@ -130,6 +131,12 @@ class addressbook_bo extends addressbook_so
|
||||
function __construct($contact_app='addressbook')
|
||||
{
|
||||
parent::__construct($contact_app);
|
||||
if ($this->log)
|
||||
{
|
||||
$this->logfile = $GLOBALS['egw_info']['server']['temp_dir'].'/log-addressbook_bo';
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."($contact_app)\n", 3 ,$this->logfile);
|
||||
}
|
||||
|
||||
$this->now_su = egw_time::to('now','ts');
|
||||
|
||||
$this->prefs =& $GLOBALS['egw_info']['user']['preferences']['addressbook'];
|
||||
@ -1638,19 +1645,6 @@ class addressbook_bo extends addressbook_so
|
||||
}
|
||||
}
|
||||
|
||||
function all_empty(&$_contact, &$fields)
|
||||
{
|
||||
$retval = true;
|
||||
foreach ($fields as $field) {
|
||||
if (isset($_contact[$field]) && !empty($_contact[$field])) {
|
||||
$retval = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to find a matching db entry
|
||||
*
|
||||
@ -1660,11 +1654,14 @@ class addressbook_bo extends addressbook_so
|
||||
*/
|
||||
function find_contact($contact, $relax=false)
|
||||
{
|
||||
$empty_addr_one = $empty_addr_two = true;
|
||||
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__
|
||||
. '('. ($relax ? 'RELAX': 'EXACT') . ')[ContactData]:'
|
||||
. array2string($contact));
|
||||
. array2string($contact)
|
||||
. "\n", 3, $this->logfile);
|
||||
}
|
||||
|
||||
$matchingContacts = array();
|
||||
@ -1673,7 +1670,8 @@ class addressbook_bo extends addressbook_so
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__
|
||||
. '()[ContactID]: ' . $contact['id']);
|
||||
. '()[ContactID]: ' . $contact['id']
|
||||
. "\n", 3, $this->logfile);
|
||||
}
|
||||
// We only do a simple consistency check
|
||||
if (!$relax || ((empty($found['n_family']) || $found['n_family'] == $contact['n_family'])
|
||||
@ -1690,7 +1688,8 @@ class addressbook_bo extends addressbook_so
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__
|
||||
. '()[ContactUID]: ' . $contact['uid']);
|
||||
. '()[ContactUID]: ' . $contact['uid']
|
||||
. "\n", 3, $this->logfile);
|
||||
}
|
||||
// Try the given UID first
|
||||
$criteria = array ('contact_uid' => $contact['uid']);
|
||||
@ -1717,124 +1716,75 @@ class addressbook_bo extends addressbook_so
|
||||
$addr_two_fields = array('adr_two_street',
|
||||
'adr_two_locality', 'adr_two_region',
|
||||
'adr_two_postalcode', 'adr_two_countryname');
|
||||
$no_addr_one = array();
|
||||
$no_addr_two = array();
|
||||
|
||||
if (!empty($contact['owner']))
|
||||
{
|
||||
$columns_to_search += array('owner');
|
||||
}
|
||||
|
||||
$backend =& $this->get_backend();
|
||||
|
||||
// define filter for empty address one
|
||||
foreach ($addr_one_fields as $field)
|
||||
{
|
||||
if (!($db_col = array_search($field, $backend->db_cols)))
|
||||
{
|
||||
$db_col = $field;
|
||||
}
|
||||
$no_addr_one[] = "(" . $db_col . " IS NULL OR " . $db_col . " = '')";
|
||||
}
|
||||
|
||||
// define filter for empty address two
|
||||
foreach ($addr_two_fields as $field)
|
||||
{
|
||||
if (!($db_col = array_search($field, $backend->db_cols)))
|
||||
{
|
||||
$db_col = $field;
|
||||
}
|
||||
$no_addr_two[] = "(" . $db_col . " IS NULL OR " . $db_col . " = '')";
|
||||
}
|
||||
|
||||
$result = false;
|
||||
|
||||
$criteria = array();
|
||||
$empty_columns = array();
|
||||
|
||||
foreach ($columns_to_search as $field)
|
||||
{
|
||||
if (!isset($contact[$field]) || empty($contact[$field])) {
|
||||
if ($relax && in_array($field, $tolerance_fields)) continue;
|
||||
|
||||
if (empty($contact[$field]))
|
||||
{
|
||||
// Not every device supports all fields
|
||||
if (!in_array($field, $tolerance_fields))
|
||||
{
|
||||
if (!($db_col = array_search($field, $backend->db_cols)))
|
||||
{
|
||||
$db_col = $field;
|
||||
}
|
||||
$empty_columns[] = "(" . $db_col . " IS NULL OR " . $db_col . " = '')";
|
||||
$criteria[$field] = '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!$relax || !in_array($field, $tolerance_fields))
|
||||
{
|
||||
$criteria[$field] = $contact[$field];
|
||||
}
|
||||
$criteria[$field] = $contact[$field];
|
||||
}
|
||||
}
|
||||
|
||||
$filter = $empty_columns;
|
||||
|
||||
if (!$relax)
|
||||
{
|
||||
// We use addresses only for strong matching
|
||||
|
||||
if ($this->all_empty($contact, $addr_one_fields))
|
||||
foreach ($addr_one_fields as $field)
|
||||
{
|
||||
$filter = $filter + $no_addr_one;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($addr_one_fields as $field)
|
||||
if (empty($contact[$field]))
|
||||
{
|
||||
if (!isset($contact[$field]) || empty($contact[$field]))
|
||||
{
|
||||
if (!($db_col = array_search($field, $backend->db_cols)))
|
||||
{
|
||||
$db_col = $field;
|
||||
}
|
||||
$filter[] = "(" . $db_col . " IS NULL OR " . $db_col . " = '')";
|
||||
}
|
||||
else
|
||||
{
|
||||
$criteria[$field] = $contact[$field];
|
||||
}
|
||||
$criteria[$field] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$empty_addr_one = false;
|
||||
$criteria[$field] = $contact[$field];
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->all_empty($contact, $addr_two_fields))
|
||||
foreach ($addr_two_fields as $field)
|
||||
{
|
||||
$filter = $filter + $no_addr_two;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($addr_two_fields as $field)
|
||||
if (empty($contact[$field]))
|
||||
{
|
||||
if (!isset($contact[$field]) || empty($contact[$field]))
|
||||
{
|
||||
if (!($db_col = array_search($field, $backend->db_cols)))
|
||||
{
|
||||
$db_col = $field;
|
||||
}
|
||||
$filter[] = "(" . $db_col . " IS NULL OR " . $db_col . " = '')";
|
||||
}
|
||||
else
|
||||
{
|
||||
$criteria[$field] = $contact[$field];
|
||||
}
|
||||
$criteria[$field] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$empty_addr_two = false;
|
||||
$criteria[$field] = $contact[$field];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__
|
||||
. '()[Addressbook FIND Step 1]: '
|
||||
. 'FILTER:' . array2string($filter)
|
||||
. 'CRITERIA' . array2string($criteria));
|
||||
. 'CRITERIA = ' . array2string($criteria)
|
||||
. "\n", 3, $this->logfile);
|
||||
}
|
||||
|
||||
// first try full match
|
||||
if (($foundContacts = parent::search($criteria, true, '', '', '', False, 'AND', false, $filter)))
|
||||
if (($foundContacts = parent::search($criteria, true, '', '', '', true)))
|
||||
{
|
||||
foreach ($foundContacts as $egwContact)
|
||||
{
|
||||
@ -1843,24 +1793,26 @@ class addressbook_bo extends addressbook_so
|
||||
}
|
||||
|
||||
// No need for more searches for relaxed matching
|
||||
if (!$relax || count($matchingContacts)) return $matchingContacts;
|
||||
if ($relax || count($matchingContacts)) return $matchingContacts;
|
||||
|
||||
|
||||
if (!$this->all_empty($contact, $addr_one_fields)
|
||||
&& $this->all_empty($contact, $addr_two_fields))
|
||||
if (!$empty_addr_one && $empty_addr_two)
|
||||
{
|
||||
// try given address and ignore the second one in EGW
|
||||
$filter = array_diff($filter, $no_addr_two);
|
||||
foreach ($addr_two_fields as $field)
|
||||
{
|
||||
unset($criteria[$field]);
|
||||
}
|
||||
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__
|
||||
. '()[Addressbook FIND Step 2]: '
|
||||
. 'FILTER:' . array2string($filter)
|
||||
. 'CRITERIA' . array2string($criteria));
|
||||
. 'CRITERIA = ' . array2string($criteria)
|
||||
. "\n", 3, $this->logfile);
|
||||
}
|
||||
|
||||
if (($foundContacts = parent::search($criteria, true, '', '', '', False, 'AND', false, $filter)))
|
||||
if (($foundContacts = parent::search($criteria, true, '', '', '', true)))
|
||||
{
|
||||
foreach ($foundContacts as $egwContact)
|
||||
{
|
||||
@ -1870,35 +1822,21 @@ class addressbook_bo extends addressbook_so
|
||||
else
|
||||
{
|
||||
// try address as home address -- some devices don't qualify addresses
|
||||
$filter = $empty_columns;
|
||||
foreach ($addr_two_fields as $key => $field)
|
||||
{
|
||||
if (isset($criteria[$addr_one_fields[$key]]))
|
||||
{
|
||||
$criteria[$field] = $criteria[$addr_one_fields[$key]];
|
||||
unset($criteria[$addr_one_fields[$key]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!($db_col = array_search($field,$backend->db_cols)))
|
||||
{
|
||||
$db_col = $field;
|
||||
}
|
||||
$filter[] = "(" . $db_col . " IS NULL OR " . $db_col . " = '')";
|
||||
}
|
||||
$criteria[$field] = $criteria[$addr_one_fields[$key]];
|
||||
unset($criteria[$addr_one_fields[$key]]);
|
||||
}
|
||||
|
||||
$filter = $filter + $no_addr_one;
|
||||
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__
|
||||
. '()[Addressbook FIND Step 3]: '
|
||||
. 'FILTER:' . array2string($filter)
|
||||
. 'CRITERIA' . array2string($criteria));
|
||||
. 'CRITERIA = ' . array2string($criteria)
|
||||
. "\n", 3, $this->logfile);
|
||||
}
|
||||
|
||||
if (($foundContacts = parent::search($criteria, true, '', '', '', False, 'AND', false, $filter)))
|
||||
if (($foundContacts = parent::search($criteria, true, '', '', '', true)))
|
||||
{
|
||||
foreach ($foundContacts as $egwContact)
|
||||
{
|
||||
@ -1907,54 +1845,23 @@ class addressbook_bo extends addressbook_so
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
elseif (!$empty_addr_one && !$empty_addr_two)
|
||||
{ // try again after address swap
|
||||
|
||||
$filter = $empty_columns;
|
||||
|
||||
foreach ($addr_one_fields as $key => $field)
|
||||
{
|
||||
$_temp_set = false;
|
||||
if (isset($criteria[$field]))
|
||||
{
|
||||
$_temp = $criteria[$field];
|
||||
$_temp_set = true;
|
||||
unset($criteria[$field]);
|
||||
}
|
||||
if (isset($criteria[$addr_two_fields[$key]]))
|
||||
{
|
||||
$criteria[$field] = $criteria[$addr_two_fields[$key]];
|
||||
unset($criteria[$addr_two_fields[$key]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!($db_col = array_search($field,$backend->db_cols)))
|
||||
{
|
||||
$db_col = $field;
|
||||
}
|
||||
$filter[] = "(" . $db_col . " IS NULL OR " . $db_col . " = '')";
|
||||
}
|
||||
if ($_temp_set)
|
||||
{
|
||||
$criteria[$addr_two_fields[$key]] = $_temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!($db_col = array_search($addr_two_fields[$key],$backend->db_cols)))
|
||||
{
|
||||
$db_col = $field;
|
||||
}
|
||||
$filter[] = "(" . $db_col . " IS NULL OR " . $db_col . " = '')";
|
||||
}
|
||||
$_temp = $criteria[$field];
|
||||
$criteria[$field] = $criteria[$addr_two_fields[$key]];
|
||||
$criteria[$addr_two_fields[$key]] = $_temp;
|
||||
}
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__
|
||||
. '()[Addressbook FIND Step 4]: '
|
||||
. 'FILTER:' . array2string($filter)
|
||||
. 'CRITERIA' . array2string($criteria));
|
||||
. 'CRITERIA = ' . array2string($criteria)
|
||||
. "\n", 3, $this->logfile);
|
||||
}
|
||||
if(($foundContacts = parent::search($criteria, true, '', '', '', False, 'AND', false, $filter)))
|
||||
if (($foundContacts = parent::search($criteria, true, '', '', '', true)))
|
||||
{
|
||||
foreach ($foundContacts as $egwContact)
|
||||
{
|
||||
@ -1965,7 +1872,8 @@ class addressbook_bo extends addressbook_so
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__
|
||||
. '()[FOUND]:' . array2string($matchingContacts));
|
||||
. '()[FOUND]: ' . array2string($matchingContacts)
|
||||
. "\n", 3, $this->logfile);
|
||||
}
|
||||
return $matchingContacts;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ class so_sql
|
||||
* @param string $colum_prefix='' column prefix to automatic remove from the column-name, if the column name starts with it
|
||||
* @param boolean $no_clone=false can we avoid to clone the db-object, default no
|
||||
* new code using appnames and foreach(select(...,$app) can set it to avoid an extra instance of the db object
|
||||
* @param string $timestamp_type=null default null=leave them as is, 'ts'|'integer' use integer unix timestamps,
|
||||
* @param string $timestamp_type=null default null=leave them as is, 'ts'|'integer' use integer unix timestamps,
|
||||
* 'object' use egw_time objects or 'string' use DB timestamp (Y-m-d H:i:s) string
|
||||
*
|
||||
* @return so_sql
|
||||
@ -200,10 +200,10 @@ class so_sql
|
||||
}
|
||||
$this->set_times($timestamp_type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set class vars timestamp_type, now and tz_offset_s
|
||||
*
|
||||
*
|
||||
* @param string|boolean $timestamp_type=false default false do NOT set time_stamptype,
|
||||
* null=leave them as is, 'ts'|'integer' use integer unix timestamps, 'object' use egw_time objects,
|
||||
* 'string' use DB timestamp (Y-m-d H:i:s) string
|
||||
@ -438,7 +438,7 @@ class so_sql
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Name of automatically set user timezone field from read
|
||||
*/
|
||||
@ -554,7 +554,7 @@ class so_sql
|
||||
if ((int) $this->debug >= 4) echo "nothing found !!!</p>\n";
|
||||
|
||||
$this->db2data();
|
||||
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -568,7 +568,7 @@ class so_sql
|
||||
function save($keys=null,$extra_where=null)
|
||||
{
|
||||
if (is_array($keys) && count($keys)) $this->data_merge($keys);
|
||||
|
||||
|
||||
// check if data contains user timezone during read AND user changed timezone since then
|
||||
// --> load old timezone for the rest of this request
|
||||
// this only a grude hack, better handle this situation in app code:
|
||||
@ -803,7 +803,21 @@ class so_sql
|
||||
{
|
||||
$db_col = $col;
|
||||
}
|
||||
if ($wildcard || $criteria[$col][0] == '!' ||
|
||||
if ($val === '')
|
||||
{
|
||||
if (isset($this->table_def['fd'][$db_col]) &&
|
||||
$this->table_def['fd'][$db_col]['type'] == 'varchar' &&
|
||||
$this->table_def['fd'][$db_col]['nullable'] !== false)
|
||||
{
|
||||
unset($criteria[$col]);
|
||||
$query[] = '(' . $db_col . ' IS NULL OR ' . $db_col . " = '')";
|
||||
}
|
||||
else
|
||||
{
|
||||
$query[$db_col] = '';
|
||||
}
|
||||
}
|
||||
elseif ($wildcard || $criteria[$col][0] == '!' ||
|
||||
is_string($criteria[$col]) && (strpos($criteria[$col],'*')!==false || strpos($criteria[$col],'?')!==false))
|
||||
{
|
||||
$cmp_op = ' '.$this->db->capabilities['case_insensitive_like'].' ';
|
||||
@ -825,16 +839,14 @@ class so_sql
|
||||
{
|
||||
list($table,$only_col) = explode('.',$db_col);
|
||||
|
||||
$table_def = $this->db->get_table_definitions(true,$table);
|
||||
|
||||
if (is_array($val) && count($val) > 1)
|
||||
{
|
||||
array_walk($val,array($this->db,'quote'),$table_def['fd'][$only_col]['type']);
|
||||
array_walk($val,array($this->db,'quote'),$this->table_def['fd'][$only_col]['type']);
|
||||
$query[] = $sql = $db_col.' IN (' .implode(',',$val).')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$query[] = $db_col.'='.$this->db->quote(is_array($val)?array_shift($val):$val,$table_def['fd'][$only_col]['type']);
|
||||
$query[] = $db_col.'='.$this->db->quote(is_array($val)?array_shift($val):$val,$this->table_def['fd'][$only_col]['type']);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -995,6 +1007,7 @@ class so_sql
|
||||
return new so_sql_db2data_iterator($this,$rs);
|
||||
}
|
||||
$arr = array();
|
||||
$n = 0;
|
||||
if ($rs) foreach($rs as $row)
|
||||
{
|
||||
$data = array();
|
||||
|
Loading…
Reference in New Issue
Block a user