From 9b4aaa79d3cc1cded4e8a3bd11063994152fccc7 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Tue, 03 Feb 2009 02:40:26 -0500
Subject: [PATCH] - Fix displaying of alternative-inside-alternative messages (#1485713)
---
program/include/rcube_imap.php | 139 +++++++++++++++++++++++++++------------------
1 files changed, 83 insertions(+), 56 deletions(-)
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index c3d5991..032489c 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -5,7 +5,7 @@
| program/include/rcube_imap.php |
| |
| This file is part of the RoundCube Webmail client |
- | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
@@ -66,6 +66,7 @@
var $search_sort_field = '';
var $debug_level = 1;
var $error_code = 0;
+ var $options = array('imap' => 'check');
/**
@@ -90,7 +91,7 @@
* @return boolean TRUE on success, FALSE on failure
* @access public
*/
- function connect($host, $user, $pass, $port=143, $use_ssl=null, $auth_type=null)
+ function connect($host, $user, $pass, $port=143, $use_ssl=null)
{
global $ICL_SSL, $ICL_PORT, $IMAP_USE_INTERNAL_DATE;
@@ -107,7 +108,7 @@
$ICL_PORT = $port;
$IMAP_USE_INTERNAL_DATE = false;
- $this->conn = iil_Connect($host, $user, $pass, array('imap' => $auth_type ? $auth_type : 'check'));
+ $this->conn = iil_Connect($host, $user, $pass, $this->options);
$this->host = $host;
$this->user = $user;
$this->pass = $pass;
@@ -172,6 +173,13 @@
iil_C_Select($this->conn, $this->mailbox);
}
+ /**
+ * Set options to be used in iil_Connect()
+ */
+ function set_options($opt)
+ {
+ $this->options = array_merge($this->options, (array)$opt);
+ }
/**
* Set a root folder for the IMAP connection.
@@ -188,6 +196,7 @@
$root = substr($root, 0, -1);
$this->root_dir = $root;
+ $this->options['rootdir'] = $root;
if (empty($this->delimiter))
$this->get_hierarchy_delimiter();
@@ -294,7 +303,7 @@
$msgs = split(',', $msgs);
$this->search_string = $str;
- $this->search_set = (array)$msgs;
+ $this->search_set = $msgs;
$this->search_charset = $charset;
$this->search_sort_field = $sort_field;
}
@@ -345,8 +354,9 @@
*/
function check_permflag($flag)
{
- $flagsmap = $GLOBALS['IMAP_FLAGS'];
- return (($imap_flag = $flagsmap[strtoupper($flag)]) && in_array_nocase($imap_flag, $this->conn->permanentflags));
+ $flag = strtoupper($flag);
+ $imap_flag = $GLOBALS['IMAP_FLAGS'][$flag];
+ return (in_array_nocase($imap_flag, $this->conn->permanentflags));
}
@@ -676,9 +686,9 @@
$cnt = count($msgs);
if ($cnt > 300 && $cnt > $this->page_size) { // experimantal value for best result
// use memory less expensive (and quick) method for big result set
- $a_index = $this->message_index($mailbox, $this->sort_field, $this->sort_order);
+ $a_index = $this->message_index('', $this->sort_field, $this->sort_order);
// get messages uids for one page...
- $msgs = array_slice(array_keys($a_index), $start_msg, min($cnt-$start_msg, $this->page_size));
+ $msgs = array_slice($a_index, $start_msg, min($cnt-$start_msg, $this->page_size));
// ...and fetch headers
$this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL);
@@ -811,7 +821,7 @@
// we have a saved search result. get index from there
if (!isset($this->cache[$key]) && $this->search_string && $mailbox == $this->mailbox)
{
- $this->cache[$key] = $a_msg_headers = array();
+ $this->cache[$key] = array();
if ($this->get_capability('sort'))
{
@@ -832,7 +842,7 @@
else if ($this->sort_order=="DESC")
arsort($a_index);
- $this->cache[$key] = $a_index;
+ $this->cache[$key] = array_keys($a_index);
}
}
@@ -848,9 +858,8 @@
if ($cache_status>0)
{
$a_index = $this->get_message_cache_index($cache_key, TRUE, $this->sort_field, $this->sort_order);
- return array_values($a_index);
+ return array_keys($a_index);
}
-
// fetch complete message index
$msg_count = $this->_messagecount($mailbox);
@@ -870,7 +879,7 @@
else if ($this->sort_order=="DESC")
arsort($a_index);
- $this->cache[$key] = $a_index;
+ $this->cache[$key] = array_keys($a_index);
}
return $this->cache[$key];
@@ -1039,9 +1048,10 @@
* @param int Message ID
* @param string Mailbox to read from
* @param boolean True if $id is the message UID
+ * @param boolean True if we need also BODYSTRUCTURE in headers
* @return object Message headers representation
*/
- function get_headers($id, $mbox_name=NULL, $is_uid=TRUE)
+ function get_headers($id, $mbox_name=NULL, $is_uid=TRUE, $bodystr=FALSE)
{
$mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
$uid = $is_uid ? $id : $this->_id2uid($id);
@@ -1050,7 +1060,7 @@
if ($uid && ($headers = &$this->get_cached_message($mailbox.'.msg', $uid)))
return $headers;
- $headers = iil_C_FetchHeader($this->conn, $mailbox, $id, $is_uid);
+ $headers = iil_C_FetchHeader($this->conn, $mailbox, $id, $is_uid, $bodystr);
// write headers cache
if ($headers)
@@ -1070,9 +1080,10 @@
* an object structure similar to the one generated by PEAR::Mail_mimeDecode
*
* @param int Message UID to fetch
+ * @param string Message BODYSTRUCTURE string (optional)
* @return object rcube_message_part Message part tree or False on failure
*/
- function &get_structure($uid)
+ function &get_structure($uid, $structure_str='')
{
$cache_key = $this->mailbox.'.msg';
$headers = &$this->get_cached_message($cache_key, $uid, true);
@@ -1087,7 +1098,8 @@
return FALSE;
}
- $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $msg_id);
+ if (!$structure_str)
+ $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $msg_id);
$structure = iml_GetRawStructureArray($structure_str);
$struct = false;
@@ -1122,7 +1134,7 @@
*
* @access private
*/
- function &_structure_part($part, $count=0, $parent='')
+ function &_structure_part($part, $count=0, $parent='', $raw_headers=null)
{
$struct = new rcube_message_part;
$struct->mime_id = empty($parent) ? (string)$count : "$parent.$count";
@@ -1142,11 +1154,25 @@
$struct->mimetype = 'multipart/'.$struct->ctype_secondary;
+ // build parts list for headers pre-fetching
+ for ($i=0, $count=0; $i<count($part); $i++)
+ if (is_array($part[$i]) && count($part[$i]) > 3)
+ // fetch message headers if message/rfc822 or named part (could contain Content-Location header)
+ if (strtolower($part[$i][0]) == 'message' ||
+ (in_array('name', (array)$part[$i][2]) && (empty($part[$i][3]) || $part[$i][3]=='NIL'))) {
+ $part_headers[] = $struct->mime_id ? $struct->mime_id.'.'.$i+1 : $i+1;
+ }
+
+ // pre-fetch headers of all parts (in one command for better performance)
+ if ($part_headers)
+ $part_headers = iil_C_FetchMIMEHeaders($this->conn, $this->mailbox, $this->_msg_id, $part_headers);
+
$struct->parts = array();
for ($i=0, $count=0; $i<count($part); $i++)
if (is_array($part[$i]) && count($part[$i]) > 3)
- $struct->parts[] = $this->_structure_part($part[$i], ++$count, $struct->mime_id);
-
+ $struct->parts[] = $this->_structure_part($part[$i], ++$count, $struct->mime_id,
+ $part_headers[$struct->mime_id ? $struck->mime_id.'.'.$i+1 : $i+1]);
+
return $struct;
}
@@ -1211,8 +1237,9 @@
// fetch message headers if message/rfc822 or named part (could contain Content-Location header)
if ($struct->ctype_primary == 'message' || ($struct->ctype_parameters['name'] && !$struct->content_id)) {
- $part_headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $struct->mime_id);
- $struct->headers = $this->_parse_headers($part_headers) + $struct->headers;
+ if (empty($raw_headers))
+ $raw_headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $struct->mime_id);
+ $struct->headers = $this->_parse_headers($raw_headers) + $struct->headers;
}
if ($struct->ctype_primary=='message') {
@@ -1542,7 +1569,6 @@
*/
function save_message($mbox_name, &$message)
{
- $mbox_name = stripslashes($mbox_name);
$mailbox = $this->_mod_mailbox($mbox_name);
// make sure mailbox exists
@@ -1569,9 +1595,7 @@
*/
function move_message($uids, $to_mbox, $from_mbox='')
{
- $to_mbox_in = stripslashes($to_mbox);
- $from_mbox = stripslashes($from_mbox);
- $to_mbox = $this->_mod_mailbox($to_mbox_in);
+ $to_mbox = $this->_mod_mailbox($to_mbox);
$from_mbox = $from_mbox ? $this->_mod_mailbox($from_mbox) : $this->mailbox;
// make sure mailbox exists
@@ -1646,7 +1670,6 @@
*/
function delete_message($uids, $mbox_name='')
{
- $mbox_name = stripslashes($mbox_name);
$mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
// convert the list of uids to array
@@ -1703,7 +1726,6 @@
*/
function clear_mailbox($mbox_name=NULL)
{
- $mbox_name = stripslashes($mbox_name);
$mailbox = !empty($mbox_name) ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
$msg_count = $this->_messagecount($mailbox, 'ALL');
@@ -1736,7 +1758,6 @@
*/
function expunge($mbox_name='', $clear_cache=TRUE)
{
- $mbox_name = stripslashes($mbox_name);
$mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
return $this->_expunge($mailbox, $clear_cache);
}
@@ -1855,9 +1876,6 @@
{
$result = FALSE;
- // replace backslashes
- $name = preg_replace('/[\\\]+/', '-', $name);
-
// reduce mailbox name to 100 chars
$name = substr($name, 0, 100);
@@ -1886,9 +1904,6 @@
{
$result = FALSE;
- // replace backslashes
- $name = preg_replace('/[\\\]+/', '-', $new_name);
-
// encode mailbox name and reduce it to 100 chars
$name = substr($new_name, 0, 100);
@@ -2146,11 +2161,10 @@
{
$this->db->query(
"UPDATE ".get_table_name('cache')."
- SET created=". $this->db->fromunixtime(time()).", data=?, session_id=?
+ SET created=". $this->db->now().", data=?
WHERE user_id=?
AND cache_key=?",
$data,
- session_id(),
$_SESSION['user_id'],
$key);
}
@@ -2159,12 +2173,11 @@
{
$this->db->query(
"INSERT INTO ".get_table_name('cache')."
- (created, user_id, cache_key, data, session_id)
- VALUES (".$this->db->fromunixtime(time()).", ?, ?, ?, ?)",
+ (created, user_id, cache_key, data)
+ VALUES (".$this->db->now().", ?, ?, ?)",
$_SESSION['user_id'],
$key,
- $data,
- session_id());
+ $data);
}
}
@@ -2335,7 +2348,7 @@
{
if (empty($key) || !is_object($headers) || empty($headers->uid))
return;
-
+
// add to internal (fast) cache
$this->cache['__single_msg'][$headers->uid] = $headers;
$this->cache['__single_msg'][$headers->uid]->structure = $struct;
@@ -2374,7 +2387,7 @@
$this->db->query(
"INSERT INTO ".get_table_name('messages')."
(user_id, del, cache_key, created, idx, uid, subject, ".$this->db->quoteIdentifier('from').", ".$this->db->quoteIdentifier('to').", cc, date, size, headers, structure)
- VALUES (?, 0, ?, ".$this->db->fromunixtime(time()).", ?, ?, ?, ?, ?, ?, ".$this->db->fromunixtime($headers->timestamp).", ?, ?, ?)",
+ VALUES (?, 0, ?, ".$this->db->now().", ?, ?, ?, ?, ?, ?, ".$this->db->fromunixtime($headers->timestamp).", ?, ?, ?)",
$_SESSION['user_id'],
$key,
$index,
@@ -2713,31 +2726,42 @@
$folders[$folder] = rc_strtolower(rcube_charset_convert($folder, 'UTF-7'));
}
+ // sort folders and place defaults on the top
asort($folders, SORT_LOCALE_STRING);
ksort($a_defaults);
-
$folders = array_merge($a_defaults, array_keys($folders));
// finally we must rebuild the list to move
// subfolders of default folders to their place...
// ...also do this for the rest of folders because
// asort() is not properly sorting case sensitive names
-
- // set the type of folder name variable (#1485527)
while (list($key, $folder) = each($folders)) {
+ // set the type of folder name variable (#1485527)
$a_out[] = (string) $folder;
unset($folders[$key]);
- foreach ($folders as $idx => $f) {
- if (strpos($f, $folder.$delimiter) === 0) {
- $a_out[] = (string) $f;
- unset($folders[$idx]);
- }
- }
- reset($folders);
+ $this->_rsort($folder, $delimiter, $folders, $a_out);
}
return $a_out;
}
+
+
+ /**
+ * @access private
+ */
+ function _rsort($folder, $delimiter, &$list, &$out)
+ {
+ while (list($key, $name) = each($list)) {
+ if (strpos($name, $folder.$delimiter) === 0) {
+ // set the type of folder name variable (#1485527)
+ $out[] = (string) $name;
+ unset($list[$key]);
+ $this->_rsort($name, $delimiter, $list, $out);
+ }
+ }
+ reset($list);
+ }
+
/**
* @access private
@@ -2898,7 +2922,7 @@
// remove any newlines and carriage returns before
$a = $this->_explode_quoted_string('[,;]', preg_replace( "/[\r\n]/", " ", $str));
$result = array();
-
+
foreach ($a as $key => $val)
{
$val = preg_replace("/([\"\w])</", "$1 <", $val);
@@ -2907,14 +2931,17 @@
foreach ($sub_a as $k => $v)
{
- if (strpos($v, '@') > 0)
- $result[$key]['address'] = str_replace('<', '', str_replace('>', '', $v));
+ // use angle brackets in regexp to not handle names with @ sign
+ if (preg_match('/^<\S+@\S+>$/', $v))
+ $result[$key]['address'] = trim($v, '<>');
else
$result[$key]['name'] .= (empty($result[$key]['name'])?'':' ').str_replace("\"",'',stripslashes($v));
}
if (empty($result[$key]['name']))
$result[$key]['name'] = $result[$key]['address'];
+ elseif (empty($result[$key]['address']))
+ $result[$key]['address'] = $result[$key]['name'];
}
return $result;
--
Gitblit v1.9.1