diff --git a/phpgwapi/inc/class.accounts.inc.php b/phpgwapi/inc/class.accounts.inc.php index 808cbfb124..8b35975591 100644 --- a/phpgwapi/inc/class.accounts.inc.php +++ b/phpgwapi/inc/class.accounts.inc.php @@ -244,7 +244,7 @@ class accounts * 'lid','firstname','lastname','email' - query only the given field for containing $param[query] * @param $param['app'] string with an app-name, to limit result on accounts with run-right for that app * @param $param['offset'] int - number of matches to return if start given, default use the value in the prefs - * @return array with uid / data pairs, data is an array with account_id, account_lid, account_firstname, + * @return array with account_id => data pairs, data is an array with account_id, account_lid, account_firstname, * account_lastname, person_id (id of the linked addressbook entry), account_status, account_expires, account_primary_group */ function search($param) @@ -259,19 +259,18 @@ class accounts { $this->total = $account_search[$serial]['total']; } - elseif ($this->config['account_repository'] == 'ldap') - //not correct for php<5.1 elseif ((method_exists($this,'search')) // implements its on search function ==> use it + // no backend understands $param['app'] and sql does not understand group-parameters + // --> do an full search first and then filter and limit that search + elseif($param['app'] || $this->config['account_repository'] != 'ldap' && + (is_numeric($param['type']) || $param['type'] == 'owngroups')) { - $account_search[$serial]['data'] = $this->backend->search($param); - $account_search[$serial]['total'] = $this->total = $this->backend->total; - } - else - { - $serial2 = $serial; - if (is_numeric($param['type']) || $param['app'] || $param['type'] == 'owngroups') // do we need to limit the search on a group or app? + $app = $param['app']; + unset($param['app']); + $start = $param['start']; + unset($param['start']); + + if ($this->config['account_repository'] != 'ldap') { - $app = $param['app']; - unset($param['app']); if (is_numeric($param['type'])) { $group = (int) $param['type']; @@ -282,62 +281,63 @@ class accounts $group = true; $param['type'] = 'groups'; } - $start = $param['start']; - unset($param['start']); - $serial2 = serialize($param); } - if (!isset($account_search[$serial2])) // check if we already did this general search + // call ourself recursive to get (evtl. cached) full search + $full_search = $this->search($param); + + // filter search now on accounts with run-rights for app or a group + $valid = array(); + if ($app) { - $account_search[$serial2]['data'] = array(); - $accounts = $this->backend->get_list($param['type'],$param['start'],$param['sort'],$param['order'],$param['query'],$param['offset'],$param['query_type']); - if (!$accounts) $accounts = array(); - foreach($accounts as $data) - { - $account_search[$serial2]['data'][$data['account_id']] = $data; - } - $account_search[$serial2]['total'] = $this->total = $this->backend->total; + $valid = $this->split_accounts($app,$param['type'] == 'both' ? 'merge' : $param['type']); } - else + if ($group) { - $this->total = $account_search[$serial2]['total']; + $members = is_int($group) ? $this->members($group,true) : $this->memberships($GLOBALS['egw_info']['user']['account_id'],true); + if (!$members) $members = array(); + $valid = !$app ? $members : array_intersect($valid,$members); // use the intersection } - //echo "$this->backend->get_list($param[type],$param[start],$param[sort],$param[order],$param[query],$param[offset],$param[query_type]) returned
".print_r($account_search[$serial2],True)."
\n"; - if ($app || $group) // limit the search on accounts with run-rights for app or a group + //echo "

limiting result to app='app' and/or group=$group valid-ids=".print_r($valid,true)."

\n"; + $offset = $param['offset'] ? $param['offset'] : $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs']; + $stop = $start + $offset; + $n = 0; + $account_search[$serial]['data'] = array(); + foreach ($full_search as $id => $data) { - $valid = array(); - if ($app) + if (!in_array($id,$valid)) { - $valid = $this->split_accounts($app,$param['type'] == 'both' ? 'merge' : $param['type']); + $this->total--; + continue; } - if ($group) + // now we have a valid entry + if (!is_int($start) || $start <= $n && $n < $stop) { - $members = is_int($group) ? $this->members($group,true) : $this->memberships($GLOBALS['egw_info']['user']['account_id'],true); - if (!$members) $members = array(); - $valid = !$app ? $members : array_intersect($valid,$members); // use the intersection + $account_search[$serial]['data'][$id] = $data; } - //echo "

