diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php --- a/plugins/libkolab/lib/kolab_storage.php +++ b/plugins/libkolab/lib/kolab_storage.php @@ -86,11 +86,7 @@ (self::$imap->get_capability('METADATA') || self::$imap->get_capability('ANNOTATEMORE') || self::$imap->get_capability('ANNOTATEMORE2')); if (self::$ready) { - // set imap options - self::$imap->set_options(array( - 'skip_deleted' => true, - 'threading' => false, - )); + // do nothing } else if (!class_exists('kolabformat')) { rcube::raise_error(array( diff --git a/plugins/libkolab/lib/kolab_storage_cache.php b/plugins/libkolab/lib/kolab_storage_cache.php --- a/plugins/libkolab/lib/kolab_storage_cache.php +++ b/plugins/libkolab/lib/kolab_storage_cache.php @@ -186,7 +186,9 @@ if (!$this->ready) { // kolab cache is disabled, synchronize IMAP mailbox cache only + $this->imap_mode(true); $this->imap->folder_sync($this->folder->name); + $this->imap_mode(false); } else { // read cached folder metadata @@ -204,7 +206,7 @@ $this->_sync_lock(); // disable messages cache if configured to do so - $this->bypass(true); + $this->imap_mode(true); // synchronize IMAP mailbox cache $this->imap->folder_sync($this->folder->name); @@ -212,6 +214,8 @@ // compare IMAP index with object cache index $imap_index = $this->imap->index($this->folder->name, null, null, true, true); + $this->imap_mode(false); + // determine objects to fetch or to invalidate if (!$imap_index->is_error()) { $imap_index = $imap_index->get(); @@ -261,8 +265,6 @@ } } - $this->bypass(false); - // remove lock $this->_sync_unlock(); } @@ -603,6 +605,8 @@ else { $filter = $this->_query2assoc($query); + $this->imap_mode(true); + if ($filter['type']) { $search = 'UNDELETED HEADER X-Kolab-Type ' . kolab_format::KTYPE_PREFIX . $filter['type']; $index = $this->imap->search_once($this->folder->name, $search); @@ -611,6 +615,8 @@ $index = $this->imap->index($this->folder->name, null, null, true, true); } + $this->imap_mode(false); + if ($index->is_error()) { $this->check_error(); if ($uids) { @@ -670,6 +676,8 @@ else { $filter = $this->_query2assoc($query); + $this->imap_mode(true); + if ($filter['type']) { $search = 'UNDELETED HEADER X-Kolab-Type ' . kolab_format::KTYPE_PREFIX . $filter['type']; $index = $this->imap->search_once($this->folder->name, $search); @@ -678,6 +686,8 @@ $index = $this->imap->index($this->folder->name, null, null, true, true); } + $this->imap_mode(false); + if ($index->is_error()) { $this->check_error(); return null; @@ -1136,13 +1146,31 @@ } /** - * Bypass Roundcube messages cache. - * Roundcube cache duplicates information already stored in kolab_cache. + * Set Roundcube storage options and bypass messages cache. * - * @param bool $disable True disables, False enables messages cache + * We use skip_deleted and threading settings specific to Kolab, + * we have to change these global settings only temporarily. + * Roundcube cache duplicates information already stored in kolab_cache, + * that's why we can disable it for better performance. + * + * @param bool $force True to start Kolab mode, False to stop it. */ - public function bypass($disable = false) + public function imap_mode($force = false) { + // remember current IMAP settings + if ($force) { + $this->imap_options = array( + 'skip_deleted' => $this->imap->get_option('skip_deleted'), + 'threading' => $this->imap->get_threading(), + ); + } + + // re-set IMAP settings + $this->imap->set_threading($force ? false : $this->imap_options['threading']); + $this->imap->set_options(array( + 'skip_deleted' => $force ? true : $this->imap_options['skip_deleted'], + )); + // if kolab cache is disabled do nothing if (!$this->enabled) { return; @@ -1158,7 +1186,7 @@ if ($messages_cache) { // handle recurrent (multilevel) bypass() calls - if ($disable) { + if ($force) { $this->cache_bypassed += 1; if ($this->cache_bypassed > 1) { return; @@ -1174,7 +1202,7 @@ switch ($cache_bypass) { case 2: // Disable messages cache completely - $this->imap->set_messages_caching(!$disable); + $this->imap->set_messages_caching(!$force); break; case 1: @@ -1182,7 +1210,7 @@ // Default mode is both (MODE_INDEX | MODE_MESSAGE) $mode = rcube_imap_cache::MODE_INDEX; - if (!$disable) { + if (!$force) { $mode |= rcube_imap_cache::MODE_MESSAGE; } diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php --- a/plugins/libkolab/lib/kolab_storage_folder.php +++ b/plugins/libkolab/lib/kolab_storage_folder.php @@ -49,7 +49,6 @@ function __construct($name, $type = null, $type_annotation = null) { parent::__construct($name); - $this->imap->set_options(array('skip_deleted' => true)); $this->set_folder($name, $type, $type_annotation); } @@ -448,9 +447,9 @@ $this->imap->set_folder($folder); - $this->cache->bypass(true); + $this->cache->imap_mode(true); $message = new rcube_message($msguid); - $this->cache->bypass(false); + $this->cache->imap_mode(false); // Message doesn't exist? if (empty($message->headers)) { @@ -698,9 +697,9 @@ if ($old_uid) { // delete old message - $this->cache->bypass(true); + $this->cache->imap_mode(true); $this->imap->delete_message($old_uid, $object['_mailbox']); - $this->cache->bypass(false); + $this->cache->imap_mode(false); } // insert/update message in cache @@ -796,7 +795,7 @@ $msguid = is_array($object) ? $object['_msguid'] : $this->cache->uid2msguid($object); $success = false; - $this->cache->bypass(true); + $this->cache->imap_mode(true); if ($msguid && $expunge) { $success = $this->imap->delete_message($msguid, $this->name); @@ -805,7 +804,7 @@ $success = $this->imap->set_flag($msguid, 'DELETED', $this->name); } - $this->cache->bypass(false); + $this->cache->imap_mode(false); if ($success) { $this->cache->set($msguid, false); @@ -824,9 +823,9 @@ } $this->cache->purge(); - $this->cache->bypass(true); + $this->cache->imap_mode(true); $result = $this->imap->clear_folder($this->name); - $this->cache->bypass(false); + $this->cache->imap_mode(false); return $result; } @@ -844,9 +843,9 @@ } if ($msguid = $this->cache->uid2msguid($uid, true)) { - $this->cache->bypass(true); + $this->cache->imap_mode(true); $result = $this->imap->set_flag($msguid, 'UNDELETED', $this->name); - $this->cache->bypass(false); + $this->cache->imap_mode(false); if ($result) { return $msguid; @@ -873,9 +872,9 @@ $target_folder = kolab_storage::get_folder($target_folder); if ($msguid = $this->cache->uid2msguid($uid)) { - $this->cache->bypass(true); + $this->cache->imap_mode(true); $result = $this->imap->move_message($msguid, $target_folder->name, $this->name); - $this->cache->bypass(false); + $this->cache->imap_mode(false); if ($result) { $new_uid = ($copyuid = $this->imap->conn->data['COPYUID']) ? $copyuid[1] : null;