From 4ceff8f35375738c73db48e713fe56313794a4a1 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Sun, 30 Aug 2015 11:36:06 +0200 Subject: [PATCH] Make optional hidding of folders with name starting with a dot - imap_skip_hidden_folders (#1490468) --- CHANGELOG | 1 + config/defaults.inc.php | 5 +++ program/lib/Roundcube/rcube_imap.php | 42 +++++++++++++++---------- program/localization/en_US/messages.inc | 1 + program/steps/settings/save_folder.inc | 3 ++ 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 75242e983..fdb507d04 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Make optional hidding of folders with name starting with a dot - imap_skip_hidden_folders (#1490468) - Add option to enable HTML editor always, except when replying to plain text messages (#1489365) - Emoticons: Added option to switch on/off emoticons in compose editor (#1485732) - Emoticons: Added option to switch on/off emoticons in plain text messages diff --git a/config/defaults.inc.php b/config/defaults.inc.php index 76469350d..178a6e9ed 100644 --- a/config/defaults.inc.php +++ b/config/defaults.inc.php @@ -191,6 +191,11 @@ $config['imap_force_lsub'] = false; // Enable this option to force listing of folders in all namespaces $config['imap_force_ns'] = false; +// Some servers return hidden folders (name starting witha dot) +// from user home directory. IMAP RFC does not forbid that. +// Enable this option to hide them and disable possibility to create such. +$config['imap_skip_hidden_folders'] = false; + // List of disabled imap extensions. // Use if your IMAP server has broken implementation of some feature // and you can't remove it from CAPABILITY string on server-side. diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php index b8230a7d4..6ecb8df25 100644 --- a/program/lib/Roundcube/rcube_imap.php +++ b/program/lib/Roundcube/rcube_imap.php @@ -2806,42 +2806,47 @@ class rcube_imap extends rcube_storage $list_extended = !$config->get('imap_force_lsub') && $this->get_capability('LIST-EXTENDED'); if ($list_extended) { // This will also set folder options, LSUB doesn't do that - $a_folders = $this->conn->listMailboxes($root, $name, + $result = $this->conn->listMailboxes($root, $name, NULL, array('SUBSCRIBED')); } else { // retrieve list of folders from IMAP server using LSUB - $a_folders = $this->conn->listSubscribed($root, $name); + $result = $this->conn->listSubscribed($root, $name); } - if (!is_array($a_folders)) { + if (!is_array($result)) { return array(); } // #1486796: some server configurations doesn't return folders in all namespaces if ($root == '' && $name == '*' && $config->get('imap_force_ns')) { - $this->list_folders_update($a_folders, ($list_extended ? 'ext-' : '') . 'subscribed'); + $this->list_folders_update($result, ($list_extended ? 'ext-' : '') . 'subscribed'); + } + + // Remove hidden folders + if ($config->get('imap_skip_hidden_folders')) { + $result = array_filter($result, function($v) { return $v[0] != '.'; }); } if ($list_extended) { // unsubscribe non-existent folders, remove from the list - if (is_array($a_folders) && $name == '*' && !empty($this->conn->data['LIST'])) { - foreach ($a_folders as $idx => $folder) { + if ($name == '*' && !empty($this->conn->data['LIST'])) { + foreach ($result as $idx => $folder) { if (($opts = $this->conn->data['LIST'][$folder]) && in_array_nocase('\\NonExistent', $opts) ) { $this->conn->unsubscribe($folder); - unset($a_folders[$idx]); + unset($result[$idx]); } } } } else { // unsubscribe non-existent folders, remove them from the list - if (is_array($a_folders) && !empty($a_folders) && $name == '*') { + if (!empty($result) && $name == '*') { $existing = $this->list_folders($root, $name); - $nonexisting = array_diff($a_folders, $existing); - $a_folders = array_diff($a_folders, $nonexisting); + $nonexisting = array_diff($result, $existing); + $result = array_diff($result, $nonexisting); foreach ($nonexisting as $folder) { $this->conn->unsubscribe($folder); @@ -2849,7 +2854,7 @@ class rcube_imap extends rcube_storage } } - return $a_folders; + return $result; } /** @@ -2948,6 +2953,11 @@ class rcube_imap extends rcube_storage $this->list_folders_update($result); } + // Remove hidden folders + if ($config->get('imap_skip_hidden_folders')) { + $result = array_filter($result, function($v) { return $v[0] != '.'; }); + } + return $result; } @@ -4094,13 +4104,11 @@ class rcube_imap extends rcube_storage $specials = array_merge(array('INBOX'), array_values($this->get_special_folders())); $folders = array(); - // convert names to UTF-8 and skip folders starting with '.' + // convert names to UTF-8 foreach ($a_folders as $folder) { - if ($folder[0] != '.') { - // for better performance skip encoding conversion - // if the string does not look like UTF7-IMAP - $folders[$folder] = strpos($folder, '&') === false ? $folder : rcube_charset::convert($folder, 'UTF7-IMAP'); - } + // for better performance skip encoding conversion + // if the string does not look like UTF7-IMAP + $folders[$folder] = strpos($folder, '&') === false ? $folder : rcube_charset::convert($folder, 'UTF7-IMAP'); } // sort folders diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc index 621b7eafd..a8ebf88be 100644 --- a/program/localization/en_US/messages.inc +++ b/program/localization/en_US/messages.inc @@ -171,6 +171,7 @@ $messages['autocompletechars'] = 'Enter at least $min characters for autocomplet $messages['autocompletemore'] = 'More matching entries found. Please type more characters.'; $messages['namecannotbeempty'] = 'Name cannot be empty.'; $messages['nametoolong'] = 'Name is too long.'; +$messages['namedotforbidden'] = 'Folder name cannot start with a dot.'; $messages['folderupdated'] = 'Folder updated successfully.'; $messages['foldercreated'] = 'Folder created successfully.'; $messages['invalidimageformat'] = 'Not a valid image format.'; diff --git a/program/steps/settings/save_folder.inc b/program/steps/settings/save_folder.inc index e983a2f0c..879f5e864 100644 --- a/program/steps/settings/save_folder.inc +++ b/program/steps/settings/save_folder.inc @@ -42,6 +42,9 @@ else if (!strlen($name)) { else if (mb_strlen($name) > 128) { $error = $RCMAIL->gettext('nametoolong'); } +else if ($name[0] == '.' && $RCMAIL->config->get('imap_skip_hidden_folders')) { + $error = $RCMAIL->gettext('namedotforbidden'); +} else { // these characters are problematic e.g. when used in LIST/LSUB foreach (array($delimiter, '%', '*') as $char) {