performance enhancement: accounts::search

This commit is contained in:
Cornelius Weiß 2008-02-12 15:57:39 +00:00
parent 86f6654c8c
commit ed6fea6f5b

View File

@ -632,7 +632,7 @@ class accounts_ldap
// if it's a limited query, check if the unlimited query is cached
$start = $param['start'];
if (!($maxmatchs = $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'])) $maxmatchs = 15;
if (!($offset = $param['offset'])) $offset = $maxmatchs;
if (!($offset = $param['offset'])) $offset = $start + $maxmatchs;
unset($param['start']);
unset($param['offset']);
$unl_serial = serialize($param);
@ -677,22 +677,55 @@ class accounts_ldap
break;
}
}
if (is_numeric($param['type'])) // return only group-members
{
if (!($members = $this->members($param['type']))) return array();
//echo "<p>accounts_ldap::search() after members($param[type]): ".microtime()."</p>\n";
$filter .= '(|(uid='.implode(')(uid=',$members).'))';
}
// add account_filter to filter (user has to be '*', as we otherwise only search uid's)
$filter .= $this->account_filter;
$filter = str_replace(array('%user','%domain'),array('*',$GLOBALS['egw_info']['user']['domain']),$filter);
$filter .= ')';
// folw:
// - first query only few attributes for sorting and throwing away not needed results
// - throw away & sort
// - fetch relevant accounts with full information
// - map and resolve
$propertyMap = array(
'account_id' => 'uidnumber',
'account_lid' => 'uid',
'account_firstname' => 'givenname',
'account_lastname' => 'sn',
'account_email' => 'email'
);
$order = $propertyMap[$param['order']] ? $propertyMap[$param['order']] : 'uid';
$sri = ldap_search($this->ds, $this->user_context, $filter,array('uid', $order));
$fullSet = array();
foreach (ldap_get_entries($this->ds, $sri) as $entry)
{
$fullSet[$entry['uid'][0]] = $entry[$order][0];
}
if (is_numeric($param['type'])) // return only group-members
{
$relevantAccounts = array();
$sri = ldap_search($this->ds,$this->group_context,"(&(objectClass=posixGroup)(gidnumber=" . abs($param['type']) . "))",array('memberuid'));
$group = ldap_get_entries($this->ds, $sri);
if (isset($group[0]['memberuid']))
{
$fullSet = array_intersect_key($fullSet, array_flip($group[0]['memberuid']));
}
}
$totalcount = count($fullSet);
$sortFn = $param['sort'] == 'DESC' ? 'arsort' : 'asort';
$sortFn($fullSet);
$relevantAccounts = array_slice(array_keys($fullSet), $start, $offset);
$filter = "(" . "&(objectclass=posixaccount)" . '(|(uid='.implode(')(uid=',$relevantAccounts).'))' . $this->account_filter . ")";
$filter = str_replace(array('%user','%domain'),array('*',$GLOBALS['egw_info']['user']['domain']),$filter);
$sri = ldap_search($this->ds, $this->user_context, $filter,array('uid','uidNumber','givenname','sn','mail','shadowExpire'));
//echo "<p>ldap_search(,$this->user_context,'$filter',) ".($sri ? '' : ldap_error($this->ds)).microtime()."</p>\n";
$allValues = ldap_get_entries($this->ds, $sri);
$utc_diff = date('Z');
while (list($null,$allVals) = @each($allValues))
{
@ -748,7 +781,7 @@ class accounts_ldap
$param['order'] = 'account_lid';
}
$account_search[$unl_serial]['data'] = $sortedAccounts = $arrayFunctions->arfsort($accounts,explode(',',$param['order']),$param['sort']);
$account_search[$unl_serial]['total'] = $this->total = count($accounts);
$account_search[$unl_serial]['total'] = $this->total = isset($totalcount) ? $totalcount : count($accounts);
}
//echo "<p>accounts_ldap::search() found $this->total: ".microtime()."</p>\n";
// return only the wanted accounts
@ -756,7 +789,7 @@ class accounts_ldap
if(is_numeric($start) && is_numeric($offset))
{
$account_search[$serial]['total'] = $this->total;
return $account_search[$serial]['data'] = array_slice($sortedAccounts, $start, $offset);
return $account_search[$serial]['data'] = isset($totalcount) ? $sortedAccounts : array_slice($sortedAccounts, $start, $offset);
}
return $sortedAccounts;
}
@ -1029,3 +1062,20 @@ class accounts_ldap
$this->frontend->config['ldap_root_dn'],$this->frontend->config['ldap_root_pw']);
}
}
if (!function_exists('array_intersect_key')) // php5.1 function
{
function array_intersect_key($array1,$array2)
{
$intersection = $keys = array();
foreach(func_get_args() as $arr)
{
$keys[] = array_keys((array)$arr);
}
foreach(call_user_func_array('array_intersect',$keys) as $key)
{
$intersection[$key] = $array1[$key];
}
return $intersection;
}
}