limiting result to app='app' and/or group=$group valid-ids=".print_r($valid,true)."

\n"; - $offset = $param['offset'] ? $param['offset'] : $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs']; - $stop = $start + $offset; - $n = 0; - $account_search[$serial]['data'] = array(); - foreach ($account_search[$serial2]['data'] as $id => $data) - { - if (!in_array($id,$valid)) - { - $this->total--; - continue; - } - // now we have a valid entry - if (!is_int($start) || $start <= $n && $n < $stop) - { - $account_search[$serial]['data'][$id] = $data; - } - $n++; - } - $account_search[$serial]['total'] = $this->total; + $n++; } + $account_search[$serial]['total'] = $this->total; } - //echo "

accounts::search('$serial')=

".print_r($account_search[$serial]['data'],True).")
\n"; + // search via ldap backend + elseif ($this->config['account_repository'] == 'ldap') + //not correct for php<5.1 elseif ((method_exists($this,'search')) // implements its on search function ==> use it + { + $account_search[$serial]['data'] = $this->backend->search($param); + $account_search[$serial]['total'] = $this->total = $this->backend->total; + } + // search by old accounts_sql backend + else + { + $account_search[$serial]['data'] = array(); + $accounts = $this->backend->get_list($param['type'],$param['start'],$param['sort'],$param['order'],$param['query'],$param['offset'],$param['query_type']); + if (!$accounts) $accounts = array(); + foreach($accounts as $data) + { + $account_search[$serial]['data'][$data['account_id']] = $data; + } + $account_search[$serial]['total'] = $this->total = $this->backend->total; + } + //echo "

accounts::search(".array2string(unserialize($serial)).")= returning ".count($account_search[$serial]['data'])." of $this->total entries

".print_r($account_search[$serial]['data'],True)."
\n"; //echo "

accounts::search() end: ".microtime()."

\n"; return $account_search[$serial]['data']; } diff --git a/phpgwapi/inc/class.accounts_ldap.inc.php b/phpgwapi/inc/class.accounts_ldap.inc.php index 8d482b5f0a..f6db6184cd 100644 --- a/phpgwapi/inc/class.accounts_ldap.inc.php +++ b/phpgwapi/inc/class.accounts_ldap.inc.php @@ -505,8 +505,8 @@ class accounts_ldap // 'account_lastlogin' => $data['phpgwaccountlastlogin'][0], // 'account_lastloginfrom' => $data['phpgwaccountlastloginfrom'][0], 'person_id' => $data['uid'][0], // id of associated contact - 'account_created' => isset($data['createtimestamp'][0]) ? $this->accounts_ldap2ts($data['createtimestamp'][0]) : null, - 'account_modified' => isset($data['modifytimestamp'][0]) ? $this->accounts_ldap2ts($data['modifytimestamp'][0]) : null, + 'account_created' => isset($data['createtimestamp'][0]) ? self::accounts_ldap2ts($data['createtimestamp'][0]) : null, + 'account_modified' => isset($data['modifytimestamp'][0]) ? self::accounts_ldap2ts($data['modifytimestamp'][0]) : null, ); //echo "

accounts_ldap::_read_user($account_id): shadowexpire={$data['shadowexpire'][0]} --> account_expires=$user[account_expires]=".date('Y-m-d H:i',$user['account_expires'])."

