From 5048c739d57fa6d7e726ca272849d4c768f46490 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Tue, 28 Mar 2017 10:59:58 +0200 Subject: [PATCH] Update an event on itip-attend page for logged-in users (Bifrost#T27847) A participant can accept an invitation via link. This works fine for initial invitation. However, if there is any update for the event in another invitation request, the event in participant's calendar was not updated. Example scenario: - an organizer invites a participant for specified date/time - a participant declines the invitation (he's busy on that time), the event in participant's calendar will be created - an organizer updates the event with another date/time - a participant now accepts the modified event, the event should be updated with the new date/time. --- plugins/calendar/calendar.php | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 4ff7c345..6018704c 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -2695,15 +2695,47 @@ class calendar extends rcube_plugin $this->rc->output->command('display_message', $this->gettext('errorsaving'), 'error', -1); // if user is logged in... + // FIXME: we should really consider removing this functionality + // it's confusing that it creates/updates an event only for logged-in user + // what if the logged-in user is not the same as the attendee? if ($this->rc->user->ID) { $this->load_driver(); + $invitation = $itip->get_invitation($token); + $existing = $this->driver->get_event($this->event); // save the event to his/her default calendar if not yet present - if (!$this->driver->get_event($this->event) && ($calendar = $this->get_default_calendar($invitation['event']['sensitivity']))) { + if (!$existing && ($calendar = $this->get_default_calendar($invitation['event']['sensitivity']))) { $invitation['event']['calendar'] = $calendar['id']; if ($this->driver->new_event($invitation['event'])) $this->rc->output->command('display_message', $this->gettext(array('name' => 'importedsuccessfully', 'vars' => array('calendar' => $calendar['name']))), 'confirmation'); + else + $this->rc->output->command('display_message', $this->gettext('errorimportingevent'), 'error'); + } + else if ($existing + && ($this->event['sequence'] >= $existing['sequence'] || $this->event['changed'] >= $existing['changed']) + && ($calendar = $this->driver->get_calendar($existing['calendar'])) + ) { + $this->event = $invitation['event']; + $this->event['id'] = $existing['id']; + + unset($this->event['comment']); + + // merge attendees status + // e.g. preserve my participant status for regular updates + $this->lib->merge_attendees($this->event, $existing, $status); + + // update attachments list + $event['deleted_attachments'] = true; + + // show me as free when declined (#1670) + if ($status == 'declined') + $this->event['free_busy'] = 'free'; + + if ($this->driver->edit_event($this->event)) + $this->rc->output->command('display_message', $this->gettext(array('name' => 'updatedsuccessfully', 'vars' => array('calendar' => $calendar->get_name()))), 'confirmation'); + else + $this->rc->output->command('display_message', $this->gettext('errorimportingevent'), 'error'); } } }