diff --git a/lib/drivers/kolab/kolab_file_autocomplete.php b/lib/drivers/kolab/kolab_file_autocomplete.php index dc4b197..b710cbc 100644 --- a/lib/drivers/kolab/kolab_file_autocomplete.php +++ b/lib/drivers/kolab/kolab_file_autocomplete.php @@ -1,171 +1,221 @@ | +--------------------------------------------------------------------------+ | Author: Aleksander Machniak | +--------------------------------------------------------------------------+ */ class kolab_file_autocomplete { private $rc; private $ldap; /** * Class constructor */ public function __construct() { $this->rc = rcube::get_instance(); } /** * Search users/groups */ public function search($search, $with_groups = false) { if (!$this->init_ldap()) { return false; } $max = (int) $this->rc->config->get('autocomplete_max', 15); $mode = (int) $this->rc->config->get('addressbook_search_mode'); $me = $this->rc->get_user_name(); $this->ldap->set_pagesize($max); $result = $this->ldap->search('*', $search, $mode); $users = array(); $index = array(); foreach ($result->records as $record) { $user = $record['uid']; if (is_array($user)) { $user = array_filter($user); $user = $user[0]; } if (in_array($me, rcube_addressbook::get_col_values('email', $record, true))) { continue; } if ($user) { $display = rcube_addressbook::compose_search_name($record); $user = array('name' => $user, 'display' => $display); $users[] = $user; $index[] = $display ?: $user['name']; } } $group_support = $this->rc->config->get('fileapi_groups'); $group_prefix = $this->rc->config->get('fileapi_group_prefix'); $group_field = $this->rc->config->get('fileapi_group_field', 'name'); if ($with_groups && $group_support && $group_field) { $result = $this->ldap->list_groups($search, $mode); foreach ($result as $record) { $group = $record['name']; $group_id = is_array($record[$group_field]) ? $record[$group_field][0] : $record[$group_field]; if ($group) { $users[] = array('name' => ($group_prefix ? $group_prefix : '') . $group_id, 'display' => $group, 'type' => 'group'); $index[] = $group; } } } if (count($users)) { array_multisort($index, SORT_ASC, SORT_LOCALE_STRING, $users); } if (count($users) > $max) { $users = array_slice($users, 0, $max); } return $users; } + /** + * Resolve acl identifier to user/group name + */ + public function resolve_uid($id, &$title = null) + { + $groups = $this->rc->config->get('acl_groups'); + $prefix = $this->rc->config->get('acl_group_prefix'); + $group_field = $this->rc->config->get('acl_group_field', 'name'); + + if ($groups && $prefix && strpos($id, $prefix) === 0) { + $gid = substr($id, strlen($prefix)); + + // Unfortunately this works only if group_field=name, + // list_groups() allows searching by group name only + if ($group_field === 'name' && $this->init_ldap()) { + $result = $this->ldap->list_groups($gid, rcube_addressbook::SEARCH_STRICT); + + if (count($result) === 1 && ($record = $result[0])) { + if ($record[$group_field] === $gid) { + $display = $record['name']; + if ($display != $gid) { + $title = sprintf('%s (%s)', $display, $gid); + } + + return $display; + } + } + } + + return $gid; + } + + if ($this->init_ldap()) { + $this->ldap->set_pagesize('2'); + // Note: 'uid' works here because we overwrite fieldmap in init_ldap() above + $result = $this->ldap->search('uid', $id, rcube_addressbook::SEARCH_STRICT); + + if ($result->count === 1 && ($record = $result->first())) { + if ($record['uid'] === $id) { + $title = rcube_addressbook::compose_search_name($record); + $display = rcube_addressbook::compose_list_name($record); + + return $display; + } + } + } + + return $id; + } + /** * Initializes autocomplete LDAP backend */ private function init_ldap() { if ($this->ldap) { return $this->ldap->ready; } // get LDAP config $config = $this->rc->config->get('fileapi_users_source'); if (empty($config)) { return false; } // not an array, use configured ldap_public source if (!is_array($config)) { $ldap_config = (array) $this->rc->config->get('ldap_public'); $config = $ldap_config[$config]; } $uid_field = $this->rc->config->get('fileapi_users_field', 'mail'); $filter = $this->rc->config->get('fileapi_users_filter'); $debug = $this->rc->config->get('ldap_debug'); $domain = $this->rc->config->mail_domain($_SESSION['imap_host']); if (empty($uid_field) || empty($config)) { return false; } // get name attribute if (!empty($config['fieldmap'])) { $name_field = $config['fieldmap']['name']; } // ... no fieldmap, use the old method if (empty($name_field)) { $name_field = $config['name_field']; } // add UID field to fieldmap, so it will be returned in a record with name $config['fieldmap']['name'] = $name_field; $config['fieldmap']['uid'] = $uid_field; // search in UID and name fields // $name_field can be in a form of : (#1490591) $name_field = preg_replace('/:.*$/', '', $name_field); $search = array_unique(array($name_field, $uid_field)); $config['search_fields'] = $search; $config['required_fields'] = array($uid_field); // set search filter if ($filter) { $config['filter'] = $filter; } // disable vlv $config['vlv'] = false; // Initialize LDAP connection $this->ldap = new rcube_ldap($config, $debug, $domain); return $this->ldap->ready; } }