From d43d4bcf44a1feae4274e51f41ce9625147f9f85 Mon Sep 17 00:00:00 2001 From: thomascube <thomas@roundcube.net> Date: Fri, 19 Aug 2011 12:32:38 -0400 Subject: [PATCH] Backporting r5092, r5095, r5096 to release-0.6 branch --- program/include/rcube_imap.php | 96 +++++++++++++++++++++++++++++++++++++---------- 1 files changed, 75 insertions(+), 21 deletions(-) diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 411be52..6a35af0 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -80,6 +80,7 @@ private $db_header_fields = array('idx', 'uid', 'subject', 'from', 'to', 'cc', 'date', 'size'); private $options = array('auth_method' => 'check'); private $host, $user, $pass, $port, $ssl; + private $caching = false; /** * All (additional) headers used (in any way) by Roundcube @@ -2162,7 +2163,7 @@ if (strtolower($part[$i][0]) == 'message' && strtolower($part[$i][1]) == 'rfc822') { $mime_part_headers[] = $tmp_part_id; } - else if (in_array('name', (array)$part[$i][2]) && (empty($part[$i][3]) || $part[$i][3]=='NIL')) { + else if (in_array('name', (array)$part[$i][2]) && empty($part[$i][3])) { $mime_part_headers[] = $tmp_part_id; } } @@ -2230,13 +2231,13 @@ } // read content encoding - if (!empty($part[5]) && $part[5]!='NIL') { + if (!empty($part[5])) { $struct->encoding = strtolower($part[5]); $struct->headers['content-transfer-encoding'] = $struct->encoding; } // get part size - if (!empty($part[6]) && $part[6]!='NIL') + if (!empty($part[6])) $struct->size = intval($part[6]); // read part disposition @@ -2263,7 +2264,7 @@ } // get part ID - if (!empty($part[3]) && $part[3]!='NIL') { + if (!empty($part[3])) { $struct->content_id = $part[3]; $struct->headers['content-id'] = $part[3]; @@ -3082,20 +3083,36 @@ $a_folders = $this->conn->listMailboxes($root, $name, NULL, array('SUBSCRIBED')); - // remove non-existent folders - if (is_array($a_folders)) { + // unsubscribe non-existent folders, remove from the list + if (is_array($a_folders) && $name == '*') { foreach ($a_folders as $idx => $folder) { if ($this->conn->data['LIST'] && ($opts = $this->conn->data['LIST'][$folder]) && in_array('\\NonExistent', $opts) ) { + $this->conn->unsubscribe($folder); unset($a_folders[$idx]); - } + } } } } // retrieve list of folders from IMAP server using LSUB else { $a_folders = $this->conn->listSubscribed($root, $name); + + // unsubscribe non-existent folders, remove from the list + if (is_array($a_folders) && $name == '*') { + foreach ($a_folders as $idx => $folder) { + if ($this->conn->data['LIST'] && ($opts = $this->conn->data['LIST'][$folder]) + && in_array('\\Noselect', $opts) + ) { + // Some servers returns \Noselect for existing folders + if (!$this->mailbox_exists($folder)) { + $this->conn->unsubscribe($folder); + unset($a_folders[$idx]); + } + } + } + } } } @@ -3496,6 +3513,10 @@ */ function mailbox_info($mailbox) { + if ($this->icache['options'] && $this->icache['options']['name'] == $mailbox) { + return $this->icache['options']; + } + $acl = $this->get_capability('ACL'); $namespace = $this->get_namespace(); $options = array(); @@ -3508,8 +3529,21 @@ foreach ($ns as $item) { if ($item[0] === $mbox) { $options['is_root'] = true; - break; + break 2; } + } + } + } + } + // check if the folder is other user virtual-root + if (!$options['is_root'] && !empty($namespace) && !empty($namespace['other'])) { + $parts = explode($this->delimiter, $mailbox); + if (count($parts) == 2) { + $mbox = $parts[0] . $this->delimiter; + foreach ($namespace['other'] as $item) { + if ($item[0] === $mbox) { + $options['is_root'] = true; + break; } } } @@ -3521,6 +3555,7 @@ $options['rights'] = $acl && !$options['is_root'] ? (array)$this->my_rights($mailbox) : array(); $options['special'] = in_array($mailbox, $this->default_folders); + // Set 'noselect' and 'norename' flags if (is_array($options['options'])) { foreach ($options['options'] as $opt) { $opt = strtolower($opt); @@ -3534,12 +3569,16 @@ } if (!empty($options['rights'])) { - $options['norename'] = !in_array('x', $options['rights']) && - (!in_array('c', $options['rights']) || !in_array('d', $options['rights'])); + $options['norename'] = !in_array('x', $options['rights']); if (!$options['noselect']) { $options['noselect'] = !in_array('r', $options['rights']); } } + else { + $options['norename'] = $options['is_root'] || $options['namespace'] != 'personal'; + } + + $this->icache['options'] = $options; return $options; } @@ -3801,16 +3840,28 @@ function set_caching($type) { if ($type) { - $rcmail = rcmail::get_instance(); - $this->cache = $rcmail->get_cache('IMAP', $type); + $this->caching = true; } else { if ($this->cache) $this->cache->close(); $this->cache = null; + $this->caching = false; } } + /** + * Getter for IMAP cache object + */ + private function get_cache_engine() + { + if ($this->caching && !$this->cache) { + $rcmail = rcmail::get_instance(); + $this->cache = $rcmail->get_cache('IMAP', $type); + } + + return $this->cache; + } /** * Returns cached value @@ -3821,8 +3872,8 @@ */ function get_cache($key) { - if ($this->cache) { - return $this->cache->get($key); + if ($cache = $this->get_cache_engine()) { + return $cache->get($key); } } @@ -3835,8 +3886,8 @@ */ function update_cache($key, $data) { - if ($this->cache) { - $this->cache->set($key, $data); + if ($cache = $this->get_cache_engine()) { + $cache->set($key, $data); } } @@ -3850,8 +3901,8 @@ */ function clear_cache($key=null, $prefix_mode=false) { - if ($this->cache) { - $this->cache->remove($key, $prefix_mode); + if ($cache = $this->get_cache_engine()) { + $cache->remove($key, $prefix_mode); } } @@ -4731,16 +4782,19 @@ $str = self::explode_header_string(',;', $str, true); $result = array(); + // simplified regexp, supporting quoted local part + $email_rx = '(\S+|("\s*(?:[^"\f\n\r\t\v\b\s]+\s*)+"))@\S+'; + foreach ($str as $key => $val) { $name = ''; $address = ''; $val = trim($val); - if (preg_match('/(.*)<(\S+@\S+)>$/', $val, $m)) { + if (preg_match('/(.*)<('.$email_rx.')>$/', $val, $m)) { $address = $m[2]; $name = trim($m[1]); } - else if (preg_match('/^(\S+@\S+)$/', $val, $m)) { + else if (preg_match('/^('.$email_rx.')$/', $val, $m)) { $address = $m[1]; $name = ''; } @@ -4750,7 +4804,7 @@ // dequote and/or decode name if ($name) { - if ($name[0] == '"') { + if ($name[0] == '"' && $name[strlen($name)-1] == '"') { $name = substr($name, 1, -1); $name = stripslashes($name); } -- Gitblit v1.9.1