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:
parent
0c5465c2ad
commit
afb64c3948
5 changed files with 47 additions and 6 deletions
|
@ -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') {
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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']);
|
||||
|
|
Loading…
Add table
Reference in a new issue