Fix moving objects between DAV folders

The code does "move object then read it" and "read it" was failing
because the folder cache wasn't up-to-date. We force re-synchronization
by reseting the state properly after move().
This commit is contained in:
Aleksander Machniak 2023-05-01 12:11:33 +02:00
parent 000cfa43b5
commit 68eaf60aca
6 changed files with 54 additions and 36 deletions

View file

@ -1021,17 +1021,12 @@ class kolab_driver extends calendar_driver
$old = $fromcalendar->get_event($event['id']); $old = $fromcalendar->get_event($event['id']);
if ($event['_savemode'] != 'new') { if (empty($event['_savemode']) || $event['_savemode'] != 'new') {
if (!$fromcalendar->storage->move($old['uid'], $storage->storage)) { if (!$fromcalendar->storage->move($old['uid'], $storage->storage)) {
return false; return false;
} }
$fromcalendar = $storage;
} }
} }
else {
$fromcalendar = $storage;
}
$success = false; $success = false;
$savemode = 'all'; $savemode = 'all';

View file

@ -359,10 +359,10 @@ class kolab_dav_client
. '</d:propfind>'; . '</d:propfind>';
// Note: Cyrus CardDAV service requires Depth:1 (CalDAV works without it) // Note: Cyrus CardDAV service requires Depth:1 (CalDAV works without it)
$response = $this->request($location, 'PROPFIND', $body, ['Depth' => 1, 'Prefer' => 'return-minimal']); $response = $this->request($location, 'PROPFIND', $body, ['Depth' => 0, 'Prefer' => 'return-minimal']);
if (!empty($response) if (!empty($response)
&& ($element = $response->getElementsByTagName('response')) && ($element = $response->getElementsByTagName('response')->item(0))
&& ($folder = $this->getFolderPropertiesFromResponse($element)) && ($folder = $this->getFolderPropertiesFromResponse($element))
) { ) {
return $folder; return $folder;

View file

@ -920,6 +920,14 @@ class kolab_storage_cache
return $count; return $count;
} }
/**
* Reset the sync state, i.e. force sync when synchronize() is called again
*/
public function reset()
{
$this->synched = null;
}
/** /**
* Define ORDER BY clause for cache queries * Define ORDER BY clause for cache queries
*/ */

View file

@ -38,14 +38,6 @@ class kolab_storage_dav
public function __construct($url) public function __construct($url)
{ {
$this->url = $url; $this->url = $url;
$this->setup();
}
/**
* Setup the environment
*/
public function setup()
{
$this->dav = new kolab_dav_client($this->url); $this->dav = new kolab_dav_client($this->url);
} }
@ -58,7 +50,6 @@ class kolab_storage_dav
*/ */
public function get_folders($type) public function get_folders($type)
{ {
// TODO: This should be cached
$folders = $this->dav->listFolders($this->get_dav_type($type)); $folders = $this->dav->listFolders($this->get_dav_type($type));
if (is_array($folders)) { if (is_array($folders)) {

View file

@ -24,10 +24,16 @@
#[AllowDynamicProperties] #[AllowDynamicProperties]
class kolab_storage_dav_folder extends kolab_storage_folder class kolab_storage_dav_folder extends kolab_storage_folder
{ {
/** @var kolab_dav_client DAV Client */
public $dav; public $dav;
/** @var string Folder URL */
public $href; public $href;
/** @var array Folder DAV attributes */
public $attributes; public $attributes;
/** /**
* Object constructor * Object constructor
*/ */
@ -76,6 +82,13 @@ class kolab_storage_dav_folder extends kolab_storage_folder
*/ */
public function get_ctag() public function get_ctag()
{ {
// Refresh requested, get the current CTag from the DAV server
if ($this->attributes['ctag'] === false) {
if ($fresh = $this->dav->folderInfo($this->href)) {
$this->attributes['ctag'] = $fresh['ctag'];
}
}
return $this->attributes['ctag']; return $this->attributes['ctag'];
} }
@ -330,6 +343,8 @@ class kolab_storage_dav_folder extends kolab_storage_folder
if ($success) { if ($success) {
$this->cache->set($uid, false); $this->cache->set($uid, false);
$target_folder->reset();
$this->reset();
} }
return $success; return $success;
@ -462,6 +477,15 @@ class kolab_storage_dav_folder extends kolab_storage_folder
return $uids; return $uids;
} }
/**
* Reset the folder status
*/
public function reset()
{
$this->cache->reset();
$this->attributes['ctag'] = false;
}
/** /**
* Convert DAV object into PHP array * Convert DAV object into PHP array
* *

View file

@ -265,6 +265,25 @@ class kolab_storage_folder extends kolab_storage_folder_api
return $this->cache->count($this->_prepare_query($query)); return $this->cache->count($this->_prepare_query($query));
} }
/**
* Getter for a single Kolab object identified by its UID
*
* @param string $uid Object UID
*
* @return array The Kolab object represented as hash array
*/
public function get_object($uid)
{
if (!$this->valid || !$uid) {
return false;
}
// synchronize caches
$this->cache->synchronize();
return $this->cache->get_by_uid($uid);
}
/** /**
* List Kolab objects matching the given query * List Kolab objects matching the given query
* *
@ -365,25 +384,6 @@ class kolab_storage_folder extends kolab_storage_folder_api
return $query; return $query;
} }
/**
* Getter for a single Kolab object identified by its UID
*
* @param string $uid Object UID
*
* @return array The Kolab object represented as hash array
*/
public function get_object($uid)
{
if (!$this->valid || !$uid) {
return false;
}
// synchronize caches
$this->cache->synchronize();
return $this->cache->get_by_uid($uid);
}
/** /**
* Fetch a Kolab object attachment which is stored in a separate part * Fetch a Kolab object attachment which is stored in a separate part
* of the mail MIME message that represents the Kolab record. * of the mail MIME message that represents the Kolab record.