From ecfaed571b2c38f4bcc2b6a0fa39fba15a5126ce Mon Sep 17 00:00:00 2001 From: alecpl <alec@alec.pl> Date: Fri, 11 Nov 2011 10:04:45 -0500 Subject: [PATCH] - Apply fixes fom trunk up to r5414 --- program/include/rcube_imap.php | 127 +++++++++++++++++++++++++++-------------- 1 files changed, 83 insertions(+), 44 deletions(-) diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index c07b398..8c1fab8 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -32,7 +32,6 @@ */ class rcube_imap { - public $debug_level = 1; public $skip_deleted = false; public $page_size = 10; public $list_page = 1; @@ -318,6 +317,19 @@ /** + * Activate/deactivate debug mode + * + * @param boolean $dbg True if IMAP conversation should be logged + * @access public + */ + function set_debug($dbg = true) + { + $this->options['debug'] = $dbg; + $this->conn->setDebug($dbg, array($this, 'debug_handler')); + } + + + /** * Set default message charset * * This will be used for message decoding if a charset specification is not available @@ -466,7 +478,7 @@ */ function get_mailbox_name() { - return $this->conn->connected() ? $this->mailbox : ''; + return $this->mailbox; } @@ -1508,7 +1520,7 @@ // I didn't found that SEARCH should return sorted IDs if (is_array($a_index)) sort($a_index); - } else if ($max = $this->_messagecount($mailbox)) { + } else if ($max = $this->_messagecount($mailbox, 'ALL', true, false)) { $a_index = range(1, $max); } @@ -1694,7 +1706,7 @@ } if ($orig_criteria == 'ALL') { - $max = $this->_messagecount($mailbox); + $max = $this->_messagecount($mailbox, 'ALL', true, false); $a_messages = $max ? range(1, $max) : array(); } else { @@ -1961,6 +1973,10 @@ } $headers = $this->get_headers($uid, $mailbox); + + // message doesn't exist? + if (empty($headers)) + return null; // structure might be cached if (!empty($headers->structure)) @@ -2320,9 +2336,14 @@ // decode filename if (!empty($filename_mime)) { - $part->filename = rcube_imap::decode_mime_string($filename_mime, - $part->charset ? $part->charset : ($this->struct_charset ? $this->struct_charset : - rc_detect_encoding($filename_mime, $this->default_charset))); + if (!empty($part->charset)) + $charset = $part->charset; + else if (!empty($this->struct_charset)) + $charset = $this->struct_charset; + else + $charset = rc_detect_encoding($filename_mime, $this->default_charset); + + $part->filename = rcube_imap::decode_mime_string($filename_mime, $charset); } else if (!empty($filename_encoded)) { // decode filename according to RFC 2231, Section 4 @@ -2330,6 +2351,7 @@ $filename_charset = $fmatches[1]; $filename_encoded = $fmatches[2]; } + $part->filename = rcube_charset_convert(urldecode($filename_encoded), $filename_charset); } } @@ -2366,24 +2388,22 @@ */ function &get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false) { - // get part encoding if not provided + // get part data if not provided if (!is_object($o_part)) { $structure = $this->conn->getStructure($this->mailbox, $uid, true); + $part_data = rcube_imap_generic::getStructurePartData($structure, $part); $o_part = new rcube_message_part; - $o_part->ctype_primary = strtolower(rcube_imap_generic::getStructurePartType($structure, $part)); - $o_part->encoding = strtolower(rcube_imap_generic::getStructurePartEncoding($structure, $part)); - $o_part->charset = rcube_imap_generic::getStructurePartCharset($structure, $part); + $o_part->ctype_primary = $part_data['type']; + $o_part->encoding = $part_data['encoding']; + $o_part->charset = $part_data['charset']; + $o_part->size = $part_data['size']; } - // TODO: Add caching for message parts - - if (!$part) { - $part = 'TEXT'; + if ($o_part && $o_part->size) { + $body = $this->conn->handlePartBody($this->mailbox, $uid, true, + $part ? $part : 'TEXT', $o_part->encoding, $print, $fp); } - - $body = $this->conn->handlePartBody($this->mailbox, $uid, true, $part, - $o_part->encoding, $print, $fp); if ($fp || $print) { return true; @@ -2397,7 +2417,7 @@ if (!$skip_charset_conv) { if (!$o_part->charset || strtoupper($o_part->charset) == 'US-ASCII') { // try to extract charset information from HTML meta tag (#1488125) - if ($o_part->ctype_secondary == 'html' && preg_match('/<meta[^>]+charset=([a-z0-9-]+)/i', $body, $m)) + if ($o_part->ctype_secondary == 'html' && preg_match('/<meta[^>]+charset=([a-z0-9-_]+)/i', $body, $m)) $o_part->charset = strtoupper($m[1]); else $o_part->charset = $this->default_charset; @@ -3067,7 +3087,19 @@ */ function list_unsubscribed($root='', $name='*', $filter=null, $rights=null, $skip_sort=false) { - // @TODO: caching + $cache_key = $root.':'.$name; + if (!empty($filter)) { + $cache_key .= ':'.(is_string($filter) ? $filter : serialize($filter)); + } + $cache_key .= ':'.$rights; + $cache_key = 'mailboxes.list.'.md5($cache_key); + + // get cached folder list + $a_mboxes = $this->get_cache($cache_key); + if (is_array($a_mboxes)) { + return $a_mboxes; + } + // Give plugins a chance to provide a list of mailboxes $data = rcmail::get_instance()->plugins->exec_hook('mailboxes_list', array('root' => $root, 'name' => $name, 'filter' => $filter, 'mode' => 'LIST')); @@ -3089,6 +3121,11 @@ array_unshift($a_mboxes, 'INBOX'); } + // cache folder attributes + if ($root == '' && $name == '*' && empty($filter)) { + $this->update_cache('mailboxes.attributes', $this->conn->data['LIST']); + } + // filter folders list according to rights requirements if ($rights && $this->get_capability('ACL')) { $a_folders = $this->filter_rights($a_folders, $rights); @@ -3098,6 +3135,9 @@ if (!$skip_sort) { $a_mboxes = $this->_sort_mailbox_list($a_mboxes); } + + // write mailboxlist to cache + $this->update_cache($cache_key, $a_mboxes); return $a_mboxes; } @@ -3430,30 +3470,29 @@ /** - * Gets folder options from LIST response, e.g. \Noselect, \Noinferiors + * Gets folder attributes from LIST response, e.g. \Noselect, \Noinferiors * * @param string $mailbox Folder name - * @param bool $force Set to True if options should be refreshed - * Options are available after LIST command only + * @param bool $force Set to True if attributes should be refreshed * * @return array Options list */ - function mailbox_options($mailbox, $force=false) + function mailbox_attributes($mailbox, $force=false) { - if ($mailbox == 'INBOX') { - return array(); + // get attributes directly from LIST command + if (!empty($this->conn->data['LIST']) && is_array($this->conn->data['LIST'][$mailbox])) { + $opts = $this->conn->data['LIST'][$mailbox]; + } + // get cached folder attributes + else if (!$force) { + $opts = $this->get_cache('mailboxes.attributes'); + $opts = $opts[$mailbox]; } - if (!is_array($this->conn->data['LIST']) || !is_array($this->conn->data['LIST'][$mailbox])) { - if ($force) { - $this->conn->listMailboxes('', $mailbox); - } - else { - return array(); - } + if (!is_array($opts)) { + $this->conn->listMailboxes('', $mailbox); + $opts = $this->conn->data['LIST'][$mailbox]; } - - $opts = $this->conn->data['LIST'][$mailbox]; return is_array($opts) ? $opts : array(); } @@ -3536,17 +3575,17 @@ } } - $options['name'] = $mailbox; - $options['options'] = $this->mailbox_options($mailbox, true); - $options['namespace'] = $this->mailbox_namespace($mailbox); - $options['rights'] = $acl && !$options['is_root'] ? (array)$this->my_rights($mailbox) : array(); - $options['special'] = in_array($mailbox, $this->default_folders); + $options['name'] = $mailbox; + $options['attributes'] = $this->mailbox_attributes($mailbox, true); + $options['namespace'] = $this->mailbox_namespace($mailbox); + $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); - if ($opt == '\noselect' || $opt == '\nonexistent') { + if (is_array($options['attributes'])) { + foreach ($options['attributes'] as $attrib) { + $attrib = strtolower($attrib); + if ($attrib == '\noselect' || $attrib == '\nonexistent') { $options['noselect'] = true; } } -- Gitblit v1.9.1