- Fix so folders with \Noinferiors attribute aren't listed in parent selector

- Add LIST result and folder attributes cache
- rcmail_render_folder_tree_select(): fix 'exceptions' parameter, add 'skip_noinferiors' option
pull/1/head
alecpl 13 years ago
parent 06744da241
commit aa07b22906

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail CHANGELOG Roundcube Webmail
=========================== ===========================
- Fix so folders with \Noinferiors attribute aren't listed in parent selector
- Fix handling of curly brackets in URLs (#1488168) - Fix handling of curly brackets in URLs (#1488168)
- Fix handling of dates (birthday/anniversary) in contact data (#1488147) - Fix handling of dates (birthday/anniversary) in contact data (#1488147)
- Fix error on opening searched LDAP contact (#1488144) - Fix error on opening searched LDAP contact (#1488144)

@ -1232,7 +1232,7 @@ function rcmail_mailbox_select($p = array())
if ($p['noselection']) if ($p['noselection'])
$select->add($p['noselection'], ''); $select->add($p['noselection'], '');
rcmail_render_folder_tree_select($a_mailboxes, $mbox, $p['maxlength'], $select, $p['realnames'], 0, $p['exceptions']); rcmail_render_folder_tree_select($a_mailboxes, $mbox, $p['maxlength'], $select, $p['realnames'], 0, $p);
return $select; return $select;
} }
@ -1281,9 +1281,9 @@ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='')
$path .= $prefix.$currentFolder; $path .= $prefix.$currentFolder;
if (!isset($arrFolders[$currentFolder])) { if (!isset($arrFolders[$currentFolder])) {
// Check \Noselect option (if options are in cache) // Check \Noselect attribute (if attributes are in cache)
if (!$virtual && ($opts = $RCMAIL->imap->mailbox_options($path))) { if (!$virtual && ($attrs = $RCMAIL->imap->mailbox_attributes($path))) {
$virtual = in_array('\\Noselect', $opts); $virtual = in_array('\\Noselect', $attrs);
} }
$arrFolders[$currentFolder] = array( $arrFolders[$currentFolder] = array(
@ -1402,30 +1402,40 @@ function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, &$jslist, $at
* @access private * @access private
* @return string * @return string
*/ */
function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0, $exceptions=array()) function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0, $opts=array())
{ {
global $RCMAIL;
$out = ''; $out = '';
foreach ($arrFolders as $key => $folder) { foreach ($arrFolders as $key => $folder) {
if (empty($exceptions) || !in_array($folder['id'], $exceptions)) { // skip exceptions (and its subfolders)
if (!$realnames && ($folder_class = rcmail_folder_classname($folder['id']))) if (!empty($opts['exceptions']) && in_array($folder['id'], $opts['exceptions'])) {
$foldername = rcube_label($folder_class); continue;
else {
$foldername = $folder['name'];
// shorten the folder name to a given length
if ($maxlength && $maxlength>1)
$foldername = abbreviate_string($foldername, $maxlength);
}
$select->add(str_repeat(' ', $nestLevel*4) . $foldername, $folder['id']);
} }
else if ($nestLevel)
// skip folders in which it isn't possible to create subfolders
if (!empty($opts['skip_noinferiors']) && ($attrs = $RCMAIL->imap->mailbox_attributes($folder['id']))
&& in_array('\\Noinferiors', $attrs)
) {
continue; continue;
}
if (!$realnames && ($folder_class = rcmail_folder_classname($folder['id'])))
$foldername = rcube_label($folder_class);
else {
$foldername = $folder['name'];
// shorten the folder name to a given length
if ($maxlength && $maxlength>1)
$foldername = abbreviate_string($foldername, $maxlength);
}
$select->add(str_repeat(' ', $nestLevel*4) . $foldername, $folder['id']);
if (!empty($folder['folders'])) if (!empty($folder['folders']))
$out .= rcmail_render_folder_tree_select($folder['folders'], $mbox_name, $maxlength, $out .= rcmail_render_folder_tree_select($folder['folders'], $mbox_name, $maxlength,
$select, $realnames, $nestLevel+1, $exceptions); $select, $realnames, $nestLevel+1, $opts);
} }
return $out; return $out;

@ -3087,7 +3087,19 @@ class rcube_imap
*/ */
function list_unsubscribed($root='', $name='*', $filter=null, $rights=null, $skip_sort=false) function list_unsubscribed($root='', $name='*', $filter=null, $rights=null, $skip_sort=false)
{ {
// @TODO: caching $cache_key = $root.':'.$name;
if (!empty($filter)) {
$cache_key .= ':'.(is_string($filter) ? $filter : serialize($filter));
}
$cache_key .= ':'.$rights;
$cache_key = 'mailboxes.list.'.md5($cache_key);
// get cached folder list
$a_mboxes = $this->get_cache($cache_key);
if (is_array($a_mboxes)) {
return $a_mboxes;
}
// Give plugins a chance to provide a list of mailboxes // Give plugins a chance to provide a list of mailboxes
$data = rcmail::get_instance()->plugins->exec_hook('mailboxes_list', $data = rcmail::get_instance()->plugins->exec_hook('mailboxes_list',
array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LIST')); array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LIST'));
@ -3109,6 +3121,11 @@ class rcube_imap
array_unshift($a_mboxes, 'INBOX'); array_unshift($a_mboxes, 'INBOX');
} }
// cache folder attributes
if ($root == '' && $name == '*' && empty($filter)) {
$this->update_cache('mailboxes.attributes', $this->conn->data['LIST']);
}
// filter folders list according to rights requirements // filter folders list according to rights requirements
if ($rights && $this->get_capability('ACL')) { if ($rights && $this->get_capability('ACL')) {
$a_folders = $this->filter_rights($a_folders, $rights); $a_folders = $this->filter_rights($a_folders, $rights);
@ -3119,6 +3136,9 @@ class rcube_imap
$a_mboxes = $this->_sort_mailbox_list($a_mboxes); $a_mboxes = $this->_sort_mailbox_list($a_mboxes);
} }
// write mailboxlist to cache
$this->update_cache($cache_key, $a_mboxes);
return $a_mboxes; return $a_mboxes;
} }
@ -3450,30 +3470,29 @@ class rcube_imap
/** /**
* Gets folder options from LIST response, e.g. \Noselect, \Noinferiors * Gets folder attributes from LIST response, e.g. \Noselect, \Noinferiors
* *
* @param string $mailbox Folder name * @param string $mailbox Folder name
* @param bool $force Set to True if options should be refreshed * @param bool $force Set to True if attributes should be refreshed
* Options are available after LIST command only
* *
* @return array Options list * @return array Options list
*/ */
function mailbox_options($mailbox, $force=false) function mailbox_attributes($mailbox, $force=false)
{ {
if ($mailbox == 'INBOX') { // get attributes directly from LIST command
return array(); if (!empty($this->conn->data['LIST']) && is_array($this->conn->data['LIST'][$mailbox])) {
$opts = $this->conn->data['LIST'][$mailbox];
} }
// get cached folder attributes
if (!is_array($this->conn->data['LIST']) || !is_array($this->conn->data['LIST'][$mailbox])) { else if (!$force) {
if ($force) { $opts = $this->get_cache('mailboxes.attributes');
$this->conn->listMailboxes('', $mailbox); $opts = $opts[$mailbox];
}
else {
return array();
}
} }
$opts = $this->conn->data['LIST'][$mailbox]; if (!is_array($opts)) {
$this->conn->listMailboxes('', $mailbox);
$opts = $this->conn->data['LIST'][$mailbox];
}
return is_array($opts) ? $opts : array(); return is_array($opts) ? $opts : array();
} }
@ -3556,17 +3575,17 @@ class rcube_imap
} }
} }
$options['name'] = $mailbox; $options['name'] = $mailbox;
$options['options'] = $this->mailbox_options($mailbox, true); $options['attributes'] = $this->mailbox_attributes($mailbox, true);
$options['namespace'] = $this->mailbox_namespace($mailbox); $options['namespace'] = $this->mailbox_namespace($mailbox);
$options['rights'] = $acl && !$options['is_root'] ? (array)$this->my_rights($mailbox) : array(); $options['rights'] = $acl && !$options['is_root'] ? (array)$this->my_rights($mailbox) : array();
$options['special'] = in_array($mailbox, $this->default_folders); $options['special'] = in_array($mailbox, $this->default_folders);
// Set 'noselect' and 'norename' flags // Set 'noselect' and 'norename' flags
if (is_array($options['options'])) { if (is_array($options['attributes'])) {
foreach ($options['options'] as $opt) { foreach ($options['attributes'] as $attrib) {
$opt = strtolower($opt); $attrib = strtolower($attrib);
if ($opt == '\noselect' || $opt == '\nonexistent') { if ($attrib == '\noselect' || $attrib == '\nonexistent') {
$options['noselect'] = true; $options['noselect'] = true;
} }
} }

@ -2258,13 +2258,11 @@ class rcube_imap_generic
} }
// Add to options array // Add to options array
if (!empty($opts)) { if (empty($this->data['LIST'][$mailbox]))
if (empty($this->data['LIST'][$mailbox])) $this->data['LIST'][$mailbox] = $opts;
$this->data['LIST'][$mailbox] = $opts; else if (!empty($opts))
else $this->data['LIST'][$mailbox] = array_unique(array_merge(
$this->data['LIST'][$mailbox] = array_unique(array_merge( $this->data['LIST'][$mailbox], $opts));
$this->data['LIST'][$mailbox], $opts));
}
} }
// * STATUS <mailbox> (<result>) // * STATUS <mailbox> (<result>)
else if ($cmd == 'STATUS') { else if ($cmd == 'STATUS') {

@ -119,7 +119,8 @@ function rcmail_folder_form($attrib)
'realnames' => false, 'realnames' => false,
'maxlength' => 150, 'maxlength' => 150,
'unsubscribed' => true, 'unsubscribed' => true,
'exceptions' => array($mbox_imap), 'skip_noinferiors' => true,
'exceptions' => array($mbox_imap),
)); ));
$form['props']['fieldsets']['location']['content']['path'] = array( $form['props']['fieldsets']['location']['content']['path'] = array(

@ -283,8 +283,8 @@ function rcube_subscription_form($attrib)
} }
if (!$protected) { if (!$protected) {
$opts = $IMAP->mailbox_options($folder['id']); $attrs = $IMAP->mailbox_attributes($folder['id']);
$noselect = in_array('\\Noselect', $opts); $noselect = in_array('\\Noselect', $attrs);
} }
$disabled = (($protected && $subscribed) || $noselect); $disabled = (($protected && $subscribed) || $noselect);

Loading…
Cancel
Save