Replace other user folders uids with display name (Bifrost#T216238)
Extends existing functionality that worked in kolab plugins' UI in a way that: - ldap lookups are optionally cached - replacing is done also in Mail/Settings parts of the UI - object_prettyname() uses the same technique as folders listings
This commit is contained in:
parent
9da21b887c
commit
acd1740a29
4 changed files with 177 additions and 48 deletions
|
@ -72,6 +72,11 @@ class kolab_folders extends rcube_plugin
|
|||
// ACL plugin hooks
|
||||
$this->add_hook('acl_rights_simple', array($this, 'acl_rights_simple'));
|
||||
$this->add_hook('acl_rights_supported', array($this, 'acl_rights_supported'));
|
||||
|
||||
// Resolving other user folder names
|
||||
$this->add_hook('render_mailboxlist', array($this, 'render_folderlist'));
|
||||
$this->add_hook('render_folder_selector', array($this, 'render_folderlist'));
|
||||
$this->add_hook('folders_list', array($this, 'render_folderlist'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -709,6 +714,7 @@ class kolab_folders extends rcube_plugin
|
|||
* Static getter for default folder of the given type
|
||||
*
|
||||
* @param string $type Folder type
|
||||
*
|
||||
* @return string Folder name
|
||||
*/
|
||||
public static function default_folder($type)
|
||||
|
@ -781,4 +787,74 @@ class kolab_folders extends rcube_plugin
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for various folders list widgets (hooks)
|
||||
*
|
||||
* @param array $args Hash array with hook parameters
|
||||
*
|
||||
* @return array Hash array with modified hook parameters
|
||||
*/
|
||||
public function render_folderlist($args)
|
||||
{
|
||||
$storage = $this->rc->get_storage();
|
||||
$ns_other = $storage->get_namespace('other');
|
||||
$is_fl = $this->rc->plugins->is_processing('folders_list');
|
||||
|
||||
foreach ((array) $ns_other as $root) {
|
||||
$delim = $root[1];
|
||||
$prefix = rtrim($root[0], $delim);
|
||||
$length = strlen($prefix);
|
||||
|
||||
if (!$length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// folders_list hook mode
|
||||
if ($is_fl) {
|
||||
foreach ((array) $args['list'] as $folder_name => $folder) {
|
||||
if (strpos($folder_name, $root[0]) === 0 && !substr_count($folder_name, $root[1], $length+1)) {
|
||||
if ($name = $this->folder_id2username(substr($folder_name, $length+1))) {
|
||||
$old = $args['list'][$folder_name]['display'];
|
||||
$content = $args['list'][$folder_name]['content'];
|
||||
|
||||
$name = rcube::Q($name);
|
||||
$content = str_replace(">$old<", ">$name<", $content);
|
||||
|
||||
$args['list'][$folder_name]['display'] = $name;
|
||||
$args['list'][$folder_name]['content'] = $content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Re-sort the list
|
||||
}
|
||||
// render_* hooks mode
|
||||
else if (!empty($args['list'][$prefix]) && !empty($args['list'][$prefix]['folders'])) {
|
||||
$map = array();
|
||||
foreach ($args['list'][$prefix]['folders'] as $folder_name => $folder) {
|
||||
if ($name = $this->folder_id2username($folder_name)) {
|
||||
$args['list'][$prefix]['folders'][$folder_name]['name'] = $name;
|
||||
}
|
||||
|
||||
$map[$folder_name] = $name ?: $args['list'][$prefix]['folders'][$folder_name]['name'];
|
||||
}
|
||||
|
||||
// Re-sort the list
|
||||
uasort($map, 'strcoll');
|
||||
$args['list'][$prefix]['folders'] = array_replace($map, $args['list'][$prefix]['folders']);
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map other user (imap) folder identifier to user name
|
||||
* @see kolab_storage::folder_id2user()
|
||||
*/
|
||||
private static function folder_id2username($uid)
|
||||
{
|
||||
return kolab_storage::folder_id2user($uid, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,18 @@ $config['kolab_users_id_attrib'] = null;
|
|||
// Use these attributes when searching users in LDAP
|
||||
$config['kolab_users_search_attrib'] = array('cn','mail','alias');
|
||||
|
||||
// Which property of the LDAP user record to use as a display name.
|
||||
// Defaults to the 'kolab_auth_name' configuration option.
|
||||
$config['kolab_users_name_field'] = null;
|
||||
|
||||
// Type of cache for uid-to-user map. Supported: 'db', 'apc', 'memcache' and 'memcached'.
|
||||
// Note: This stores only other user folder identifier to user attributes map.
|
||||
$config['kolab_users_cache'] = null;
|
||||
|
||||
// lifetime of shared folder mapping cache
|
||||
// possible units: s, m, h, d, w
|
||||
$config['kolab_users_cache_ttl'] = '10d';
|
||||
|
||||
// JSON-RPC endpoint configuration of the Bonnie web service providing historic data for groupware objects
|
||||
$config['kolab_bonnie_api'] = array(
|
||||
'uri' => 'https://<kolab-hostname>:8080/api/rpc',
|
||||
|
|
|
@ -46,12 +46,14 @@ class kolab_storage
|
|||
private static $ready = false;
|
||||
private static $with_tempsubs = true;
|
||||
private static $subscriptions;
|
||||
private static $ldapcache = array();
|
||||
private static $typedata = array();
|
||||
private static $states;
|
||||
private static $config;
|
||||
private static $imap;
|
||||
private static $ldap;
|
||||
|
||||
|
||||
// Default folder names
|
||||
private static $default_folders = array(
|
||||
'event' => 'Calendar',
|
||||
|
@ -354,7 +356,6 @@ class kolab_storage
|
|||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes IMAP folder
|
||||
*
|
||||
|
@ -421,7 +422,6 @@ class kolab_storage
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renames IMAP folder
|
||||
*
|
||||
|
@ -457,7 +457,6 @@ class kolab_storage
|
|||
return $success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rename or Create a new IMAP folder.
|
||||
*
|
||||
|
@ -552,7 +551,6 @@ class kolab_storage
|
|||
return $result ? $folder : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for human-readable name of Kolab object (folder)
|
||||
* with kolab_custom_display_names support.
|
||||
|
@ -637,20 +635,18 @@ class kolab_storage
|
|||
if (!$found && !empty($namespace['other'])) {
|
||||
foreach ($namespace['other'] as $ns) {
|
||||
if (strlen($ns[0]) && strpos($folder, $ns[0]) === 0) {
|
||||
// remove namespace prefix
|
||||
// remove namespace prefix and extract username
|
||||
$folder = substr($folder, strlen($ns[0]));
|
||||
$delim = $ns[1];
|
||||
// get username
|
||||
$pos = strpos($folder, $delim);
|
||||
if ($pos) {
|
||||
$prefix = '('.substr($folder, 0, $pos).')';
|
||||
$folder = substr($folder, $pos+1);
|
||||
}
|
||||
else {
|
||||
$prefix = '('.$folder.')';
|
||||
$folder = '';
|
||||
}
|
||||
|
||||
// get username part and map it to user name
|
||||
$pos = strpos($folder, $delim);
|
||||
$fid = $pos ? substr($folder, 0, $pos) : $folder;
|
||||
$fid = self::folder_id2user($fid, true);
|
||||
$fid = str_replace($delim, '', $fid);
|
||||
|
||||
$prefix = "($fid)";
|
||||
$folder = $pos ? substr($folder, $pos + 1) : '';
|
||||
$found = true;
|
||||
$folder_ns = 'other';
|
||||
break;
|
||||
|
@ -729,7 +725,6 @@ class kolab_storage
|
|||
return $name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SELECT field with folders list
|
||||
*
|
||||
|
@ -812,7 +807,6 @@ class kolab_storage
|
|||
return $select;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of folder names
|
||||
*
|
||||
|
@ -976,7 +970,6 @@ class kolab_storage
|
|||
return $folders;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sort the given list of kolab folders by namespace/name
|
||||
*
|
||||
|
@ -1006,7 +999,6 @@ class kolab_storage
|
|||
return $out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the folder tree and add the missing parents as virtual folders
|
||||
*
|
||||
|
@ -1082,7 +1074,6 @@ class kolab_storage
|
|||
return $_folders;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns folder types indexed by folder name
|
||||
*
|
||||
|
@ -1149,7 +1140,6 @@ class kolab_storage
|
|||
return self::$typedata[$prefix];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback for array_map to select the correct annotation value
|
||||
*/
|
||||
|
@ -1165,7 +1155,6 @@ class kolab_storage
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns type of IMAP folder
|
||||
*
|
||||
|
@ -1197,7 +1186,6 @@ class kolab_storage
|
|||
return 'mail';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets folder content-type.
|
||||
*
|
||||
|
@ -1220,7 +1208,6 @@ class kolab_storage
|
|||
return $success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check subscription status of this folder
|
||||
*
|
||||
|
@ -1242,7 +1229,6 @@ class kolab_storage
|
|||
($temp && in_array($folder, (array)$_SESSION['kolab_subscribed_folders']));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change subscription status of this folder
|
||||
*
|
||||
|
@ -1273,7 +1259,6 @@ class kolab_storage
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change subscription status of this folder
|
||||
*
|
||||
|
@ -1301,7 +1286,6 @@ class kolab_storage
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check activation status of this folder
|
||||
*
|
||||
|
@ -1316,7 +1300,6 @@ class kolab_storage
|
|||
return in_array($folder, $active_folders);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change activation status of this folder
|
||||
*
|
||||
|
@ -1331,7 +1314,6 @@ class kolab_storage
|
|||
return self::set_state($folder, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change activation status of this folder
|
||||
*
|
||||
|
@ -1347,7 +1329,6 @@ class kolab_storage
|
|||
return self::set_state($folder, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return list of active folders
|
||||
*/
|
||||
|
@ -1379,7 +1360,6 @@ class kolab_storage
|
|||
return self::$states;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update list of active folders
|
||||
*/
|
||||
|
@ -1504,7 +1484,6 @@ class kolab_storage
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $query Search value (or array of field => value pairs)
|
||||
|
@ -1544,7 +1523,6 @@ class kolab_storage
|
|||
return $results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of IMAP folders shared by the given user
|
||||
*
|
||||
|
@ -1584,7 +1562,6 @@ class kolab_storage
|
|||
return $folders;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of (virtual) top-level folders from the other users namespace
|
||||
*
|
||||
|
@ -1635,7 +1612,6 @@ class kolab_storage
|
|||
return $folders;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for user_delete plugin hooks
|
||||
*
|
||||
|
@ -1673,4 +1649,79 @@ class kolab_storage
|
|||
return $metadata[$folder];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user attributes for specified other user (imap) folder identifier.
|
||||
* Note: This uses LDAP config/code from kolab_auth.
|
||||
*
|
||||
* @param string $folder_id Folder name w/o path (imap user identifier)
|
||||
* @param bool $as_string Return configured display name attribute value
|
||||
*
|
||||
* @return array User attributes
|
||||
* @see self::ldap()
|
||||
*/
|
||||
public static function folder_id2user($folder_id, $as_string = false)
|
||||
{
|
||||
static $domain, $cache, $name_attr;
|
||||
|
||||
$rcube = rcube::get_instance();
|
||||
|
||||
if ($domain === null) {
|
||||
list(, $domain) = explode('@', $rcube->get_user_name());
|
||||
}
|
||||
|
||||
if ($name_attr === null) {
|
||||
$name_attr = (array) (self::$config->get('kolab_users_name_field', self::$config->get('kolab_auth_name')) ?: 'name');
|
||||
}
|
||||
|
||||
$token = $folder_id;
|
||||
if ($domain && strpos($find, '@') === false) {
|
||||
$token .= '@' . $domain;
|
||||
}
|
||||
|
||||
if ($cache === null) {
|
||||
$cache = $rcube->get_cache_shared('kolab_users') ?: false;
|
||||
}
|
||||
|
||||
// use value cached in memory for repeated lookups
|
||||
if (!$cache && array_key_exists($token, self::$ldapcache)) {
|
||||
$user = self::$ldapcache[$token];
|
||||
}
|
||||
|
||||
if (empty($user) && $cache) {
|
||||
$user = $cache->get($token);
|
||||
}
|
||||
|
||||
if (empty($user) && ($ldap = kolab_storage::ldap())) {
|
||||
$user = $ldap->get_user_record($token, $_SESSION['imap_host']);
|
||||
|
||||
if (!empty($user)) {
|
||||
$keys = array('displayname', 'name', 'mail'); // supported keys
|
||||
$user = array_intersect_key($user, array_flip($keys));
|
||||
|
||||
if (!empty($user)) {
|
||||
if ($cache) {
|
||||
$cache->set($token, $user);
|
||||
}
|
||||
else {
|
||||
self::$ldapcache[$token] = $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($user)) {
|
||||
if ($as_string) {
|
||||
foreach ($name_attr as $attr) {
|
||||
if ($name = $user[$attr]) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $user['displayname'] ?: $user['name'];
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
*/
|
||||
class kolab_storage_folder_user extends kolab_storage_folder_virtual
|
||||
{
|
||||
protected static $ldapcache = array();
|
||||
|
||||
public $ldaprec;
|
||||
public $type;
|
||||
|
||||
|
@ -36,21 +34,13 @@ class kolab_storage_folder_user extends kolab_storage_folder_virtual
|
|||
parent::__construct($name, kolab_storage::object_prettyname($name), 'other', $parent);
|
||||
|
||||
if (!empty($ldaprec)) {
|
||||
self::$ldapcache[$name] = $this->ldaprec = $ldaprec;
|
||||
$this->ldaprec = $ldaprec;
|
||||
}
|
||||
// use value cached in memory for repeated lookups
|
||||
else if (array_key_exists($name, self::$ldapcache)) {
|
||||
$this->ldaprec = self::$ldapcache[$name];
|
||||
}
|
||||
// lookup user in LDAP and set $this->ldaprec
|
||||
else if ($ldap = kolab_storage::ldap()) {
|
||||
// get domain from current user
|
||||
list(,$domain) = explode('@', rcube::get_instance()->get_user_name());
|
||||
$this->ldaprec = $ldap->get_user_record(parent::get_foldername($this->name) . '@' . $domain, $_SESSION['imap_host']);
|
||||
else {
|
||||
$this->ldaprec = kolab_storage::folder_id2user(parent::get_foldername($this->name));
|
||||
if (!empty($this->ldaprec)) {
|
||||
$this->ldaprec['kolabtargetfolder'] = $name;
|
||||
}
|
||||
self::$ldapcache[$name] = $this->ldaprec;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue