From a5a4bf46bd2e579e828989563c120f9ab2b28a32 Mon Sep 17 00:00:00 2001 From: alecpl Date: Mon, 25 Oct 2010 12:39:36 +0000 Subject: [PATCH] - Add basic IMAP LIST's \Noselect option support (mark unselectable folders as virtual, etc.) --- CHANGELOG | 1 + program/include/main.inc | 8 +++++++ program/include/rcube_imap.php | 25 ++++++++++++++++++++++ program/include/rcube_imap_generic.php | 15 +++++++++++-- program/steps/settings/manage_folders.inc | 26 +++++++++++++++-------- 5 files changed, 64 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 48daaa150..30868f1f6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -48,6 +48,7 @@ CHANGELOG Roundcube Webmail - Add support for IMAP proxy authentication (#1486690) - Add support for AUTH=DIGEST-MD5 in IMAP (RFC 2831) - Fix parent folder with unread subfolder not bold when message is open (#1487078) +- Add basic IMAP LIST's \Noselect option support RELEASE 0.4.2 ------------- diff --git a/program/include/main.inc b/program/include/main.inc index 46e45f7cb..7e96233bc 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -1332,6 +1332,8 @@ function rcmail_mailbox_select($p = array()) */ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='') { + global $RCMAIL; + $pos = strpos($folder, $delm); if ($pos !== false) { @@ -1354,6 +1356,12 @@ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='') $path .= $currentFolder; + // Check \Noselect option + if (!$virtual) { + $opts = $RCMAIL->imap->mailbox_options($path); + $virtual = in_array('\\Noselect', $opts); + } + if (!isset($arrFolders[$currentFolder])) { $arrFolders[$currentFolder] = array( 'id' => $path, diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 7fbff37f1..46427d6cf 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -3120,6 +3120,31 @@ class rcube_imap } + /** + * Gets folder options from LIST/LSUB response, e.g. \Noselect, \Noinferiors + * + * @param string $mbox_name Folder name + * + * @return array Options list + */ + function mailbox_options($mbox_name) + { + $mbox = $this->mod_mailbox($mbox_name); + + if ($mbox == 'INBOX') { + return array(); + } + + if (!is_array($this->conn->data['LIST']) || !is_array($this->conn->data['LIST'][$mbox])) { + $this->conn->listMailboxes($this->mod_mailbox(''), $mbox_name); + } + + $opts = $this->conn->data['LIST'][$mbox]; + + return is_array($opts) ? $opts : array(); + } + + /** * Get message header names for rcube_imap_generic::fetchHeader(s) * diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php index 9009d125d..d51b8cfbe 100644 --- a/program/include/rcube_imap_generic.php +++ b/program/include/rcube_imap_generic.php @@ -857,6 +857,12 @@ class rcube_imap_generic return true; } + if (is_array($this->data['LIST']) && is_array($opts = $this->data['LIST'][$mailbox])) { + if (in_array('\\Noselect', $opts)) { + return false; + } + } + list($code, $response) = $this->execute('SELECT', array($this->escape($mailbox))); if ($code == self::ERROR_OK) { @@ -1861,11 +1867,11 @@ class rcube_imap_generic if (empty($mailbox)) { $mailbox = '*'; } -/* + if (empty($ref) && $this->prefs['rootdir']) { $ref = $this->prefs['rootdir']; } -*/ + $args = array($this->escape($ref), $this->escape($mailbox)); if (!empty($status_opts) && $this->getCapability('LIST-STATUS')) { @@ -1884,12 +1890,17 @@ class rcube_imap_generic // * LIST () if (!$lstatus || $cmd == 'LIST' || $cmd == 'LSUB') { list($opts, $delim, $folder) = $this->tokenizeResponse($response, 3); + if (!$lstatus) { $folders[] = $folder; } else { $folders[$folder] = array(); } + + if ($cmd == 'LIST') { + $this->data['LIST'][$folder] = $opts; + } } // * STATUS () else if ($cmd == 'STATUS') { diff --git a/program/steps/settings/manage_folders.inc b/program/steps/settings/manage_folders.inc index 4a0bb6984..1dd459aef 100644 --- a/program/steps/settings/manage_folders.inc +++ b/program/steps/settings/manage_folders.inc @@ -221,7 +221,7 @@ function rcube_subscription_form($attrib) $a_subscribed = $IMAP->list_mailboxes(); $a_threaded = $a_threaded_copy = $RCMAIL->config->get('message_threading', array()); $delimiter = $IMAP->get_hierarchy_delimiter(); - $a_js_folders = $seen_folders = $list_folders = array(); + $a_js_folders = $seen = $list_folders = array(); // pre-process folders list foreach ($a_unsubscribed as $i => $folder) { @@ -233,11 +233,11 @@ function rcube_subscription_form($attrib) // add any necessary "virtual" parent folders if ($parent_folder && !$seen[$parent_folder]) { for ($i=1; $i<=$level; $i++) { - $ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i)); - if ($ancestor_folder && !$seen[$ancestor_folder]++) { - $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF7-IMAP'); - $list_folders[] = array('id' => $ancestor_folder, 'name' => $ancestor_name, 'level' => $i-1, 'virtual' => true); - } + $ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i)); + if ($ancestor_folder && !$seen[$ancestor_folder]++) { + $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF7-IMAP'); + $list_folders[] = array('id' => $ancestor_folder, 'name' => $ancestor_name, 'level' => $i-1, 'virtual' => true); + } } } @@ -247,6 +247,8 @@ function rcube_subscription_form($attrib) $seen[$folder]++; } + unset($seen); + // remove 'message_threading' option for not existing folders if ($a_threaded_copy) { foreach ($a_threaded_copy as $key => $val) @@ -285,15 +287,21 @@ function rcube_subscription_form($attrib) $display_folder = str_repeat('    ', $folder['level']) . ($protected ? rcmail_localize_foldername($folder['id']) : $folder['name']); $folder_utf8 = rcube_charset_convert($folder['id'], 'UTF7-IMAP'); - if ($folder['virtual']) + if ($folder['virtual']) { $classes[] = 'virtual'; - + } + + if (!$protected) { + $opts = $IMAP->mailbox_options($folder['id']); + $noselect = in_array('\\Noselect', $opts); + } + $table->add_row(array('id' => 'rcmrow'.$idx, 'class' => join(' ', $classes))); $table->add('name', Q($display_folder)); $table->add('msgcount', ($folder['virtual'] ? '' : $IMAP->messagecount($folder['id'], 'ALL', false, false))); $table->add('subscribed', $checkbox_subscribe->show(($subscribed ? $folder_utf8 : ''), - array('value' => $folder_utf8, 'disabled' => $protected ? 'disabled' : ''))); + array('value' => $folder_utf8, 'disabled' => ($protected || $noselect) ? 'disabled' : ''))); if ($threading_supported) { $table->add('threaded', $folder['virtual'] ? '' : $checkbox_threaded->show(($threaded ? $folder_utf8 : ''), array('value' => $folder_utf8)));