From 4ceff8f35375738c73db48e713fe56313794a4a1 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Sun, 30 Aug 2015 05:36:06 -0400
Subject: [PATCH] Make optional hidding of folders with name starting with a dot - imap_skip_hidden_folders (#1490468)

---
 CHANGELOG                               |    1 +
 program/lib/Roundcube/rcube_imap.php    |   42 +++++++++++++++++++++++++-----------------
 program/localization/en_US/messages.inc |    1 +
 program/steps/settings/save_folder.inc  |    3 +++
 config/defaults.inc.php                 |    5 +++++
 5 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 75242e9..fdb507d 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 7646935..178a6e9 100644
--- a/config/defaults.inc.php
+++ b/config/defaults.inc.php
@@ -191,6 +191,11 @@
 // 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 b8230a7..6ecb8df 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -2806,42 +2806,47 @@
         $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 @@
             }
         }
 
-        return $a_folders;
+        return $result;
     }
 
     /**
@@ -2946,6 +2951,11 @@
         // #1486796: some server configurations doesn't return folders in all namespaces
         if ($root == '' && $name == '*' && $config->get('imap_force_ns')) {
             $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 @@
         $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 621b7ea..a8ebf88 100644
--- a/program/localization/en_US/messages.inc
+++ b/program/localization/en_US/messages.inc
@@ -171,6 +171,7 @@
 $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 e983a2f..879f5e8 100644
--- a/program/steps/settings/save_folder.inc
+++ b/program/steps/settings/save_folder.inc
@@ -42,6 +42,9 @@
 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) {

--
Gitblit v1.9.1