|
|
|
@ -27,6 +27,9 @@
|
|
|
|
|
*/
|
|
|
|
|
class rcube_imap_cache
|
|
|
|
|
{
|
|
|
|
|
const MODE_INDEX = 1;
|
|
|
|
|
const MODE_MESSAGE = 2;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Instance of rcube_imap
|
|
|
|
|
*
|
|
|
|
@ -70,6 +73,7 @@ class rcube_imap_cache
|
|
|
|
|
private $icache = array();
|
|
|
|
|
|
|
|
|
|
private $skip_deleted = false;
|
|
|
|
|
private $mode;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* List of known flags. Thanks to this we can handle flag changes
|
|
|
|
@ -95,6 +99,7 @@ class rcube_imap_cache
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Object constructor.
|
|
|
|
|
*
|
|
|
|
@ -117,6 +122,9 @@ class rcube_imap_cache
|
|
|
|
|
$this->skip_deleted = $skip_deleted;
|
|
|
|
|
$this->ttl = $ttl;
|
|
|
|
|
$this->threshold = $threshold;
|
|
|
|
|
|
|
|
|
|
// cache all possible information by default
|
|
|
|
|
$this->mode = self::MODE_INDEX | self::MODE_MESSAGE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -130,6 +138,17 @@ class rcube_imap_cache
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set cache mode
|
|
|
|
|
*
|
|
|
|
|
* @param int $mode Cache mode
|
|
|
|
|
*/
|
|
|
|
|
public function set_mode($mode)
|
|
|
|
|
{
|
|
|
|
|
$this->mode = $mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return (sorted) messages index (UIDs).
|
|
|
|
|
* If index doesn't exist or is invalid, will be updated.
|
|
|
|
@ -308,6 +327,10 @@ class rcube_imap_cache
|
|
|
|
|
return array();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$msgs = array_flip($msgs);
|
|
|
|
|
$result = array();
|
|
|
|
|
|
|
|
|
|
if ($this->mode & self::MODE_MESSAGE) {
|
|
|
|
|
// Fetch messages from cache
|
|
|
|
|
$sql_result = $this->db->query(
|
|
|
|
|
"SELECT uid, data, flags"
|
|
|
|
@ -317,9 +340,6 @@ class rcube_imap_cache
|
|
|
|
|
." AND uid IN (".$this->db->array2list($msgs, 'integer').")",
|
|
|
|
|
$this->userid, $mailbox);
|
|
|
|
|
|
|
|
|
|
$msgs = array_flip($msgs);
|
|
|
|
|
$result = array();
|
|
|
|
|
|
|
|
|
|
while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
|
|
|
|
|
$uid = intval($sql_arr['uid']);
|
|
|
|
|
$result[$uid] = $this->build_message($sql_arr);
|
|
|
|
@ -331,6 +351,7 @@ class rcube_imap_cache
|
|
|
|
|
unset($msgs[$uid]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fetch not found messages from IMAP server
|
|
|
|
|
if (!empty($msgs)) {
|
|
|
|
@ -339,7 +360,10 @@ class rcube_imap_cache
|
|
|
|
|
// Insert to DB and add to result list
|
|
|
|
|
if (!empty($messages)) {
|
|
|
|
|
foreach ($messages as $msg) {
|
|
|
|
|
if ($this->mode & self::MODE_MESSAGE) {
|
|
|
|
|
$this->add_message($mailbox, $msg, !array_key_exists($msg->uid, $result));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$result[$msg->uid] = $msg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -370,6 +394,7 @@ class rcube_imap_cache
|
|
|
|
|
return $this->icache['__message']['object'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($this->mode & self::MODE_MESSAGE) {
|
|
|
|
|
$sql_result = $this->db->query(
|
|
|
|
|
"SELECT flags, data"
|
|
|
|
|
." FROM ".$this->db->table_name('cache_messages')
|
|
|
|
@ -382,6 +407,7 @@ class rcube_imap_cache
|
|
|
|
|
$message = $this->build_message($sql_arr);
|
|
|
|
|
$found = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the message from IMAP server
|
|
|
|
|
if (empty($message) && $update) {
|
|
|
|
@ -389,6 +415,10 @@ class rcube_imap_cache
|
|
|
|
|
// cache will be updated in close(), see below
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!($this->mode & self::MODE_MESSAGE)) {
|
|
|
|
|
return $message;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save the message in internal cache, will be written to DB in close()
|
|
|
|
|
// Common scenario: user opens unseen message
|
|
|
|
|
// - get message (SELECT)
|
|
|
|
@ -424,6 +454,10 @@ class rcube_imap_cache
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!($this->mode & self::MODE_MESSAGE)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$flags = 0;
|
|
|
|
|
$msg = clone $message;
|
|
|
|
|
|
|
|
|
@ -495,6 +529,10 @@ class rcube_imap_cache
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!($this->mode & self::MODE_MESSAGE)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$flag = strtoupper($flag);
|
|
|
|
|
$idx = (int) array_search($flag, $this->flags);
|
|
|
|
|
$uids = (array) $uids;
|
|
|
|
@ -535,6 +573,10 @@ class rcube_imap_cache
|
|
|
|
|
*/
|
|
|
|
|
function remove_message($mailbox = null, $uids = null)
|
|
|
|
|
{
|
|
|
|
|
if (!($this->mode & self::MODE_MESSAGE)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strlen($mailbox)) {
|
|
|
|
|
$this->db->query(
|
|
|
|
|
"DELETE FROM ".$this->db->table_name('cache_messages')
|
|
|
|
@ -1036,6 +1078,7 @@ class rcube_imap_cache
|
|
|
|
|
$removed = array();
|
|
|
|
|
|
|
|
|
|
// Get known UIDs
|
|
|
|
|
if ($this->mode & self::MODE_MESSAGE) {
|
|
|
|
|
$sql_result = $this->db->query(
|
|
|
|
|
"SELECT uid"
|
|
|
|
|
." FROM ".$this->db->table_name('cache_messages')
|
|
|
|
@ -1046,6 +1089,7 @@ class rcube_imap_cache
|
|
|
|
|
while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
|
|
|
|
|
$uids[] = $sql_arr['uid'];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Synchronize messages data
|
|
|
|
|
if (!empty($uids)) {
|
|
|
|
|