diff options
author | alecpl <alec@alec.pl> | 2010-10-26 13:44:39 +0000 |
---|---|---|
committer | alecpl <alec@alec.pl> | 2010-10-26 13:44:39 +0000 |
commit | 3870bec7ff891677fd848df8d027171acf921420 (patch) | |
tree | 6ecb2eb47f02cf8f8685125cf41e4a132122bac6 /program | |
parent | 10a6fc58e6e8a40388ffda43f949f69f5ec804dc (diff) |
- Add support for selection options from LIST-EXTENDED extension (RFC 5258)
- Don't list subscribed but non-existent folders (#1486225)
- Fix \Noselect handling performance (#1487082)
Diffstat (limited to 'program')
-rw-r--r-- | program/include/main.inc | 5 | ||||
-rw-r--r-- | program/include/rcube_imap.php | 36 | ||||
-rw-r--r-- | program/include/rcube_imap_generic.php | 37 |
3 files changed, 61 insertions, 17 deletions
diff --git a/program/include/main.inc b/program/include/main.inc index 7e96233bc..242fb1ac3 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -1356,9 +1356,8 @@ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='') $path .= $currentFolder; - // Check \Noselect option - if (!$virtual) { - $opts = $RCMAIL->imap->mailbox_options($path); + // Check \Noselect option (if options are in cache) + if (!$virtual && ($opts = $RCMAIL->imap->mailbox_options($path))) { $virtual = in_array('\\Noselect', $opts); } diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 556441dcb..a4b18c970 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -2816,8 +2816,27 @@ class rcube_imap $a_folders = $data['folders']; } else { - // retrieve list of folders from IMAP server - $a_folders = $this->conn->listSubscribed($this->mod_mailbox($root), $filter); + // Server supports LIST-EXTENDED, we can use selection options + if ($this->get_capability('LIST-EXTENDED')) { + // This will also set mailbox options, LSUB doesn't do that + $a_folders = $this->conn->listMailboxes($this->mod_mailbox($root), $filter, + NULL, array('SUBSCRIBED')); + + // remove non-existent folders + if (is_array($a_folders)) { + foreach ($a_folders as $idx => $folder) { + if ($this->conn->data['LIST'] && ($opts = $this->conn->data['LIST'][$folder]) + && in_array('\\NonExistent', $opts) + ) { + unset($a_folders[$idx]); + } + } + } + } + // retrieve list of folders from IMAP server using LSUB + else { + $a_folders = $this->conn->listSubscribed($this->mod_mailbox($root), $filter); + } } if (!is_array($a_folders) || !sizeof($a_folders)) @@ -3121,13 +3140,15 @@ class rcube_imap /** - * Gets folder options from LIST/LSUB response, e.g. \Noselect, \Noinferiors + * Gets folder options from LIST response, e.g. \Noselect, \Noinferiors * * @param string $mbox_name Folder name + * @param bool $force Set to True if options should be refreshed + * Options are available after LIST command only * * @return array Options list */ - function mailbox_options($mbox_name) + function mailbox_options($mbox_name, $force=false) { $mbox = $this->mod_mailbox($mbox_name); @@ -3136,7 +3157,12 @@ class rcube_imap } if (!is_array($this->conn->data['LIST']) || !is_array($this->conn->data['LIST'][$mbox])) { - $this->conn->listMailboxes($this->mod_mailbox(''), $mbox_name); + if ($force) { + $this->conn->listMailboxes($this->mod_mailbox(''), $mbox_name); + } + else { + return array(); + } } $opts = $this->conn->data['LIST'][$mbox]; diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php index c79124bec..41240a2d1 100644 --- a/program/include/rcube_imap_generic.php +++ b/program/include/rcube_imap_generic.php @@ -1826,14 +1826,15 @@ class rcube_imap_generic * @param string $ref Reference name * @param string $mailbox Mailbox name * @param array $status_opts (see self::_listMailboxes) + * @param array $select_opts (see self::_listMailboxes) * * @return array List of mailboxes or hash of options if $status_opts argument * is non-empty. * @access public */ - function listMailboxes($ref, $mailbox, $status_opts=array()) + function listMailboxes($ref, $mailbox, $status_opts=array(), $select_opts=array()) { - return $this->_listMailboxes($ref, $mailbox, false, $status_opts); + return $this->_listMailboxes($ref, $mailbox, false, $status_opts, $select_opts); } /** @@ -1843,13 +1844,13 @@ class rcube_imap_generic * @param string $mailbox Mailbox name * @param array $status_opts (see self::_listMailboxes) * - * @return array List of mailboxes or hash of options if $status_ops argument + * @return array List of mailboxes or hash of options if $status_opts argument * is non-empty. * @access public */ function listSubscribed($ref, $mailbox, $status_opts=array()) { - return $this->_listMailboxes($ref, $mailbox, true, $status_opts); + return $this->_listMailboxes($ref, $mailbox, true, $status_opts, NULL); } /** @@ -1860,12 +1861,15 @@ class rcube_imap_generic * @param bool $subscribed Enables returning subscribed mailboxes only * @param array $status_opts List of STATUS options (RFC5819: LIST-STATUS) * Possible: MESSAGES, RECENT, UIDNEXT, UIDVALIDITY, UNSEEN + * @param array $select_opts List of selection options (RFC5258: LIST-EXTENDED) + * Possible: SUBSCRIBED, RECURSIVEMATCH, REMOTE * * @return array List of mailboxes or hash of options if $status_ops argument * is non-empty. * @access private */ - private function _listMailboxes($ref, $mailbox, $subscribed=false, $status_opts=array()) + private function _listMailboxes($ref, $mailbox, $subscribed=false, + $status_opts=array(), $select_opts=array()) { if (empty($mailbox)) { $mailbox = '*'; @@ -1875,10 +1879,19 @@ class rcube_imap_generic $ref = $this->prefs['rootdir']; } - $args = array($this->escape($ref), $this->escape($mailbox)); + $args = array(); + + if (!empty($select_opts) && $this->getCapability('LIST-EXTENDED')) { + $select_opts = (array) $select_opts; + + $args[] = '(' . implode(' ', $select_opts) . ')'; + } + + $args[] = $this->escape($ref); + $args[] = $this->escape($mailbox); if (!empty($status_opts) && $this->getCapability('LIST-STATUS')) { - $status_opts = array($status_opts); + $status_opts = (array) $status_opts; $lstatus = true; $args[] = 'RETURN (STATUS (' . implode(' ', $status_opts) . '))'; @@ -1894,6 +1907,7 @@ class rcube_imap_generic if (!$lstatus || $cmd == 'LIST' || $cmd == 'LSUB') { list($opts, $delim, $folder) = $this->tokenizeResponse($response, 3); + // Add to result array if (!$lstatus) { $folders[] = $folder; } @@ -1901,8 +1915,13 @@ class rcube_imap_generic $folders[$folder] = array(); } - if ($cmd == 'LIST') { - $this->data['LIST'][$folder] = $opts; + // Add to options array + if (!empty($opts)) { + if (empty($this->data['LIST'][$folder])) + $this->data['LIST'][$folder] = $opts; + else + $this->data['LIST'][$folder] = array_unique(array_merge( + $this->data['LIST'][$folder], $opts)); } } // * STATUS <mailbox> (<result>) |