- small backend cleanup + support for operations on ALL messages in a folder

release-0.6
alecpl 15 years ago
parent b488c1d02d
commit cff88617c0

@ -2104,42 +2104,42 @@ class rcube_imap
/**
* Set message flag to one or several messages
*
* @param mixed Message UIDs as array or as comma-separated string
* @param string Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
* @param string Folder name
* @param mixed Message UIDs as array or comma-separated string, or '*'
* @param string Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
* @param string Folder name
* @param boolean True to skip message cache clean up
* @return boolean True on success, False on failure
* @return int Number of flagged messages, -1 on failure
*/
function set_flag($uids, $flag, $mbox_name=NULL, $skip_cache=false)
{
$mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
$flag = strtoupper($flag);
if (!is_array($uids))
$uids = explode(',',$uids);
list($uids, $all_mode) = $this->_parse_uids($uids);
if (strpos($flag, 'UN') === 0)
$result = iil_C_UnFlag($this->conn, $mailbox, join(',', $uids), substr($flag, 2));
$result = iil_C_UnFlag($this->conn, $mailbox, $uids, substr($flag, 2));
else
$result = iil_C_Flag($this->conn, $mailbox, join(',', $uids), $flag);
// reload message headers if cached
if ($this->caching_enabled && !$skip_cache) {
$cache_key = $mailbox.'.msg';
$this->remove_message_cache($cache_key, $uids);
$result = iil_C_Flag($this->conn, $mailbox, $uids, $flag);
if ($result >= 0) {
// reload message headers if cached
if ($this->caching_enabled && !$skip_cache) {
$cache_key = $mailbox.'.msg';
if ($all_mode)
$this->clear_message_cache($cache_key);
else
$this->remove_message_cache($cache_key, explode(',', $uids));
}
// update counters
if ($flag=='SEEN')
$this->_set_messagecount($mailbox, 'UNSEEN', $result*(-1));
else if ($flag=='UNSEEN')
$this->_set_messagecount($mailbox, 'UNSEEN', $result);
else if ($flag=='DELETED')
$this->_set_messagecount($mailbox, 'ALL', $result*(-1));
}
// set nr of messages that were flaged
$count = count($uids);
// clear message count cache
if ($result && $flag=='SEEN')
$this->_set_messagecount($mailbox, 'UNSEEN', $count*(-1));
else if ($result && $flag=='UNSEEN')
$this->_set_messagecount($mailbox, 'UNSEEN', $count);
else if ($result && $flag=='DELETED')
$this->_set_messagecount($mailbox, 'ALL', $count*(-1));
return $result;
}
@ -2147,10 +2147,10 @@ class rcube_imap
/**
* Remove message flag for one or several messages
*
* @param mixed Message UIDs as array or as comma-separated string
* @param mixed Message UIDs as array or comma-separated string, or '*'
* @param string Flag to unset: SEEN, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
* @param string Folder name
* @return boolean True on success, False on failure
* @return int Number of flagged messages, -1 on failure
* @see set_flag
*/
function unset_flag($uids, $flag, $mbox_name=NULL)
@ -2197,7 +2197,7 @@ class rcube_imap
/**
* Move a message from one mailbox to another
*
* @param string List of UIDs to move, separated by comma
* @param mixed Message UIDs as array or comma-separated string, or '*'
* @param string Target mailbox
* @param string Source mailbox
* @return boolean True on success, False on error
@ -2209,11 +2209,10 @@ class rcube_imap
$to_mbox = $this->mod_mailbox($to_mbox);
$from_mbox = $from_mbox ? $this->mod_mailbox($from_mbox) : $this->mailbox;
// convert the list of uids to array
$a_uids = is_string($uids) ? explode(',', $uids) : (is_array($uids) ? $uids : NULL);
list($uids, $all_mode) = $this->_parse_uids($uids);
// exit if no message uids are specified
if (!is_array($a_uids) || empty($a_uids))
if (empty($uids))
return false;
// make sure mailbox exists
@ -2233,19 +2232,19 @@ class rcube_imap
}
// move messages
$iil_move = iil_C_Move($this->conn, join(',', $a_uids), $from_mbox, $to_mbox);
$iil_move = iil_C_Move($this->conn, $uids, $from_mbox, $to_mbox);
$moved = !($iil_move === false || $iil_move < 0);
// send expunge command in order to have the moved message
// really deleted from the source mailbox
if ($moved) {
$this->_expunge($from_mbox, false, $a_uids);
$this->_expunge($from_mbox, false, $uids);
$this->_clear_messagecount($from_mbox);
$this->_clear_messagecount($to_mbox);
}
// moving failed
else if ($config->get('delete_always', false) && $tbox == $config->get('trash_mbox')) {
$moved = $this->delete_message($a_uids, $fbox);
$moved = $this->delete_message($uids, $fbox);
}
if ($moved) {
@ -2255,10 +2254,11 @@ class rcube_imap
// remove message ids from search set
if ($this->search_set && $from_mbox == $this->mailbox) {
// threads are too complicated to just remove messages from set
if ($this->search_threads)
if ($this->search_threads || $all_mode)
$this->refresh_search();
else {
foreach ($a_uids as $uid)
$uids = explode(',', $uids);
foreach ($uids as $uid)
$a_mids[] = $this->_uid2id($uid, $from_mbox);
$this->search_set = array_diff($this->search_set, $a_mids);
}
@ -2266,9 +2266,9 @@ class rcube_imap
// update cached message headers
$cache_key = $from_mbox.'.msg';
if ($start_index = $this->get_message_cache_index_min($cache_key, $a_uids)) {
if ($all_mode || ($start_index = $this->get_message_cache_index_min($cache_key, $uids))) {
// clear cache from the lowest index on
$this->clear_message_cache($cache_key, $start_index);
$this->clear_message_cache($cache_key, $all_mode ? 1 : $start_index);
}
}
@ -2279,7 +2279,7 @@ class rcube_imap
/**
* Copy a message from one mailbox to another
*
* @param string List of UIDs to copy, separated by comma
* @param mixed Message UIDs as array or comma-separated string, or '*'
* @param string Target mailbox
* @param string Source mailbox
* @return boolean True on success, False on error
@ -2291,11 +2291,10 @@ class rcube_imap
$to_mbox = $this->mod_mailbox($to_mbox);
$from_mbox = $from_mbox ? $this->mod_mailbox($from_mbox) : $this->mailbox;
// convert the list of uids to array
$a_uids = is_string($uids) ? explode(',', $uids) : (is_array($uids) ? $uids : NULL);
list($uids, $all_mode) = $this->_parse_uids($uids);
// exit if no message uids are specified
if (!is_array($a_uids) || empty($a_uids))
if (empty($uids))
return false;
// make sure mailbox exists
@ -2308,7 +2307,7 @@ class rcube_imap
}
// copy messages
$iil_copy = iil_C_Copy($this->conn, join(',', $a_uids), $from_mbox, $to_mbox);
$iil_copy = iil_C_Copy($this->conn, $uids, $from_mbox, $to_mbox);
$copied = !($iil_copy === false || $iil_copy < 0);
if ($copied) {
@ -2322,7 +2321,7 @@ class rcube_imap
/**
* Mark messages as deleted and expunge mailbox
*
* @param string List of UIDs to move, separated by comma
* @param mixed Message UIDs as array or comma-separated string, or '*'
* @param string Source mailbox
* @return boolean True on success, False on error
*/
@ -2330,19 +2329,18 @@ class rcube_imap
{
$mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
// convert the list of uids to array
$a_uids = is_string($uids) ? explode(',', $uids) : (is_array($uids) ? $uids : NULL);
list($uids, $all_mode) = $this->_parse_uids($uids);
// exit if no message uids are specified
if (!is_array($a_uids) || empty($a_uids))
if (empty($uids))
return false;
$deleted = iil_C_Delete($this->conn, $mailbox, join(',', $a_uids));
$deleted = iil_C_Delete($this->conn, $mailbox, $uids);
if ($deleted) {
// send expunge command in order to have the deleted message
// really deleted from the mailbox
$this->_expunge($mailbox, false, $a_uids);
$this->_expunge($mailbox, false, $uids);
$this->_clear_messagecount($mailbox);
unset($this->uid_id_map[$mailbox]);
@ -2352,10 +2350,11 @@ class rcube_imap
// remove message ids from search set
if ($this->search_set && $mailbox == $this->mailbox) {
// threads are too complicated to just remove messages from set
if ($this->search_threads)
if ($this->search_threads || $all_mode)
$this->refresh_search();
else {
foreach ($a_uids as $uid)
$uids = explode(',', $uids);
foreach ($uids as $uid)
$a_mids[] = $this->_uid2id($uid, $mailbox);
$this->search_set = array_diff($this->search_set, $a_mids);
}
@ -2363,9 +2362,9 @@ class rcube_imap
// remove deleted messages from cache
$cache_key = $mailbox.'.msg';
if ($start_index = $this->get_message_cache_index_min($cache_key, $a_uids)) {
if ($all_mode || ($start_index = $this->get_message_cache_index_min($cache_key, $uids))) {
// clear cache from the lowest index on
$this->clear_message_cache($cache_key, $start_index);
$this->clear_message_cache($cache_key, $all_mode ? 1 : $start_index);
}
}
@ -2421,12 +2420,12 @@ class rcube_imap
/**
* Send IMAP expunge command and clear cache
*
* @see rcube_imap::expunge()
* @param string Mailbox name
* @param boolean False if cache should not be cleared
* @param string List of UIDs to remove, separated by comma
* @param string Mailbox name
* @param boolean False if cache should not be cleared
* @param mixed Message UIDs as array or comma-separated string, or '*'
* @return boolean True on success
* @access private
* @see rcube_imap::expunge()
*/
private function _expunge($mailbox, $clear_cache=true, $uids=NULL)
{
@ -2447,11 +2446,35 @@ class rcube_imap
}
/**
* Parse message UIDs input
*
* @param mixed UIDs array or comma-separated list or '*' or '1:*'
* @return array Two elements array with UIDs converted to list and ALL flag
* @access private
*/
private function _parse_uids($uids)
{
if ($uids === '*' || $uids === '1:*') {
$uids = '1:*';
$all = true;
}
else {
if (is_array($uids))
$uids = join(',', $uids);
if (preg_match('/[^0-9,]/', $uids))
$uids = '';
}
return array($uids, (bool) $all);
}
/* --------------------------------
* folder managment
* --------------------------------*/
/**
* Get a list of all folders available on the IMAP server
*
@ -3148,6 +3171,13 @@ class rcube_imap
if (!$this->caching_enabled)
return;
if (!empty($uids) && !is_array($uids)) {
if ($uids == '*' || $uids == '1:*')
$uids = NULL;
else
$uids = explode(',', $uids);
}
$sql_result = $this->db->query(
"SELECT MIN(idx) AS minidx
FROM ".get_table_name('messages')."

@ -389,7 +389,7 @@ function iil_C_GetCapability(&$conn, $name)
return false;
}
function iil_C_ClearCapability(&$conn)
function iil_ClearCapability()
{
$conn->capability = array();
$conn->capability_readed = false;
@ -660,7 +660,7 @@ function iil_Connect($host, $user, $password, $options=null) {
}
// Now we're authenticated, capabilities need to be reread
iil_C_ClearCapability($conn);
iil_ClearCapability();
}
}
@ -1425,10 +1425,10 @@ function iil_C_Expunge(&$conn, $mailbox, $messages=NULL) {
iil_PutLine($conn->fp, "exp1 $command");
do {
$line=chop(iil_ReadLine($conn->fp, 100));
$line = iil_ReadLine($conn->fp, 100);
if ($line[0] == '*') {
$c++;
}
$c++;
}
} while (!iil_StartsWith($line, 'exp1', true));
if (iil_ParseResult($line) == 0) {
@ -1447,29 +1447,27 @@ function iil_C_ModFlag(&$conn, $mailbox, $messages, $flag, $mod) {
return -1;
}
$fp = $conn->fp;
$flags = $GLOBALS['IMAP_FLAGS'];
$flag = strtoupper($flag);
$flag = $flags[$flag];
$flag = $flags[strtoupper($flag)];
if (iil_C_Select($conn, $mailbox)) {
$c = 0;
iil_PutLine($fp, "flg UID STORE $messages " . $mod . "FLAGS (" . $flag . ")");
do {
$line=chop(iil_ReadLine($fp, 100));
if ($line[0] == '*') {
$c++;
}
} while (!iil_StartsWith($line, 'flg', true));
if (!iil_C_Select($conn, $mailbox)) {
return -1;
}
$c = 0;
iil_PutLine($conn->fp, "flg UID STORE $messages " . $mod . "FLAGS (" . $flag . ")");
do {
$line = iil_ReadLine($conn->fp, 1000);
if ($line[0] == '*') {
$c++;
}
} while (!iil_StartsWith($line, 'flg', true));
if (iil_ParseResult($line) == 0) {
return $c;
}
$conn->error = $line;
return -1;
if (iil_ParseResult($line) == 0) {
return $c;
}
$conn->error = 'Select failed';
$conn->error = $line;
return -1;
}
@ -1486,28 +1484,25 @@ function iil_C_Delete(&$conn, $mailbox, $messages) {
}
function iil_C_Copy(&$conn, $messages, $from, $to) {
$fp = $conn->fp;
if (empty($from) || empty($to)) {
return -1;
}
if (iil_C_Select($conn, $from)) {
$c=0;
iil_PutLine($fp, "cpy1 UID COPY $messages \"".iil_Escape($to)."\"");
$line = iil_ReadReply($fp);
return iil_ParseResult($line);
} else {
return -1;
if (!iil_C_Select($conn, $from)) {
return -1;
}
iil_PutLine($conn->fp, "cpy1 UID COPY $messages \"".iil_Escape($to)."\"");
$line = iil_ReadReply($conn->fp);
return iil_ParseResult($line);
}
function iil_C_CountUnseen(&$conn, $folder) {
$index = iil_C_Search($conn, $folder, 'ALL UNSEEN');
if (is_array($index))
return count($index);
return false;
$index = iil_C_Search($conn, $folder, 'ALL UNSEEN');
if (is_array($index))
return count($index);
return false;
}
function iil_C_UID2ID(&$conn, $folder, $uid) {

Loading…
Cancel
Save