Allow an event updates on iTip request without SEQUENCE bump (Bifrost#T27883)
We're detecting if something changed in description, title, url, location or attendees. These are properties that could be changed by the organizer without SEQUENCE bump. If that is detected we display "Update in my calendar" button. TODO: display a diff of changes, so user can take a decission if he want's to overwrite his copy of the event.
This commit is contained in:
parent
a1cd95152c
commit
16a71fccdc
2 changed files with 72 additions and 5 deletions
|
@ -374,7 +374,7 @@ class libcalendaring_itip
|
|||
{
|
||||
$action = $event['rsvp'] ? 'rsvp' : '';
|
||||
$status = $event['fallback'];
|
||||
$latest = $resheduled = false;
|
||||
$latest = $rescheduled = false;
|
||||
$html = '';
|
||||
|
||||
if (is_numeric($event['changed']))
|
||||
|
@ -404,7 +404,7 @@ class libcalendaring_itip
|
|||
if (!$latest) {
|
||||
// FIXME: This is probably to simplistic, or maybe we should just check
|
||||
// attendee's RSVP flag in the new event?
|
||||
$resheduled = $existing['start'] != $event['start'] || $existing['end'] > $event['end'];
|
||||
$rescheduled = $existing['start'] != $event['start'] || $existing['end'] > $event['end'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -428,10 +428,16 @@ class libcalendaring_itip
|
|||
else if (!$existing && !$rsvp) {
|
||||
$action = 'import';
|
||||
}
|
||||
else if ($resheduled) {
|
||||
else if ($rescheduled) {
|
||||
$action = 'rsvp';
|
||||
}
|
||||
else if ($status_lc != 'needs-action') {
|
||||
// check if there are any changes
|
||||
if ($latest) {
|
||||
$diff = $this->get_itip_diff($event, $existing);
|
||||
$latest = empty($diff);
|
||||
}
|
||||
|
||||
$action = !$latest ? 'update' : '';
|
||||
}
|
||||
|
||||
|
@ -485,11 +491,69 @@ class libcalendaring_itip
|
|||
'latest' => $latest,
|
||||
'status' => $status,
|
||||
'action' => $action,
|
||||
'resheduled' => $resheduled,
|
||||
'rescheduled' => $rescheduled,
|
||||
'html' => $html,
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_itip_diff($event, $existing)
|
||||
{
|
||||
if (empty($event) || empty($existing) || empty($event['message_uid'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$itip = $this->lib->mail_get_itip_object($event['mbox'], $event['message_uid'], $event['mime_id'],
|
||||
$event['task'] == 'calendar' ? 'event' : 'task');
|
||||
|
||||
if ($itip) {
|
||||
// List of properties that could change without SEQUENCE bump
|
||||
$attrs = array('description', 'title', 'location', 'url');
|
||||
$diff = array();
|
||||
|
||||
foreach ($attrs as $attr) {
|
||||
if (isset($itip[$attr]) && $itip[$attr] != $existing[$attr]) {
|
||||
$diff[$attr] = array(
|
||||
'new' => $itip[$attr],
|
||||
'old' => $existing[$attr]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$status = array();
|
||||
$itip_attendees = array();
|
||||
$existing_attendees = array();
|
||||
$emails = $this->lib->get_user_emails();
|
||||
|
||||
// Compare list of attendees (ignoring current user status)
|
||||
foreach ((array) $existing['attendees'] as $idx => $attendee) {
|
||||
if ($attendee['email'] && in_array(strtolower($attendee['email']), $emails)) {
|
||||
$status[strtolower($attendee['email'])] = $attendee['status'];
|
||||
}
|
||||
if ($attendee['role'] == 'ORGANIZER') {
|
||||
$attendee['status'] = 'ACCEPTED'; // sometimes is not set for exceptions
|
||||
$existing['attendees'][$idx] = $attendee;
|
||||
}
|
||||
$existing_attendees[] = $attendee['email'].$attendee['name'];
|
||||
}
|
||||
foreach ((array) $itip['attendees'] as $idx => $attendee) {
|
||||
if ($attendee['email'] && ($_status = $status[strtolower($attendee['email'])])) {
|
||||
$attendee['status'] = $_status;
|
||||
$itip['attendees'][$idx] = $attendee;
|
||||
}
|
||||
$itip_attendees[] = $attendee['email'].$attendee['name'];
|
||||
}
|
||||
|
||||
if ($itip_attendees != $existing_attendees) {
|
||||
$diff['attendees'] = array(
|
||||
'new' => $itip['attendees'],
|
||||
'old' => $existing['attendees']
|
||||
);
|
||||
}
|
||||
|
||||
return $diff;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build inline UI elements for iTip messages
|
||||
*/
|
||||
|
@ -508,6 +572,7 @@ class libcalendaring_itip
|
|||
'sequence' => intval($event['sequence']),
|
||||
'method' => $method,
|
||||
'task' => $task,
|
||||
'mime_id' => $mime_id,
|
||||
);
|
||||
|
||||
// create buttons to be activated from async request checking existence of this event in local calendars
|
||||
|
|
|
@ -1325,6 +1325,8 @@ rcube_libcalendaring.decline_attendee_reply = function(mime_id, task)
|
|||
*/
|
||||
rcube_libcalendaring.fetch_itip_object_status = function(p)
|
||||
{
|
||||
p.mbox = rcmail.env.mailbox;
|
||||
p.message_uid = rcmail.env.uid;
|
||||
rcmail.http_post(p.task + '/itip-status', { data: p });
|
||||
};
|
||||
|
||||
|
@ -1356,7 +1358,7 @@ rcube_libcalendaring.update_itip_object_status = function(p)
|
|||
$('#'+p.action+'-'+p.id).show().find('input.button').last().after(p.select);
|
||||
|
||||
// highlight date if date change detected
|
||||
if (p.resheduled)
|
||||
if (p.rescheduled)
|
||||
$('.calendar-eventdetails td.date').addClass('modified');
|
||||
|
||||
// show itip box appendix after replacing the given placeholders
|
||||
|
|
Loading…
Add table
Reference in a new issue