Correctly handle object moving in kolab cache
This commit is contained in:
parent
3fc78aa409
commit
c9963d279c
2 changed files with 92 additions and 27 deletions
|
@ -66,22 +66,8 @@ class kolab_storage_cache
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// strip namespace prefix from folder name
|
|
||||||
$ns = $this->folder->get_namespace();
|
|
||||||
$nsdata = $this->imap->get_namespace($ns);
|
|
||||||
if (is_array($nsdata[0]) && strpos($this->folder->name, $nsdata[0][0]) === 0) {
|
|
||||||
$subpath = substr($this->folder->name, strlen($nsdata[0][0]));
|
|
||||||
if ($ns == 'other') {
|
|
||||||
list($user, $suffix) = explode($nsdata[0][1], $subpath);
|
|
||||||
$subpath = $suffix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$subpath = $this->folder->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compose fully qualified ressource uri for this instance
|
// compose fully qualified ressource uri for this instance
|
||||||
$this->resource_uri = 'imap://' . urlencode($this->folder->get_owner()) . '@' . $this->imap->options['host'] . '/' . $subpath;
|
$this->resource_uri = $this->folder->get_resource_uri();
|
||||||
$this->ready = $this->enabled;
|
$this->ready = $this->enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,14 +126,22 @@ class kolab_storage_cache
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a single entry from cache or
|
* Read a single entry from cache or
|
||||||
|
*
|
||||||
|
* @param string Related IMAP message UID
|
||||||
|
* @param string Object type to read
|
||||||
|
* @param string IMAP folder name the entry relates to
|
||||||
|
* @param array Hash array with object properties or null if not found
|
||||||
*/
|
*/
|
||||||
public function get($msguid, $type = null, $folder = null)
|
public function get($msguid, $type = null, $foldername = null)
|
||||||
{
|
{
|
||||||
|
// delegate to another cache instance
|
||||||
|
if ($foldername && $foldername != $this->folder->name) {
|
||||||
|
return kolab_storage::get_folder($foldername)->cache->get($msguid, $object);
|
||||||
|
}
|
||||||
|
|
||||||
// load object if not in memory
|
// load object if not in memory
|
||||||
if (!isset($this->objects[$msguid])) {
|
if (!isset($this->objects[$msguid])) {
|
||||||
if ($this->ready) {
|
if ($this->ready) {
|
||||||
// TODO: handle $folder != $this->folder->name situations
|
|
||||||
|
|
||||||
$sql_result = $this->db->query(
|
$sql_result = $this->db->query(
|
||||||
"SELECT * FROM kolab_cache ".
|
"SELECT * FROM kolab_cache ".
|
||||||
"WHERE resource=? AND msguid=?",
|
"WHERE resource=? AND msguid=?",
|
||||||
|
@ -162,7 +156,7 @@ class kolab_storage_cache
|
||||||
|
|
||||||
// fetch from IMAP if not present in cache
|
// fetch from IMAP if not present in cache
|
||||||
if (empty($this->objects[$msguid])) {
|
if (empty($this->objects[$msguid])) {
|
||||||
$result = $this->_fetch(array($msguid), $type, $folder);
|
$result = $this->_fetch(array($msguid), $type, $foldername);
|
||||||
$this->objects[$msguid] = $result[0];
|
$this->objects[$msguid] = $result[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,14 +166,22 @@ class kolab_storage_cache
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Insert/Update a cache entry
|
||||||
*
|
*
|
||||||
|
* @param string Related IMAP message UID
|
||||||
|
* @param mixed Hash array with object properties to save or false to delete the cache entry
|
||||||
|
* @param string IMAP folder name the entry relates to
|
||||||
*/
|
*/
|
||||||
public function set($msguid, $object, $folder = null)
|
public function set($msguid, $object, $foldername = null)
|
||||||
{
|
{
|
||||||
|
// delegate to another cache instance
|
||||||
|
if ($foldername && $foldername != $this->folder->name) {
|
||||||
|
kolab_storage::get_folder($foldername)->cache->set($msguid, $object);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// write to cache
|
// write to cache
|
||||||
if ($this->ready) {
|
if ($this->ready) {
|
||||||
// TODO: handle $folder != $this->folder->name situations
|
|
||||||
|
|
||||||
// remove old entry
|
// remove old entry
|
||||||
$this->db->query("DELETE FROM kolab_cache WHERE resource=? AND msguid=?",
|
$this->db->query("DELETE FROM kolab_cache WHERE resource=? AND msguid=?",
|
||||||
$this->resource_uri, $msguid);
|
$this->resource_uri, $msguid);
|
||||||
|
@ -219,6 +221,36 @@ class kolab_storage_cache
|
||||||
$this->uid2msg[$object['uid']] = $msguid;
|
$this->uid2msg[$object['uid']] = $msguid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move an existing cache entry to a new resource
|
||||||
|
*
|
||||||
|
* @param string Entry's IMAP message UID
|
||||||
|
* @param string Entry's Object UID
|
||||||
|
* @param string Target IMAP folder to move it to
|
||||||
|
*/
|
||||||
|
public function move($msguid, $objuid, $target_folder)
|
||||||
|
{
|
||||||
|
$target = kolab_storage::get_folder($target_folder);
|
||||||
|
|
||||||
|
// resolve new message UID in target folder
|
||||||
|
if ($new_msguid = $target->cache->uid2msguid($objuid)) {
|
||||||
|
$this->db->query(
|
||||||
|
"UPDATE kolab_cache SET resource=?, msguid=? ".
|
||||||
|
"WHERE resource=? AND msguid=?",
|
||||||
|
$target->get_resource_uri(),
|
||||||
|
$new_msguid,
|
||||||
|
$this->resource_uri,
|
||||||
|
$msguid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// just clear cache entry
|
||||||
|
$this->set($msguid, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($this->uid2msg[$uid]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all objects from local cache
|
* Remove all objects from local cache
|
||||||
|
@ -365,7 +397,7 @@ class kolab_storage_cache
|
||||||
|
|
||||||
// set type specific values
|
// set type specific values
|
||||||
if ($this->folder->type == 'event') {
|
if ($this->folder->type == 'event') {
|
||||||
// database runs in server's timetone so using date() is safe
|
// database runs in server's timezone so using date() is what we want
|
||||||
$sql_data['dtstart'] = date('Y-m-d H:i:s', is_object($object['start']) ? $object['start']->format('U') : $object['start']);
|
$sql_data['dtstart'] = date('Y-m-d H:i:s', is_object($object['start']) ? $object['start']->format('U') : $object['start']);
|
||||||
$sql_data['dtend'] = date('Y-m-d H:i:s', is_object($object['end']) ? $object['end']->format('U') : $object['end']);
|
$sql_data['dtend'] = date('Y-m-d H:i:s', is_object($object['end']) ? $object['end']->format('U') : $object['end']);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,23 +27,27 @@ class kolab_storage_folder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The folder name.
|
* The folder name.
|
||||||
*
|
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $name;
|
public $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of this folder.
|
* The type of this folder.
|
||||||
*
|
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $type;
|
public $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attached cache object
|
||||||
|
* @var kolab_storage_cache
|
||||||
|
*/
|
||||||
|
public $cache;
|
||||||
|
|
||||||
private $type_annotation;
|
private $type_annotation;
|
||||||
private $imap;
|
private $imap;
|
||||||
private $info;
|
private $info;
|
||||||
private $owner;
|
private $owner;
|
||||||
private $cache;
|
private $resource_uri;
|
||||||
private $uid2msg = array();
|
private $uid2msg = array();
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +76,7 @@ class kolab_storage_folder
|
||||||
$metadata = $this->imap->get_metadata($this->name, array(kolab_storage::CTYPE_KEY));
|
$metadata = $this->imap->get_metadata($this->name, array(kolab_storage::CTYPE_KEY));
|
||||||
$this->type_annotation = $metadata[$this->name][kolab_storage::CTYPE_KEY];
|
$this->type_annotation = $metadata[$this->name][kolab_storage::CTYPE_KEY];
|
||||||
$this->type = reset(explode('.', $this->type_annotation));
|
$this->type = reset(explode('.', $this->type_annotation));
|
||||||
|
$this->resource_uri = null;
|
||||||
|
|
||||||
$this->cache->set_folder($this);
|
$this->cache->set_folder($this);
|
||||||
}
|
}
|
||||||
|
@ -180,6 +185,34 @@ class kolab_storage_folder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compose a unique resource URI for this IMAP folder
|
||||||
|
*/
|
||||||
|
public function get_resource_uri()
|
||||||
|
{
|
||||||
|
if (!empty($this->resource_uri))
|
||||||
|
return $this->resource_uri;
|
||||||
|
|
||||||
|
// strip namespace prefix from folder name
|
||||||
|
$ns = $this->get_namespace();
|
||||||
|
$nsdata = $this->imap->get_namespace($ns);
|
||||||
|
if (is_array($nsdata[0]) && strpos($this->name, $nsdata[0][0]) === 0) {
|
||||||
|
$subpath = substr($this->name, strlen($nsdata[0][0]));
|
||||||
|
if ($ns == 'other') {
|
||||||
|
list($user, $suffix) = explode($nsdata[0][1], $subpath);
|
||||||
|
$subpath = $suffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$subpath = $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compose fully qualified ressource uri for this instance
|
||||||
|
$this->resource_uri = 'imap://' . urlencode($this->get_owner()) . '@' . $this->imap->options['host'] . '/' . $subpath;
|
||||||
|
return $this->resource_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check subscription status of this folder
|
* Check subscription status of this folder
|
||||||
*
|
*
|
||||||
|
@ -532,7 +565,7 @@ class kolab_storage_folder
|
||||||
{
|
{
|
||||||
if ($msguid = $this->cache->uid2msguid($uid)) {
|
if ($msguid = $this->cache->uid2msguid($uid)) {
|
||||||
if ($success = $this->imap->move_message($msguid, $target_folder, $this->name)) {
|
if ($success = $this->imap->move_message($msguid, $target_folder, $this->name)) {
|
||||||
// TODO: update cache
|
$this->cache->move($msguid, $uid, $target_folder);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Add table
Reference in a new issue