From bec9690ff519d33d7ef3f0c8f8f8cf72b4ef059d Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Mon, 20 May 2013 14:52:36 -0400
Subject: [PATCH] Improve some options description
---
program/lib/Roundcube/rcube_imap.php | 107 +++++++++++++++++++++++++++++++----------------------
1 files changed, 63 insertions(+), 44 deletions(-)
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 9054b6b..43c61fd 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -2,8 +2,6 @@
/*
+-----------------------------------------------------------------------+
- | program/include/rcube_imap.php |
- | |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2005-2012, The Roundcube Dev Team |
| Copyright (C) 2011-2012, Kolab Systems AG |
@@ -14,13 +12,11 @@
| |
| PURPOSE: |
| IMAP Storage Engine |
- | |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
-
/**
* Interface class for accessing an IMAP server
@@ -141,17 +137,17 @@
$this->set_debug(true);
$this->options['ident'] = array(
- 'name' => 'Roundcube Webmail',
- 'version' => RCMAIL_VERSION,
- 'php' => PHP_VERSION,
- 'os' => PHP_OS,
+ 'name' => 'Roundcube',
+ 'version' => RCUBE_VERSION,
+ 'php' => PHP_VERSION,
+ 'os' => PHP_OS,
'command' => $_SERVER['REQUEST_URI'],
);
}
$attempt = 0;
do {
- $data = rcube::get_instance()->plugins->exec_hook('imap_connect',
+ $data = rcube::get_instance()->plugins->exec_hook('storage_connect',
array_merge($this->options, array('host' => $host, 'user' => $user,
'attempt' => ++$attempt)));
@@ -571,7 +567,7 @@
* Get message count for a specific folder
*
* @param string $folder Folder name
- * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT]
+ * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS]
* @param boolean $force Force reading from server and update cache
* @param boolean $status Enables storing folder status info (max UID/count),
* required for folder_status()
@@ -592,7 +588,7 @@
* protected method for getting nr of messages
*
* @param string $folder Folder name
- * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT]
+ * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS]
* @param boolean $force Force reading from server and update cache
* @param boolean $status Enables storing folder status info (max UID/count),
* required for folder_status()
@@ -613,6 +609,10 @@
return $this->search_set->count();
}
}
+
+ // EXISTS is a special alias for ALL, it allows to get the number
+ // of all messages in a folder also when search is active and with
+ // any skip_deleted setting
$a_folder_cache = $this->get_cache('messagecount');
@@ -644,7 +644,7 @@
$count = $this->conn->countRecent($folder);
}
// use SEARCH for message counting
- else if (!empty($this->options['skip_deleted'])) {
+ else if ($mode != 'EXISTS' && !empty($this->options['skip_deleted'])) {
$search_str = "ALL UNDELETED";
$keys = array('COUNT');
@@ -683,8 +683,8 @@
}
else {
$count = $this->conn->countMessages($folder);
- if ($status) {
- $this->set_folder_stats($folder,'cnt', $count);
+ if ($status && $mode == 'ALL') {
+ $this->set_folder_stats($folder, 'cnt', $count);
$this->set_folder_stats($folder, 'maxuid', $count ? $this->id2uid($count, $folder) : 0);
}
}
@@ -981,7 +981,7 @@
// use memory less expensive (and quick) method for big result set
$index = clone $this->index('', $this->sort_field, $this->sort_order);
// get messages uids for one page...
- $index->slice($start_msg, min($cnt-$from, $this->page_size));
+ $index->slice($from, min($cnt-$from, $this->page_size));
if ($slice) {
$index->slice(-$slice, $slice);
@@ -1096,16 +1096,17 @@
/**
- * Returns current status of folder
+ * Returns current status of a folder (compared to the last time use)
*
* We compare the maximum UID to determine the number of
* new messages because the RECENT flag is not reliable.
*
* @param string $folder Folder name
+ * @param array $diff Difference data
*
- * @return int Folder status
+ * @return int Folder status
*/
- public function folder_status($folder = null)
+ public function folder_status($folder = null, &$diff = array())
{
if (!strlen($folder)) {
$folder = $this->folder;
@@ -1126,6 +1127,9 @@
// got new messages
if ($new['maxuid'] > $old['maxuid']) {
$result += 1;
+ // get new message UIDs range, that can be used for example
+ // to get the data of these messages
+ $diff['new'] = ($old['maxuid'] + 1 < $new['maxuid'] ? ($old['maxuid']+1).':' : '') . $new['maxuid'];
}
// some messages has been deleted
if ($new['cnt'] < $old['cnt']) {
@@ -1419,8 +1423,6 @@
*/
protected function search_index($folder, $criteria='ALL', $charset=NULL, $sort_field=NULL)
{
- $orig_criteria = $criteria;
-
if (!$this->check_connection()) {
if ($this->threading) {
return new rcube_result_thread();
@@ -1634,9 +1636,15 @@
// Example of structure for malformed MIME message:
// ("text" "plain" NIL NIL NIL "7bit" 2154 70 NIL NIL NIL)
if ($headers->ctype && !is_array($structure[0]) && $headers->ctype != 'text/plain'
- && strtolower($structure[0].'/'.$structure[1]) == 'text/plain') {
+ && strtolower($structure[0].'/'.$structure[1]) == 'text/plain'
+ ) {
+ // A special known case "Content-type: text" (#1488968)
+ if ($headers->ctype == 'text') {
+ $structure[1] = 'plain';
+ $headers->ctype = 'text/plain';
+ }
// we can handle single-part messages, by simple fix in structure (#1486898)
- if (preg_match('/^(text|application)\/(.*)/', $headers->ctype, $m)) {
+ else if (preg_match('/^(text|application)\/(.*)/', $headers->ctype, $m)) {
$structure[0] = $m[1];
$structure[1] = $m[2];
}
@@ -1660,11 +1668,21 @@
$struct = $this->structure_part($structure, 0, '', $headers);
}
- // don't trust given content-type
- if (empty($struct->parts) && !empty($headers->ctype)) {
- $struct->mime_id = '1';
- $struct->mimetype = strtolower($headers->ctype);
- list($struct->ctype_primary, $struct->ctype_secondary) = explode('/', $struct->mimetype);
+ // some workarounds on simple messages...
+ if (empty($struct->parts)) {
+ // ...don't trust given content-type
+ if (!empty($headers->ctype)) {
+ $struct->mime_id = '1';
+ $struct->mimetype = strtolower($headers->ctype);
+ list($struct->ctype_primary, $struct->ctype_secondary) = explode('/', $struct->mimetype);
+ }
+
+ // ...and charset (there's a case described in #1488968 where invalid content-type
+ // results in invalid charset in BODYSTRUCTURE)
+ if (!empty($headers->charset) && $headers->charset != $struct->ctype_parameters['charset']) {
+ $struct->charset = $headers->charset;
+ $struct->ctype_parameters['charset'] = $headers->charset;
+ }
}
$headers->structure = $struct;
@@ -2051,10 +2069,11 @@
* @param mixed $print True to print part, ressource to write part contents in
* @param resource $fp File pointer to save the message part
* @param boolean $skip_charset_conv Disables charset conversion
+ * @param int $max_bytes Only read this number of bytes
*
* @return string Message/part body if not printed
*/
- public function get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false)
+ public function get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false, $max_bytes=0)
{
if (!$this->check_connection()) {
return null;
@@ -2074,7 +2093,7 @@
if ($o_part && $o_part->size) {
$body = $this->conn->handlePartBody($this->folder, $uid, true,
- $part ? $part : 'TEXT', $o_part->encoding, $print, $fp, $o_part->ctype_primary == 'text');
+ $part ? $part : 'TEXT', $o_part->encoding, $print, $fp, $o_part->ctype_primary == 'text', $max_bytes);
}
if ($fp || $print) {
@@ -2188,10 +2207,10 @@
$result = $this->conn->flag($folder, $uids, $flag);
}
- if ($result) {
+ if ($result && !$skip_cache) {
// reload message headers if cached
- // @TODO: update flags instead removing from cache
- if (!$skip_cache && ($mcache = $this->get_mcache_engine())) {
+ // update flags instead removing from cache
+ if ($mcache = $this->get_mcache_engine()) {
$status = strpos($flag, 'UN') !== 0;
$mflag = preg_replace('/^UN/', '', $flag);
$mcache->change_flag($folder, $all_mode ? null : explode(',', $uids),
@@ -2203,8 +2222,12 @@
$this->clear_messagecount($folder, 'SEEN');
$this->clear_messagecount($folder, 'UNSEEN');
}
- else if ($flag == 'DELETED') {
+ else if ($flag == 'DELETED' || $flag == 'UNDELETED') {
$this->clear_messagecount($folder, 'DELETED');
+ // remove cached messages
+ if ($this->options['skip_deleted']) {
+ $this->clear_message_cache($folder, $all_mode ? null : explode(',', $uids));
+ }
}
}
@@ -2221,10 +2244,11 @@
* @param boolean $is_file True if $message is a filename
* @param array $flags Message flags
* @param mixed $date Message internal date
+ * @param bool $binary Enables BINARY append
*
* @return int|bool Appended message UID or True on success, False on error
*/
- public function save_message($folder, &$message, $headers='', $is_file=false, $flags = array(), $date = null)
+ public function save_message($folder, &$message, $headers='', $is_file=false, $flags = array(), $date = null, $binary = false)
{
if (!strlen($folder)) {
$folder = $this->folder;
@@ -2242,10 +2266,10 @@
$date = $this->date_format($date);
if ($is_file) {
- $saved = $this->conn->appendFromFile($folder, $message, $headers, $flags, $date);
+ $saved = $this->conn->appendFromFile($folder, $message, $headers, $flags, $date, $binary);
}
else {
- $saved = $this->conn->append($folder, $message, $flags, $date);
+ $saved = $this->conn->append($folder, $message, $flags, $date, $binary);
}
if ($saved) {
@@ -2311,10 +2335,7 @@
// move messages
$moved = $this->conn->move($uids, $from_mbox, $to_mbox);
- // send expunge command in order to have the moved message
- // really deleted from the source folder
if ($moved) {
- $this->expunge_message($uids, $from_mbox, false);
$this->clear_messagecount($from_mbox);
$this->clear_messagecount($to_mbox);
}
@@ -2704,7 +2725,7 @@
// filter folders list according to rights requirements
if ($rights && $this->get_capability('ACL')) {
- $a_folders = $this->filter_rights($a_folders, $rights);
+ $a_mboxes = $this->filter_rights($a_mboxes, $rights);
}
// filter folders and sort them
@@ -2760,7 +2781,6 @@
*/
private function list_folders_update(&$result, $type = null)
{
- $delim = $this->get_hierarchy_delimiter();
$namespace = $this->get_namespace();
$search = array();
@@ -3349,7 +3369,6 @@
{
if (!empty($this->options['fetch_headers'])) {
$headers = explode(' ', $this->options['fetch_headers']);
- $headers = array_map('strtoupper', $headers);
}
else {
$headers = array();
@@ -3359,7 +3378,7 @@
$headers = array_merge($headers, $this->all_headers);
}
- return implode(' ', array_unique($headers));
+ return $headers;
}
@@ -3824,7 +3843,7 @@
$delimiter = $this->get_hierarchy_delimiter();
// find default folders and skip folders starting with '.'
- foreach ($a_folders as $i => $folder) {
+ foreach ($a_folders as $folder) {
if ($folder[0] == '.') {
continue;
}
--
Gitblit v1.9.1