forked from extern/egroupware
Fix duplicate contact view to make sense if you have more than 3 matching rows
This commit is contained in:
parent
915f76e2e6
commit
56d9424c1d
@ -10,8 +10,6 @@
|
|||||||
<column width="40%"/>
|
<column width="40%"/>
|
||||||
<column width="30%"/>
|
<column width="30%"/>
|
||||||
<column width="30%"/>
|
<column width="30%"/>
|
||||||
<column width="180"/>
|
|
||||||
<column width="180"/>
|
|
||||||
</columns>
|
</columns>
|
||||||
<rows>
|
<rows>
|
||||||
<row class="th">
|
<row class="th">
|
||||||
|
@ -269,9 +269,7 @@ class Sql extends Api\Storage
|
|||||||
function duplicates($param)
|
function duplicates($param)
|
||||||
{
|
{
|
||||||
$join = 'JOIN ' . $this->table_name . ' AS a2 ON ';
|
$join = 'JOIN ' . $this->table_name . ' AS a2 ON ';
|
||||||
$filter = array(
|
$filter = $param['col_filter'];
|
||||||
$this->table_name.'.contact_tid != "D"'
|
|
||||||
);
|
|
||||||
$op = 'OR';
|
$op = 'OR';
|
||||||
if (isset($param['op']) && !empty($param['op'])) $op = $param['op'];
|
if (isset($param['op']) && !empty($param['op'])) $op = $param['op'];
|
||||||
$advanced_search = false;
|
$advanced_search = false;
|
||||||
@ -287,11 +285,20 @@ class Sql extends Api\Storage
|
|||||||
$join .= str_replace('cat_id', 'a2.cat_id', $cat_filter) . ' AND ';
|
$join .= str_replace('cat_id', 'a2.cat_id', $cat_filter) . ' AND ';
|
||||||
unset($filter['cat_id']);
|
unset($filter['cat_id']);
|
||||||
}
|
}
|
||||||
|
if ($param['col_filter']['tid'])
|
||||||
|
{
|
||||||
|
$filter['contact_tid'] = $param['col_filter']['tid'];
|
||||||
|
$join .= 'a2.contact_tid = ' . $this->db->quote($filter['contact_tid']) . ' AND ';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$join .= 'a2.contact_tid != \'D\' AND ';
|
||||||
|
}
|
||||||
// add filter for read ACL in sql, if user is NOT the owner of the addressbook
|
// add filter for read ACL in sql, if user is NOT the owner of the addressbook
|
||||||
if ($param['owner'] && $param['owner'] == $GLOBALS['egw_info']['user']['account_id'])
|
if ($param['owner'] && $param['owner'] == $GLOBALS['egw_info']['user']['account_id'])
|
||||||
{
|
{
|
||||||
$filter['owner'] = $param['owner'];
|
$filter['owner'] = $param['owner'];
|
||||||
$join .= 'a2.owner = ' . $this->db->quote($filter['owner']) . ' AND ';
|
$join .= 'a2.contact_owner = ' . $this->db->quote($filter['owner']) . ' AND ';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -302,8 +309,8 @@ class Sql extends Api\Storage
|
|||||||
|
|
||||||
$filter['owner'] = $param['owner'];
|
$filter['owner'] = $param['owner'];
|
||||||
$filter['private'] = 0;
|
$filter['private'] = 0;
|
||||||
$join .= 'a2.owner = ' . $this->db->quote($filter['owner']) . ' AND ';
|
$join .= 'a2.contact_owner = ' . $this->db->quote($filter['owner']) . ' AND ';
|
||||||
$join .= 'a2.private = ' . $this->db->quote($filter['private']) . ' AND ';
|
$join .= 'a2.contact_private = ' . $this->db->quote($filter['private']) . ' AND ';
|
||||||
}
|
}
|
||||||
else // search all addressbooks, incl. accounts
|
else // search all addressbooks, incl. accounts
|
||||||
{
|
{
|
||||||
@ -327,55 +334,71 @@ class Sql extends Api\Storage
|
|||||||
array('n_family', 'n_given', 'org_name', 'contact_email');
|
array('n_family', 'n_given', 'org_name', 'contact_email');
|
||||||
$match_count = $GLOBALS['egw_info']['user']['preferences']['addressbook']['duplicate_threshold'] ?
|
$match_count = $GLOBALS['egw_info']['user']['preferences']['addressbook']['duplicate_threshold'] ?
|
||||||
$GLOBALS['egw_info']['user']['preferences']['addressbook']['duplicate_threshold'] : 3;
|
$GLOBALS['egw_info']['user']['preferences']['addressbook']['duplicate_threshold'] : 3;
|
||||||
|
|
||||||
|
$columns = Array();
|
||||||
$extra = Array();
|
$extra = Array();
|
||||||
$order = in_array($param['order'], $group) ? $param['order'] : $group[0];
|
$order = in_array($param['order'], $group) ? $param['order'] : $group[0];
|
||||||
$join .= $this->table_name .'.contact_id != a2.contact_id AND a2.contact_tid != "D" AND (';
|
$join .= $this->table_name .'.contact_id != a2.contact_id AND (';
|
||||||
$join_fields = Array();
|
$join_fields = Array();
|
||||||
foreach($group as &$field)
|
foreach($group as $field)
|
||||||
{
|
{
|
||||||
$extra[] = "IF({$this->table_name}.$field = a2.$field, 1, 0)";
|
$extra[] = "IF({$this->table_name}.$field = a2.$field, 1, 0)";
|
||||||
$join_fields[] = $this->table_name . ".$field = a2.$field";
|
$join_fields[] = $this->table_name . ".$field = a2.$field";
|
||||||
$field = $this->table_name . ".$field AS $field";
|
$columns[] = "IF({$this->table_name}.$field = a2.$field, {$this->table_name}.$field, '') AS $field";
|
||||||
}
|
}
|
||||||
$extra = Array(
|
$extra = Array(
|
||||||
'a2.contact_id AS matched',
|
|
||||||
implode('+', $extra) . ' AS match_count'
|
implode('+', $extra) . ' AS match_count'
|
||||||
);
|
);
|
||||||
$join .= $this->db->column_data_implode(' OR ',$join_fields) . ')';
|
$join .= $this->db->column_data_implode(' OR ',$join_fields) . ')';
|
||||||
|
|
||||||
$append = " HAVING match_count >= $match_count ORDER BY {$this->table_name}.{$order} $sort, $this->table_name.contact_id";
|
$append = " HAVING match_count >= $match_count ORDER BY {$order} $sort, $this->table_name.contact_id";
|
||||||
$group[] = $this->table_name.'.contact_id AS contact_id';
|
$columns[] = $this->table_name.'.contact_id AS contact_id';
|
||||||
|
|
||||||
$rows = parent::search($param['search'],$group,
|
$criteria = array();
|
||||||
$append,$extra,$wildcard,false,$op/*'OR'*/,
|
if ($param['search'] && !is_array($param['search']))
|
||||||
array($param['start'],$param['num_rows']),$filter, $join);
|
{
|
||||||
|
$search = $this->search2criteria($param['search'],$wildcard,$op);
|
||||||
|
$criteria = array($search);
|
||||||
|
}
|
||||||
|
$query = $this->parse_search(array_merge($criteria, $filter), $wildcard, false, ' AND ');
|
||||||
|
|
||||||
|
$sub_query = $this->db->select($this->table_name,
|
||||||
|
'DISTINCT ' . implode(', ',array_merge($columns, $extra)),
|
||||||
|
$query,
|
||||||
|
False, False, 0, $append, False, -1,
|
||||||
|
$join
|
||||||
|
);
|
||||||
|
|
||||||
|
$columns = implode(', ', $group);
|
||||||
|
if ($this->db->Type == 'mysql' && $this->db->ServerInfo['version'] >= 4.0)
|
||||||
|
{
|
||||||
|
$mysql_calc_rows = 'SQL_CALC_FOUND_ROWS ';
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = $this->db->query(
|
||||||
|
"SELECT " . $columns. ', COUNT(contact_id) AS group_count' .
|
||||||
|
' FROM (' . $sub_query . ') AS matches GROUP BY ' . implode(',',$group) .
|
||||||
|
' ORDER BY ' . $order,
|
||||||
|
__LINE__, __FILE__, (int)$param['start'],$mysql_calc_rows ? (int)$param['num_rows'] : -1
|
||||||
|
);
|
||||||
|
if ($mysql_calc_rows)
|
||||||
|
{
|
||||||
|
$this->total = $this->db->query('SELECT FOUND_ROWS()')->fetchColumn();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->total = $rows->NumRows();
|
||||||
|
}
|
||||||
|
|
||||||
// Go through rows and only return one for each pair/triplet/etc. of matches
|
// Go through rows and only return one for each pair/triplet/etc. of matches
|
||||||
$dupes = array();
|
$dupes = array();
|
||||||
foreach($rows as $key => &$row)
|
foreach($rows as $key => $row)
|
||||||
{
|
{
|
||||||
if(array_key_exists($row['contact_id'], $dupes))
|
$row['email'] = $row['contact_email'];
|
||||||
{
|
$row['email_home'] = $row['contact_email_home'];
|
||||||
$kept_row =& $rows[$dupes[$row['contact_id']]];
|
$dupes[] = $this->db2data($row);
|
||||||
$kept_row['group_count']++;
|
|
||||||
|
|
||||||
// Clear not matching fields, or we won't be able to find children
|
|
||||||
foreach($kept_row as $sub_key => $sub_value)
|
|
||||||
{
|
|
||||||
if(in_array($sub_key, array('contact_id','group_count'))) continue;
|
|
||||||
if($row[$sub_key] != $sub_value)
|
|
||||||
{
|
|
||||||
unset($kept_row[$sub_key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($rows[$key]);
|
|
||||||
$this->total--;
|
|
||||||
}
|
|
||||||
$dupes[$row['matched']] = $key;
|
|
||||||
$row['group_count'] = 1;
|
|
||||||
}
|
}
|
||||||
return array_values($rows);
|
return $dupes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -859,13 +859,18 @@ class Storage
|
|||||||
}
|
}
|
||||||
if(!array_key_exists('tid', $param['col_filter']) || $param['col_filter']['tid'] === '')
|
if(!array_key_exists('tid', $param['col_filter']) || $param['col_filter']['tid'] === '')
|
||||||
{
|
{
|
||||||
$param['col_filter'][] = 'contact_tid != \'' . self::DELETED_TYPE . '\'';
|
$param['col_filter'][] = $this->somain->table_name.'.contact_tid != \'' . self::DELETED_TYPE . '\'';
|
||||||
}
|
}
|
||||||
elseif(is_null($param['col_filter']['tid']))
|
elseif(is_null($param['col_filter']['tid']))
|
||||||
{
|
{
|
||||||
// return all entries including deleted
|
// return all entries including deleted
|
||||||
unset($param['col_filter']['tid']);
|
unset($param['col_filter']['tid']);
|
||||||
}
|
}
|
||||||
|
if($param['col_filter']['owner'])
|
||||||
|
{
|
||||||
|
$param['owner'] = $param['col_filter']['owner'];
|
||||||
|
unset($param['col_filter']['owner']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$rows = $this->somain->duplicates($param);
|
$rows = $this->somain->duplicates($param);
|
||||||
|
Loading…
Reference in New Issue
Block a user