From 00290a603237e719cc4ec3db65e6661ba7d46a51 Mon Sep 17 00:00:00 2001 From: alecpl Date: Tue, 9 Nov 2010 07:54:34 +0000 Subject: - Add support for shared folders (#1403507) --- program/include/rcube_imap.php | 212 ++++++++++++++++++++++++++++++----------- 1 file changed, 156 insertions(+), 56 deletions(-) (limited to 'program/include/rcube_imap.php') diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index acf0aa0e0..2b77bf55d 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -33,10 +33,8 @@ class rcube_imap { public $debug_level = 1; public $skip_deleted = false; - public $root_dir = ''; public $page_size = 10; public $list_page = 1; - public $delimiter = NULL; public $threading = false; public $fetch_add_headers = ''; public $get_all_headers = false; @@ -54,8 +52,9 @@ class rcube_imap * @var rcube_mdb2 */ private $db; - private $root_ns = ''; private $mailbox = 'INBOX'; + private $delimiter = NULL; + private $namespace = NULL; private $sort_field = ''; private $sort_order = 'DESC'; private $caching_enabled = false; @@ -156,18 +155,13 @@ class rcube_imap $this->port = $port; $this->ssl = $use_ssl; - // print trace messages if ($this->conn->connected()) { + // print trace messages if ($this->conn->message && ($this->debug_level & 8)) { console($this->conn->message); } - - // get server properties - $rootdir = $this->conn->getRootDir(); - if (!empty($rootdir)) - $this->set_rootdir($rootdir); - if (empty($this->delimiter)) - $this->get_hierarchy_delimiter(); + // get namespace and delimiter + $this->set_env(); return true; } @@ -246,28 +240,6 @@ class rcube_imap } - /** - * Set a root folder for the IMAP connection. - * - * Only folders within this root folder will be displayed - * and all folder paths will be translated using this folder name - * - * @param string $root Root folder - * @access public - */ - function set_rootdir($root) - { - if (preg_match('/[.\/]$/', $root)) //(substr($root, -1, 1)==='/') - $root = substr($root, 0, -1); - - $this->root_dir = $root; - $this->options['rootdir'] = $root; - - if (empty($this->delimiter)) - $this->get_hierarchy_delimiter(); - } - - /** * Set default message charset * @@ -482,13 +454,101 @@ class rcube_imap */ function get_hierarchy_delimiter() { - if ($this->conn && empty($this->delimiter)) - $this->delimiter = $this->conn->getHierarchyDelimiter(); + return $this->delimiter; + } - if (empty($this->delimiter)) - $this->delimiter = '/'; - return $this->delimiter; + /** + * Get namespace + * + * @return array Namespace data + * @access public + */ + function get_namespace() + { + return $this->namespace; + } + + + /** + * Sets delimiter and namespaces + * + * @access private + */ + private function set_env() + { + if ($this->delimiter !== null && $this->namespace !== null) { + return; + } + + if (isset($_SESSION['imap_namespace']) && isset($_SESSION['imap_delimiter'])) { + $this->namespace = $_SESSION['imap_namespace']; + $this->delimiter = $_SESSION['imap_delimiter']; + return; + } + + $config = rcmail::get_instance()->config; + $imap_personal = $config->get('imap_ns_personal'); + $imap_other = $config->get('imap_ns_other'); + $imap_shared = $config->get('imap_ns_shared'); + $imap_delimiter = $config->get('imap_delimiter'); + + if ($imap_delimiter) { + $this->delimiter = $imap_delimiter; + } + + if (!$this->conn) + return; + + $ns = $this->conn->getNamespace(); + + // NAMESPACE supported + if (is_array($ns)) { + $this->namespace = $ns; + + if (empty($this->delimiter)) + $this->delimiter = $ns['personal'][0][1]; + if (empty($this->delimiter)) + $this->delimiter = $this->conn->getHierarchyDelimiter(); + if (empty($this->delimiter)) + $this->delimiter = '/'; + } + // not supported, get namespace from config + else if ($imap_personal !== null || $imap_shared !== null || $imap_other !== null) { + if (empty($this->delimiter)) + $this->delimiter = $this->conn->getHierarchyDelimiter(); + if (empty($this->delimiter)) + $this->delimiter = '/'; + + $this->namespace = array( + 'personal' => NULL, + 'other' => NULL, + 'shared' => NULL, + ); + + if ($imap_personal !== null) { + foreach ((array)$imap_personal as $dir) { + $this->namespace['personal'][] = array($dir, $this->delimiter); + } + } + if ($imap_other !== null) { + foreach ((array)$imap_other as $dir) { + if ($dir) { + $this->namespace['other'][] = array($dir, $this->delimiter); + } + } + } + if ($imap_shared !== null) { + foreach ((array)$imap_shared as $dir) { + if ($dir) { + $this->namespace['shared'][] = array($dir, $this->delimiter); + } + } + } + } + + $_SESSION['imap_namespace'] = $this->namespace; + $_SESSION['imap_delimiter'] = $this->delimiter; } @@ -891,7 +951,7 @@ class rcube_imap // flatten threads array // @TODO: fetch children only in expanded mode (?) $all_ids = array(); - foreach($msg_index as $root) { + foreach ($msg_index as $root) { $all_ids[] = $root; if (!empty($thread_tree[$root])) $all_ids = array_merge($all_ids, array_keys_recursive($thread_tree[$root])); @@ -1463,7 +1523,7 @@ class rcube_imap // flatten threads array $all_ids = array(); - foreach($msg_index as $root) { + foreach ($msg_index as $root) { $all_ids[] = $root; if (!empty($thread_tree[$root])) { foreach (array_keys_recursive($thread_tree[$root]) as $val) @@ -3073,10 +3133,11 @@ class rcube_imap $a_mboxes = explode(',', $mbox_name); if (is_array($a_mboxes)) { + $delimiter = $this->get_hierarchy_delimiter(); + foreach ($a_mboxes as $mbox_name) { $mailbox = $this->mod_mailbox($mbox_name); - $sub_mboxes = $this->conn->listMailboxes($this->mod_mailbox(''), - $mbox_name . $this->delimiter . '*'); + $sub_mboxes = $this->conn->listMailboxes('', $mbox_name . $delimiter . '*'); // unsubscribe mailbox before deleting $this->conn->unsubscribe($mailbox); @@ -3137,19 +3198,20 @@ class rcube_imap if ($mbox_name == 'INBOX') return true; - $key = $subscription ? 'subscribed' : 'existing'; - if (is_array($this->icache[$key]) && in_array($mbox_name, $this->icache[$key])) + $key = $subscription ? 'subscribed' : 'existing'; + $mbox = $this->mod_mailbox($mbox_name) + if (is_array($this->icache[$key]) && in_array($mbox, $this->icache[$key])) return true; if ($subscription) { - $a_folders = $this->conn->listSubscribed($this->mod_mailbox(''), $mbox_name); + $a_folders = $this->conn->listSubscribed('', $mbox); } else { - $a_folders = $this->conn->listMailboxes($this->mod_mailbox(''), $mbox_name); + $a_folders = $this->conn->listMailboxes('', $mbox); } - if (is_array($a_folders) && in_array($this->mod_mailbox($mbox_name), $a_folders)) { - $this->icache[$key][] = $mbox_name; + if (is_array($a_folders) && in_array($mbox, $a_folders)) { + $this->icache[$key][] = $mbox; return true; } } @@ -3167,14 +3229,52 @@ class rcube_imap */ function mod_mailbox($mbox_name, $mode='in') { - if ($mbox_name == 'INBOX') - return $mbox_name; + if (empty($mbox_name)) + return ''; - if (!empty($this->root_dir)) { - if ($mode=='in') - $mbox_name = $this->root_dir.$this->delimiter.$mbox_name; - else if (!empty($mbox_name)) // $mode=='out' - $mbox_name = substr($mbox_name, strlen($this->root_dir)+1); + if ($mode == 'in') { + // If folder contains namespace prefix, don't modify it + if (is_array($this->namespace['shared'])) { + foreach ($this->namespace['shared'] as $ns) { + foreach ((array)$ns as $root) { + if (strpos($mbox_name, $root[0]) === 0) { + return $mbox_name; + } + } + } + } + if (is_array($this->namespace['other'])) { + foreach ($this->namespace['other'] as $ns) { + foreach ((array)$ns as $root) { + if (strpos($mbox_name, $root[0]) === 0) { + return $mbox_name; + } + } + } + } + if (is_array($this->namespace['personal'])) { + foreach ($this->namespace['personal'] as $ns) { + foreach ((array)$ns as $root) { + if ($root[0] && strpos($mbox_name, $root[0]) === 0) { + return $mbox_name; + } + } + } + // Add prefix if first personal namespace is non-empty + if ($this->namespace['personal'][0][0]) { + return $this->namespace['personal'][0][0].$mbox_name; + } + } + } + else { + // Remove prefix if folder is from first ("non-empty") personal namespace + if (is_array($this->namespace['personal'])) { + if ($prefix = $this->namespace['personal'][0][0]) { + if (strpos($mbox_name, $prefix) === 0) { + return substr($mbox_name, strlen($prefix)); + } + } + } } return $mbox_name; @@ -3200,7 +3300,7 @@ class rcube_imap if (!is_array($this->conn->data['LIST']) || !is_array($this->conn->data['LIST'][$mbox])) { if ($force) { - $this->conn->listMailboxes($this->mod_mailbox(''), $mbox_name); + $this->conn->listMailboxes('', $mbox_name); } else { return array(); -- cgit v1.2.3