From 94bdcce081eb4b080fcaab74bc8466237c2dfcd4 Mon Sep 17 00:00:00 2001 From: alecpl Date: Fri, 6 May 2011 08:14:48 +0000 Subject: - Add possibility (for plugins) to filter folders lists by some additional criteria (e.g. folder type) --- program/include/main.inc | 12 ++++-- program/include/rcube_imap.php | 77 +++++++++++++++++++++++++------------ program/steps/mail/check_recent.inc | 2 +- program/steps/mail/compose.inc | 5 ++- program/steps/mail/getunread.inc | 2 +- 5 files changed, 68 insertions(+), 30 deletions(-) (limited to 'program') diff --git a/program/include/main.inc b/program/include/main.inc index baaca654d..00069c2a2 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -1170,13 +1170,16 @@ function rcmail_mailbox_list($attrib) if ($type=='ul' && !$attrib['id']) $attrib['id'] = 'rcmboxlist'; + if (empty($attrib['folder_name'])) + $attrib['folder_name'] = '*'; + // get mailbox list $mbox_name = $RCMAIL->imap->get_mailbox_name(); // build the folders tree if (empty($a_mailboxes)) { // get mailbox list - $a_folders = $RCMAIL->imap->list_mailboxes(); + $a_folders = $RCMAIL->imap->list_mailboxes('', $attrib['folder_name'], $attrib['folder_filter']); $delimiter = $RCMAIL->imap->get_hierarchy_delimiter(); $a_mailboxes = array(); @@ -1223,10 +1226,13 @@ function rcmail_mailbox_select($p = array()) $p += array('maxlength' => 100, 'realnames' => false); $a_mailboxes = array(); + if (empty($p['folder_name'])) + $p['folder_name'] = '*'; + if ($p['unsubscribed']) - $list = $RCMAIL->imap->list_unsubscribed(); + $list = $RCMAIL->imap->list_unsubscribed('', $p['folder_name'], $p['folder_filter']); else - $list = $RCMAIL->imap->list_mailboxes(); + $list = $RCMAIL->imap->list_mailboxes('', $p['folder_name'], $p['folder_filter']); $delimiter = $RCMAIL->imap->get_hierarchy_delimiter(); diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index d7100a6ba..484e70bd1 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -3014,18 +3014,20 @@ class rcube_imap * Public method for listing subscribed folders * * @param string $root Optional root folder - * @param string $filter Optional filter for mailbox listing + * @param string $name Optional name pattern + * @param string $filter Optional filter * * @return array List of mailboxes/folders * @access public */ - function list_mailboxes($root='', $filter='*') + function list_mailboxes($root='', $name='*', $filter=null) { - $a_mboxes = $this->_list_mailboxes($root, $filter); + $a_mboxes = $this->_list_mailboxes($root, $name, $filter); // INBOX should always be available - if (!in_array('INBOX', $a_mboxes)) + if ((!$filter || $filter == 'mail') && !in_array('INBOX', $a_mboxes)) { array_unshift($a_mboxes, 'INBOX'); + } // sort mailboxes $a_mboxes = $this->_sort_mailbox_list($a_mboxes); @@ -3038,23 +3040,31 @@ class rcube_imap * Private method for mailbox listing * * @param string $root Optional root folder - * @param string $filter Optional filter for mailbox listing + * @param string $name Optional name pattern + * @param mixed $filter Optional filter + * * @return array List of mailboxes/folders * @see rcube_imap::list_mailboxes() * @access private */ - private function _list_mailboxes($root='', $filter='*') + private function _list_mailboxes($root='', $name='*', $filter=null) { + $cache_key = 'mailboxes'; + if (!empty($filter)) { + $cache_key .= ':'.substr((is_string($filter) ? $filter : serialize($filter)), 0, 90); + } + // get cached folder list - $a_mboxes = $this->get_cache('mailboxes'); - if (is_array($a_mboxes)) + $a_mboxes = $this->get_cache($cache_key); + if (is_array($a_mboxes)) { return $a_mboxes; + } $a_defaults = $a_out = array(); // Give plugins a chance to provide a list of mailboxes $data = rcmail::get_instance()->plugins->exec_hook('mailboxes_list', - array('root' => $root, 'filter' => $filter, 'mode' => 'LSUB')); + array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LSUB')); if (isset($data['folders'])) { $a_folders = $data['folders']; @@ -3065,7 +3075,7 @@ class rcube_imap // #1486225: Some dovecot versions returns wrong result using LIST-EXTENDED if (!$config->get('imap_force_lsub') && $this->get_capability('LIST-EXTENDED')) { // This will also set mailbox options, LSUB doesn't do that - $a_folders = $this->conn->listMailboxes($root, $filter, + $a_folders = $this->conn->listMailboxes($root, $name, NULL, array('SUBSCRIBED')); // remove non-existent folders @@ -3081,15 +3091,16 @@ class rcube_imap } // retrieve list of folders from IMAP server using LSUB else { - $a_folders = $this->conn->listSubscribed($root, $filter); + $a_folders = $this->conn->listSubscribed($root, $name); } } - if (!is_array($a_folders) || !sizeof($a_folders)) + if (!is_array($a_folders) || !sizeof($a_folders)) { $a_folders = array(); + } // write mailboxlist to cache - $this->update_cache('mailboxes', $a_folders); + $this->update_cache($cache_key, $a_folders); return $a_folders; } @@ -3099,21 +3110,24 @@ class rcube_imap * Get a list of all folders available on the IMAP server * * @param string $root IMAP root dir - * @param string $filter Optional filter for mailbox listing + * @param string $name Optional name pattern + * @param mixed $filter Optional filter + * * @return array Indexed array with folder names */ - function list_unsubscribed($root='', $filter='*') + function list_unsubscribed($root='', $name='*', $filter=null) { + // @TODO: caching // Give plugins a chance to provide a list of mailboxes $data = rcmail::get_instance()->plugins->exec_hook('mailboxes_list', - array('root' => $root, 'filter' => $filter, 'mode' => 'LIST')); + array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LIST')); if (isset($data['folders'])) { $a_mboxes = $data['folders']; } else { // retrieve list of folders from IMAP server - $a_mboxes = $this->conn->listMailboxes($root, $filter); + $a_mboxes = $this->conn->listMailboxes($root, $name); } if (!is_array($a_mboxes)) { @@ -3121,8 +3135,9 @@ class rcube_imap } // INBOX should always be available - if (!in_array('INBOX', $a_mboxes)) + if ((!$filter || $filter == 'mail') && !in_array('INBOX', $a_mboxes)) { array_unshift($a_mboxes, 'INBOX'); + } // filter folders and sort them $a_mboxes = $this->_sort_mailbox_list($a_mboxes); @@ -3263,7 +3278,7 @@ class rcube_imap // clear cache $this->clear_message_cache($mailbox.'.msg'); - $this->clear_cache('mailboxes'); + $this->clear_cache('/^mailboxes.*/', true); } return $result; @@ -3305,7 +3320,7 @@ class rcube_imap // clear mailbox-related cache $this->clear_message_cache($mailbox.'.msg'); - $this->clear_cache('mailboxes'); + $this->clear_cache('/^mailboxes.*/', true); } return $result; @@ -3777,22 +3792,36 @@ class rcube_imap /** * Clears the cache. * - * @param string $key Cache key + * @param string $key Cache key name or pattern + * @param boolean $pattern_mode Enable it to clear all keys with name + * matching PREG pattern in $key * @access public */ - function clear_cache($key=NULL) + function clear_cache($key=null, $pattern_mode=false) { if (!$this->caching_enabled) return; - if ($key===NULL) { - foreach ($this->cache as $key => $data) + if ($key === null) { + foreach (array_keys($this->cache) as $key) $this->_clear_cache_record($key); $this->cache = array(); $this->cache_changed = false; $this->cache_changes = array(); } + else if ($pattern_mode) { + foreach (array_keys($this->cache) as $k) { + if (preg_match($key, $k)) { + $this->_clear_cache_record($k); + $this->cache_changes[$k] = false; + unset($this->cache[$key]); + } + } + if (!count($this->cache)) { + $this->cache_changed = false; + } + } else { $this->_clear_cache_record($key); $this->cache_changes[$key] = false; diff --git a/program/steps/mail/check_recent.inc b/program/steps/mail/check_recent.inc index fc26d6387..c636e459b 100644 --- a/program/steps/mail/check_recent.inc +++ b/program/steps/mail/check_recent.inc @@ -24,7 +24,7 @@ $check_all = !empty($_GET['_refresh']) || (bool)$RCMAIL->config->get('check_all_ // list of folders to check if ($check_all) { - $a_mailboxes = $IMAP->list_mailboxes(); + $a_mailboxes = $IMAP->list_mailboxes('', '*', 'mail'); } else { $a_mailboxes = (array) $current; diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index 531e698a8..4fe924409 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -1297,7 +1297,10 @@ function rcmail_editor_selector($attrib) function rcmail_store_target_selection($attrib) { $attrib['name'] = '_store_target'; - $select = rcmail_mailbox_select(array_merge($attrib, array('noselection' => '- '.rcube_label('dontsave').' -'))); + $select = rcmail_mailbox_select(array_merge($attrib, array( + 'noselection' => '- '.rcube_label('dontsave').' -', + 'folder_filter' => 'mail' + ))); return $select->show($_SESSION['compose']['param']['sent_mbox'], $attrib); } diff --git a/program/steps/mail/getunread.inc b/program/steps/mail/getunread.inc index 4ae7e05bc..27ae5f747 100644 --- a/program/steps/mail/getunread.inc +++ b/program/steps/mail/getunread.inc @@ -19,7 +19,7 @@ */ -$a_folders = $IMAP->list_mailboxes(); +$a_folders = $IMAP->list_mailboxes('', '*', 'mail'); if (!empty($a_folders)) { -- cgit v1.2.3