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']);
if ($event['_savemode'] != 'new') {
if (empty($event['_savemode']) || $event['_savemode'] != 'new') {
if (!$fromcalendar->storage->move($old['uid'], $storage->storage)) {
return false;
}
$fromcalendar = $storage;
}
}
else {
$fromcalendar = $storage;
}
$success = false;
$savemode = 'all';

View file

@ -359,10 +359,10 @@ class kolab_dav_client
. '</d:propfind>';
// 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)
&& ($element = $response->getElementsByTagName('response'))
&& ($element = $response->getElementsByTagName('response')->item(0))
&& ($folder = $this->getFolderPropertiesFromResponse($element))
) {
return $folder;

View file

@ -920,6 +920,14 @@ class kolab_storage_cache
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
*/

View file

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

View file

@ -24,10 +24,16 @@
#[AllowDynamicProperties]
class kolab_storage_dav_folder extends kolab_storage_folder
{
/** @var kolab_dav_client DAV Client */
public $dav;
/** @var string Folder URL */
public $href;
/** @var array Folder DAV attributes */
public $attributes;
/**
* Object constructor
*/
@ -76,6 +82,13 @@ class kolab_storage_dav_folder extends kolab_storage_folder
*/
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'];
}
@ -330,6 +343,8 @@ class kolab_storage_dav_folder extends kolab_storage_folder
if ($success) {
$this->cache->set($uid, false);
$target_folder->reset();
$this->reset();
}
return $success;
@ -462,6 +477,15 @@ class kolab_storage_dav_folder extends kolab_storage_folder
return $uids;
}
/**
* Reset the folder status
*/
public function reset()
{
$this->cache->reset();
$this->attributes['ctag'] = false;
}
/**
* 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));
}
/**
* 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
*
@ -365,25 +384,6 @@ class kolab_storage_folder extends kolab_storage_folder_api
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
* of the mail MIME message that represents the Kolab record.