\n"; if ($this->frontend->config['ldap_extra_attributes']) @@ -621,7 +621,7 @@ class accounts_ldap * 'exact' - query all fields for exact $param[query] * 'lid','firstname','lastname','email' - query only the given field for containing $param[query] * @param $param['offset'] int - number of matches to return if start given, default use the value in the prefs - * @return array with uid / data pairs, data is an array with account_id, account_lid, account_firstname, + * @return array with account_id => data pairs, data is an array with account_id, account_lid, account_firstname, * account_lastname, person_id (id of the linked addressbook entry), account_status, account_expires, account_primary_group */ function search($param) @@ -751,16 +751,16 @@ class accounts_ldap $test = @$allVals['uid'][0]; if (!$this->frontend->config['global_denied_users'][$test] && $allVals['uid'][0]) { - $accounts[] = Array( + $accounts[$allVals['uidnumber'][0]] = Array( 'account_id' => $allVals['uidnumber'][0], - 'account_lid' => $GLOBALS['egw']->translation->convert($allVals['uid'][0],'utf-8'), + 'account_lid' => translation::convert($allVals['uid'][0],'utf-8'), 'account_type' => 'u', - 'account_firstname' => $GLOBALS['egw']->translation->convert($allVals['givenname'][0],'utf-8'), - 'account_lastname' => $GLOBALS['egw']->translation->convert($allVals['sn'][0],'utf-8'), + 'account_firstname' => translation::convert($allVals['givenname'][0],'utf-8'), + 'account_lastname' => translation::convert($allVals['sn'][0],'utf-8'), 'account_status' => isset($allVals['shadowexpire'][0]) && $allVals['shadowexpire'][0]*24*3600-$utc_diff < time() ? false : 'A', 'account_email' => $allVals['mail'][0], - 'account_created' => isset($allVals['createtimestamp'][0]) ? $this->accounts_ldap2ts($allVals['createtimestamp'][0]) : null, - 'account_modified' => isset($allVals['modifytimestamp'][0]) ? $this->accounts_ldap2ts($allVals['modifytimestamp'][0]) : null, + 'account_created' => isset($allVals['createtimestamp'][0]) ? self::accounts_ldap2ts($allVals['createtimestamp'][0]) : null, + 'account_modified' => isset($allVals['modifytimestamp'][0]) ? self::accounts_ldap2ts($allVals['modifytimestamp'][0]) : null, ); } @@ -796,11 +796,11 @@ class accounts_ldap $test = $allVals['cn'][0]; if (!$this->frontend->config['global_denied_groups'][$test] && $allVals['cn'][0]) { - $accounts[] = Array( + $accounts[(string)-$allVals['gidnumber'][0]] = Array( 'account_id' => -$allVals['gidnumber'][0], - 'account_lid' => $GLOBALS['egw']->translation->convert($allVals['cn'][0],'utf-8'), + 'account_lid' => translation::convert($allVals['cn'][0],'utf-8'), 'account_type' => 'g', - 'account_firstname' => $GLOBALS['egw']->translation->convert($allVals['cn'][0],'utf-8'), + 'account_firstname' => translation::convert($allVals['cn'][0],'utf-8'), 'account_lastname' => lang('Group'), 'account_status' => 'A', ); @@ -808,12 +808,11 @@ class accounts_ldap } } // sort the array - $arrayFunctions =& CreateObject('phpgwapi.arrayfunctions'); - if(empty($param['order'])) - { - $param['order'] = 'account_lid'; - } - $account_search[$unl_serial]['data'] = $sortedAccounts = $arrayFunctions->arfsort($accounts,explode(',',$param['order']),$param['sort']); + $this->_callback_sort = strtoupper($param['sort']); + $this->_callback_order = empty($param['order']) ? array('account_lid') : explode(',',$param['order']); + uasort($sortedAccounts=$accounts,array($this,'_sort_callback')); + $account_search[$unl_serial]['data'] = $sortedAccounts; + $account_search[$unl_serial]['total'] = $this->total = isset($totalcount) ? $totalcount : count($accounts); } //echo "

accounts_ldap::search() found $this->total: ".microtime()."

\n"; @@ -827,6 +826,46 @@ class accounts_ldap return $sortedAccounts; } + /** + * DESC or ASC + * + * @var string + */ + private $_callback_sort = 'DESC'; + /** + * column_names to sort by + * + * @var array + */ + private $_callback_order = array('account_lid'); + + /** + * Sort callback for uasort + * + * @param array $a + * @param array $b + * @return int + */ + function _sort_callback($a,$b) + { + foreach($this->_callback_order as $col ) + { + if($this->_callback_sort == 'ASC') + { + $cmp = strcasecmp( $a[$col], $b[$col] ); + } + else + { + $cmp = strcasecmp( $b[$col], $a[$col] ); + } + if ( $cmp != 0 ) + { + return $cmp; + } + } + return 0; + } + /** * Creates a timestamp from the date returned by the ldap server * @@ -834,9 +873,9 @@ class accounts_ldap * @param string $date YYYYmmddHHiiss * @return int */ - protected function accounts_ldap2ts($date) + protected static function accounts_ldap2ts($date) { - if (isset($date) && strlen($date)>0) + if (!empty($date)) { return gmmktime(substr($date,8,2),substr($date,10,2),substr($date,12,2), substr($date,4,2),substr($date,6,2),substr($date,0,4));