Improve iTip REQUEST workflow:

- only increase sequence on significant changes that affect scheduling (acc. RFC 5545)
- show RSVP buttons only for higher sequence updates (#1678)
- provide a button to simply update the local copy otherwise
This commit is contained in:
Thomas Bruederli 2014-07-08 17:14:14 +02:00
parent 0c5465c2ad
commit afb64c3948
5 changed files with 47 additions and 6 deletions

View file

@ -285,7 +285,7 @@ class libcalendaring_itip
$action = 'import';
}
else if (in_array(strtolower($status), $this->rsvp_status)) {
$html = html::div('rsvp-status ' . strtolower($status), $this->gettext('youhave'.strtolower($status)));
$html = html::div('rsvp-status ' . strtolower($status), $this->gettext(($latest ? 'youhave' : 'youhavepreviously') . strtolower($status)));
if ($existing && ($existing['sequence'] > $event['sequence'] || (!$event['sequence'] && $existing['changed'] && $existing['changed'] > $event['changed']))) {
$action = ''; // nothing to do here, outdated invitation
@ -293,6 +293,9 @@ class libcalendaring_itip
else if (!$existing && !$rsvp) {
$action = 'import';
}
else if ($latest) {
$action = 'update';
}
}
}
// determine action for REPLY
@ -419,7 +422,15 @@ class libcalendaring_itip
));
}
// 2. Simply import the event without replying
// 2. update the local copy with minor changes
$update_button = html::tag('input', array(
'type' => 'button',
'class' => 'button',
'onclick' => "rcube_libcalendaring.add_from_itip_mail('" . JQ($mime_id) . "', '$task')",
'value' => $this->gettext('updatemycopy'),
));
// 3. Simply import the event without replying
$import_button = html::tag('input', array(
'type' => 'button',
'class' => 'button',
@ -441,6 +452,7 @@ class libcalendaring_itip
$rsvp_buttons .= html::div('itip-reply-controls', $this->itip_rsvp_options_ui($dom_id));
$buttons[] = html::div(array('id' => 'rsvp-'.$dom_id, 'class' => 'rsvp-buttons', 'style' => 'display:none'), $rsvp_buttons);
$buttons[] = html::div(array('id' => 'update-'.$dom_id, 'style' => 'display:none'), $update_button);
}
// for CANCEL messages, we can:
else if ($method == 'CANCEL') {

View file

@ -99,6 +99,13 @@ $labels['youhavetentative'] = 'You have tentatively accepted this invitation';
$labels['youhavedeclined'] = 'You have declined this invitation';
$labels['youhavedelegated'] = 'You have delegated this invitation';
$labels['youhaveneeds-action'] = 'You have copied this invitation into your calendar';
$labels['youhavepreviouslyaccepted'] = 'You have previously accepted this invitation';
$labels['youhavepreviouslytentative'] = 'You have previously accepted this invitation tentatively';
$labels['youhavepreviouslydeclined'] = 'You have previously declined this invitation';
$labels['youhavepreviouslydelegated'] = 'You have previously delegated this invitation';
$labels['youhavepreviouslyneeds-action'] = 'You have copied this invitation into your calendar';
$labels['attendeeaccepted'] = 'Participant has accepted';
$labels['attendeetentative'] = 'Participant has tentatively accepted';
$labels['attendeedeclined'] = 'Participant has declined';

View file

@ -26,6 +26,8 @@ class kolab_format_event extends kolab_format_xcal
{
public $CTYPEv2 = 'application/x-vnd.kolab.event';
public static $scheduling_properties = array('start', 'end', 'allday', 'location');
protected $objclass = 'Event';
protected $read_func = 'readEvent';
protected $write_func = 'writeEvent';

View file

@ -26,6 +26,8 @@ class kolab_format_task extends kolab_format_xcal
{
public $CTYPEv2 = 'application/x-vnd.kolab.task';
public static $scheduling_properties = array('start', 'due', 'summary', 'status');
protected $objclass = 'Todo';
protected $read_func = 'readTodo';
protected $write_func = 'writeTodo';

View file

@ -29,6 +29,7 @@ abstract class kolab_format_xcal extends kolab_format
public $CTYPE = 'application/calendar+xml';
public static $fulltext_cols = array('title', 'description', 'location', 'attendees:name', 'attendees:email', 'categories');
public static $scheduling_properties = array('start', 'end', 'location');
protected $sensitivity_map = array(
'public' => kolabformat::ClassPublic,
@ -302,10 +303,27 @@ abstract class kolab_format_xcal extends kolab_format
// set common object properties
parent::set($object);
// increment sequence on updates
if (empty($object['sequence']))
$object['sequence'] = !$is_new ? $this->obj->sequence()+1 : 0;
$this->obj->setSequence($object['sequence']);
// set sequence value
if (!isset($object['sequence'])) {
if ($is_new) {
$object['sequence'] = 0;
}
else {
$object['sequence'] = $this->obj->sequence();
$old = $this->data['uid'] ? $this->data : $this->to_array();
// increment sequence when updating properties relevant for scheduling.
// RFC 5545: "It is incremented [...] each time the Organizer makes a significant revision to the calendar component."
// TODO: make the list of properties considered 'significant' for scheduling configurable
foreach (self::$scheduling_properties as $prop) {
if ($object[$prop] != $old[$prop]) {
$object['sequence']++;
break;
}
}
}
}
$this->obj->setSequence(intval($object['sequence']));
$this->obj->setSummary($object['title']);
$this->obj->setLocation($object['location']);