Fix merging attachments list on event/task update from iTip (#5342)
Reviewers: #roundcube_kolab_plugins_developers, vanmeeuwen Reviewed By: #roundcube_kolab_plugins_developers, vanmeeuwen Subscribers: vanmeeuwen Projects: #roundcube_kolab_plugins Differential Revision: https://git.kolab.org/D96
This commit is contained in:
parent
ed93508c8a
commit
fc93828311
5 changed files with 83 additions and 80 deletions
|
@ -2996,6 +2996,13 @@ class calendar extends rcube_plugin
|
|||
// set status=CANCELLED on CANCEL messages
|
||||
if ($event['_method'] == 'CANCEL')
|
||||
$event['status'] = 'CANCELLED';
|
||||
|
||||
// update attachments list, allow attachments update only on REQUEST (#5342)
|
||||
if ($event['_method'] == 'REQUEST')
|
||||
$event['deleted_attachments'] = true;
|
||||
else
|
||||
unset($event['attachments']);
|
||||
|
||||
// show me as free when declined (#1670)
|
||||
if ($status == 'declined' || $event['status'] == 'CANCELLED' || $event_attendee['role'] == 'NON-PARTICIPANT')
|
||||
$event['free_busy'] = 'free';
|
||||
|
|
|
@ -1972,46 +1972,7 @@ class kolab_driver extends calendar_driver
|
|||
*/
|
||||
public static function from_rcube_event($event, $old = array())
|
||||
{
|
||||
// in kolab_storage attachments are indexed by content-id
|
||||
if (is_array($event['attachments']) || !empty($event['deleted_attachments'])) {
|
||||
$event['_attachments'] = array();
|
||||
|
||||
foreach ($event['attachments'] as $attachment) {
|
||||
$key = null;
|
||||
// Roundcube ID has nothing to do with the storage ID, remove it
|
||||
if ($attachment['content'] || $attachment['path']) {
|
||||
unset($attachment['id']);
|
||||
}
|
||||
else {
|
||||
foreach ((array)$old['_attachments'] as $cid => $oldatt) {
|
||||
if ($attachment['id'] == $oldatt['id'])
|
||||
$key = $cid;
|
||||
}
|
||||
}
|
||||
|
||||
// flagged for deletion => set to false
|
||||
if ($attachment['_deleted'] || in_array($attachment['id'], (array)$event['deleted_attachments'])) {
|
||||
$event['_attachments'][$key] = false;
|
||||
}
|
||||
// replace existing entry
|
||||
else if ($key) {
|
||||
$event['_attachments'][$key] = $attachment;
|
||||
}
|
||||
// append as new attachment
|
||||
else {
|
||||
$event['_attachments'][] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
$event['_attachments'] = array_merge((array)$old['_attachments'], $event['_attachments']);
|
||||
|
||||
// attachments flagged for deletion => set to false
|
||||
foreach ($event['_attachments'] as $key => $attachment) {
|
||||
if ($attachment['_deleted'] || in_array($attachment['id'], (array)$event['deleted_attachments'])) {
|
||||
$event['_attachments'][$key] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
kolab_format::merge_attachments($event, $old);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
|
|
@ -704,4 +704,68 @@ abstract class kolab_format
|
|||
$this->obj->setAttachments($vattach);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unified way of updating/deleting attachments of edited object
|
||||
*
|
||||
* @param array $object Kolab object data
|
||||
* @param array $old Old version of Kolab object
|
||||
*/
|
||||
public static function merge_attachments(&$object, $old)
|
||||
{
|
||||
$object['_attachments'] = (array) $old['_attachments'];
|
||||
|
||||
// delete existing attachment(s)
|
||||
if (!empty($object['deleted_attachments'])) {
|
||||
foreach ($object['_attachments'] as $idx => $att) {
|
||||
if ($object['deleted_attachments'] === true || in_array($att['id'], $object['deleted_attachments'])) {
|
||||
$object['_attachments'][$idx] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// in kolab_storage attachments are indexed by content-id
|
||||
foreach ((array) $object['attachments'] as $attachment) {
|
||||
$key = null;
|
||||
|
||||
// Roundcube ID has nothing to do with the storage ID, remove it
|
||||
// for uploaded/new attachments
|
||||
// FIXME: Roundcube uses 'data', kolab_format uses 'content'
|
||||
if ($attachment['content'] || $attachment['path'] || $attachment['data']) {
|
||||
unset($attachment['id']);
|
||||
}
|
||||
|
||||
if ($attachment['id']) {
|
||||
foreach ((array) $object['_attachments'] as $cid => $att) {
|
||||
if ($att && $attachment['id'] == $att['id']) {
|
||||
$key = $cid;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// find attachment by name, so we can update it if exists
|
||||
// and make sure there are no duplicates
|
||||
foreach ((array) $object['_attachments'] as $cid => $att) {
|
||||
if ($att && $attachment['name'] == $att['name']) {
|
||||
$key = $cid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($key && $attachment['_deleted']) {
|
||||
$object['_attachments'][$key] = false;
|
||||
}
|
||||
// replace existing entry
|
||||
else if ($key) {
|
||||
$object['_attachments'][$key] = $attachment;
|
||||
}
|
||||
// append as new attachment
|
||||
else {
|
||||
$object['_attachments'][] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
unset($object['attachments']);
|
||||
unset($object['deleted_attachments']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1308,46 +1308,8 @@ class tasklist_kolab_driver extends tasklist_driver
|
|||
$object['recurrence'] = $old['recurrence'];
|
||||
}
|
||||
|
||||
// delete existing attachment(s)
|
||||
if (!empty($task['deleted_attachments'])) {
|
||||
foreach ($task['deleted_attachments'] as $attachment) {
|
||||
if (is_array($object['_attachments'])) {
|
||||
foreach ($object['_attachments'] as $idx => $att) {
|
||||
if ($att['id'] == $attachment)
|
||||
$object['_attachments'][$idx] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($task['deleted_attachments']);
|
||||
}
|
||||
|
||||
// in kolab_storage attachments are indexed by content-id
|
||||
if (is_array($task['attachments'])) {
|
||||
foreach ($task['attachments'] as $idx => $attachment) {
|
||||
$key = null;
|
||||
// Roundcube ID has nothing to do with the storage ID, remove it
|
||||
if ($attachment['content'] || $attachment['path']) {
|
||||
unset($attachment['id']);
|
||||
}
|
||||
else {
|
||||
foreach ((array)$old['_attachments'] as $cid => $oldatt) {
|
||||
if ($oldatt && $attachment['id'] == $oldatt['id'])
|
||||
$key = $cid;
|
||||
}
|
||||
}
|
||||
|
||||
// replace existing entry
|
||||
if ($key) {
|
||||
$object['_attachments'][$key] = $attachment;
|
||||
}
|
||||
// append as new attachment
|
||||
else {
|
||||
$object['_attachments'][] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
unset($object['attachments']);
|
||||
}
|
||||
unset($task['attachments']);
|
||||
kolab_format::merge_attachments($object, $old);
|
||||
|
||||
// allow sequence increments if I'm the organizer
|
||||
if ($this->plugin->is_organizer($object) && empty($object['_method'])) {
|
||||
|
|
|
@ -2088,6 +2088,15 @@ class tasklist extends rcube_plugin
|
|||
if ($task['_method'] == 'CANCEL') {
|
||||
$task['status'] = 'CANCELLED';
|
||||
}
|
||||
|
||||
// update attachments list, allow attachments update only on REQUEST (#5342)
|
||||
if ($task['_method'] == 'REQUEST') {
|
||||
$task['deleted_attachments'] = true;
|
||||
}
|
||||
else {
|
||||
unset($task['attachments']);
|
||||
}
|
||||
|
||||
// show me as free when declined (#1670)
|
||||
if ($status == 'declined' || $task['status'] == 'CANCELLED') {
|
||||
$task['free_busy'] = 'free';
|
||||
|
|
Loading…
Add table
Reference in a new issue