5 commits - plugins/calendar plugins/libcalendaring plugins/libkolab
Thomas Brüderli
bruederli at kolabsys.com
Thu Feb 12 12:09:07 CET 2015
plugins/calendar/calendar.php | 3 -
plugins/calendar/calendar_ui.js | 14 ++++-
plugins/calendar/drivers/kolab/kolab_driver.php | 61 +++++++++++++++++++++++-
plugins/libcalendaring/libcalendaring.js | 1
plugins/libkolab/config.inc.php.dist | 8 +++
plugins/libkolab/lib/kolab_format_event.php | 5 +
plugins/libkolab/lib/kolab_format_task.php | 2
plugins/libkolab/lib/kolab_format_xcal.php | 5 -
plugins/libkolab/lib/kolab_storage.php | 9 +++
9 files changed, 98 insertions(+), 10 deletions(-)
New commits:
commit 747f2d5a2625543b0d0f0600ef17439ef71c092e
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Feb 12 12:08:56 2015 +0100
Avoid JS errors on organizer check
diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index 57a5ce5..c1e3d55 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -784,7 +784,7 @@ function rcube_calendar_ui(settings)
// select the correct organizer identity
var identity_id = 0;
$.each(settings.identities, function(i,v){
- if (organizer && v == organizer.email) {
+ if (organizer && typeof organizer == 'object' && v == organizer.email) {
identity_id = i;
return false;
}
commit bef20a0e8d447323843bf8184187c9e1e0ff78f5
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Feb 12 12:08:17 2015 +0100
Reset attendee partstat when event is rescheduled by the organizer (#4360)
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index a4d3f48..51381cb 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -1836,6 +1836,7 @@ class calendar extends rcube_plugin
// convert dates into DateTime objects in user's current timezone
$event['start'] = new DateTime($event['start'], $this->timezone);
$event['end'] = new DateTime($event['end'], $this->timezone);
+ $event['allday'] = (bool)$event['allday'];
// start/end is all we need for 'move' action (#1480)
if ($action == 'move') {
@@ -2211,7 +2212,7 @@ class calendar extends rcube_plugin
public static function event_diff($a, $b)
{
$diff = array();
- $ignore = array('changed' => 1, 'attachments' => 1);
+ $ignore = array('changed' => 1, 'attachments' => 1, 'recurrence' => 1, '_notify' => 1, '_owner' => 1);
foreach (array_unique(array_merge(array_keys($a), array_keys($b))) as $key) {
if (!$ignore[$key] && $a[$key] != $b[$key])
$diff[] = $key;
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index 0d5b9ab..98318f2 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -883,6 +883,9 @@ class kolab_driver extends calendar_driver
$savemode = $event['_savemode'];
}
+ // check if update affects scheduling and update attendee status accordingly
+ $reschedule = $this->check_scheduling($event, $old, true);
+
// keep saved exceptions (not submitted by the client)
if ($old['recurrence']['EXDATE'] && !isset($event['recurrence']['EXDATE']))
$event['recurrence']['EXDATE'] = $old['recurrence']['EXDATE'];
@@ -914,7 +917,10 @@ class kolab_driver extends calendar_driver
$event['recurrence'] = array();
$event['thisandfuture'] = $savemode == 'future';
- // TODO: increment sequence if scheduling is affected
+ // increment sequence of this instance if scheduling is affected
+ if ($reschedule) {
+ $event['sequence'] = $old['sequence'] + 1;
+ }
// remove some internal properties which should not be saved
unset($event['id'], $event['_savemode'], $event['_fromcalendar'], $event['_identity'], $event['_notify']);
@@ -991,7 +997,8 @@ class kolab_driver extends calendar_driver
}
// adjust recurrence-id when start changed and therefore the entire recurrence chain changes
- if (($old_start_date != $new_start_date || $old_start_time != $new_start_time) && is_array($event['recurrence']['EXCEPTIONS']) && !$with_exceptions) {
+ if (($old_start_date != $new_start_date || $old_start_time != $new_start_time) &&
+ is_array($event['recurrence']) && is_array($event['recurrence']['EXCEPTIONS']) && !$with_exceptions) {
$recurrence_id_format = $event['allday'] ? 'Ymd' : 'Ymd\THis';
foreach ($event['recurrence']['EXCEPTIONS'] as $i => $exception) {
$recurrence_id = is_a($exception['recurrence_date'], 'DateTime') ? $exception['recurrence_date'] :
@@ -1018,6 +1025,56 @@ class kolab_driver extends calendar_driver
}
/**
+ * Determine whether the current change affects scheduling and reset attendee status accordingly
+ */
+ public function check_scheduling(&$event, $old, $update = true)
+ {
+ $reschedule = false;
+
+ // skip this check when importing iCal/iTip events
+ if (isset($event['sequence']) || !empty($event['_method'])) {
+ return $reschedule;
+ }
+
+ // iterate through the list of properties considered 'significant' for scheduling
+ foreach (kolab_format_event::$scheduling_properties as $prop) {
+ $a = $old[$prop];
+ $b = $event[$prop];
+ if ($event['allday'] && ($prop == 'start' || $prop == 'end') && $a instanceof DateTime && $b instanceof DateTime) {
+ $a = $a->format('Y-m-d');
+ $b = $b->format('Y-m-d');
+ }
+ if ($a != $b) {
+ $reschedule = true;
+ break;
+ }
+ }
+
+ // reset all attendee status to needs-action (#4360)
+ if ($update && $reschedule && is_array($event['attendees'])) {
+ $is_organizer = false;
+ $emails = $this->cal->get_user_emails();
+ $attendees = $event['attendees'];
+ foreach ($attendees as $i => $attendee) {
+ if ($attendee['role'] == 'ORGANIZER' && $attendee['email'] && in_array(strtolower($attendee['email']), $emails)) {
+ $is_organizer = true;
+ }
+ else if ($attendee['role'] != 'ORGANIZER' && $attendee['role'] != 'NON-PARTICIPANT' && $attendee['status'] != 'DELEGATED') {
+ $attendees[$i]['status'] = 'NEEDS-ACTION';
+ $attendees[$i]['rsvp'] = true;
+ }
+ }
+
+ // update attendees only if I'm the organizer
+ if ($is_organizer || ($event['organizer'] && in_array(strtolower($event['organizer']['email']), $emails))) {
+ $event['attendees'] = $attendees;
+ }
+ }
+
+ return $reschedule;
+ }
+
+ /**
* Get events from source.
*
* @param integer Event's new start (unix timestamp)
commit 314501fdb20e2d8cd5a3ee0fbba66153f0287a05
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Feb 12 11:54:51 2015 +0100
Make the list of properties considered 'significant' for scheduling configurable
diff --git a/plugins/libkolab/config.inc.php.dist b/plugins/libkolab/config.inc.php.dist
index 5973d33..6e4b613 100644
--- a/plugins/libkolab/config.inc.php.dist
+++ b/plugins/libkolab/config.inc.php.dist
@@ -39,6 +39,14 @@ $config['kolab_http_request'] = array();
// 1 - bypass only messages, but use index cache
$config['kolab_messages_cache_bypass'] = 0;
+// These event properties contribute to a significant revision to the calendar component
+// and if changed will increment the sequence number relevant for scheduling according to RFC 5545
+$config['kolab_event_scheduling_properties'] = array('start', 'end', 'allday', 'location', 'status', 'cancelled');
+
+// These task properties contribute to a significant revision to the calendar component
+// and if changed will increment the sequence number relevant for scheduling according to RFC 5545
+$config['kolab_task_scheduling_properties'] = array('start', 'due', 'summary', 'status');
+
// LDAP directory to find avilable users for folder sharing.
// Either contains an array with LDAP addressbook configuration or refers to entry in $config['ldap_public'].
// If not specified, the configuraton from 'kolab_auth_addressbook' will be used.
diff --git a/plugins/libkolab/lib/kolab_format_event.php b/plugins/libkolab/lib/kolab_format_event.php
index 03b5dde..075c517 100644
--- a/plugins/libkolab/lib/kolab_format_event.php
+++ b/plugins/libkolab/lib/kolab_format_event.php
@@ -26,7 +26,7 @@ class kolab_format_event extends kolab_format_xcal
{
public $CTYPEv2 = 'application/x-vnd.kolab.event';
- public $scheduling_properties = array('start', 'end', 'allday', 'location', 'status', 'cancelled');
+ public static $scheduling_properties = array('start', 'end', 'allday', 'location', 'status', 'cancelled');
protected $objclass = 'Event';
protected $read_func = 'readEvent';
@@ -250,6 +250,9 @@ class kolab_format_event extends kolab_format_xcal
}
}
+ // preserve this property for date serialization
+ $exception['allday'] = $master['allday'];
+
return $exception;
}
diff --git a/plugins/libkolab/lib/kolab_format_task.php b/plugins/libkolab/lib/kolab_format_task.php
index 52744d4..ee0ca6a 100644
--- a/plugins/libkolab/lib/kolab_format_task.php
+++ b/plugins/libkolab/lib/kolab_format_task.php
@@ -26,7 +26,7 @@ class kolab_format_task extends kolab_format_xcal
{
public $CTYPEv2 = 'application/x-vnd.kolab.task';
- public $scheduling_properties = array('start', 'due', 'summary', 'status');
+ public static $scheduling_properties = array('start', 'due', 'summary', 'status');
protected $objclass = 'Todo';
protected $read_func = 'readTodo';
diff --git a/plugins/libkolab/lib/kolab_format_xcal.php b/plugins/libkolab/lib/kolab_format_xcal.php
index 33ada93..d0f89b6 100644
--- a/plugins/libkolab/lib/kolab_format_xcal.php
+++ b/plugins/libkolab/lib/kolab_format_xcal.php
@@ -30,7 +30,7 @@ abstract class kolab_format_xcal extends kolab_format
public static $fulltext_cols = array('title', 'description', 'location', 'attendees:name', 'attendees:email', 'categories');
- public $scheduling_properties = array('start', 'end', 'location');
+ public static $scheduling_properties = array('start', 'end', 'location');
protected $sensitivity_map = array(
'public' => kolabformat::ClassPublic,
@@ -321,8 +321,7 @@ abstract class kolab_format_xcal extends kolab_format
// 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 ($this->scheduling_properties as $prop) {
+ foreach (self::$scheduling_properties as $prop) {
$a = $old[$prop];
$b = $object[$prop];
if ($object['allday'] && ($prop == 'start' || $prop == 'end') && $a instanceof DateTime && $b instanceof DateTime) {
diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php
index 47c1e4b..bc38adc 100644
--- a/plugins/libkolab/lib/kolab_storage.php
+++ b/plugins/libkolab/lib/kolab_storage.php
@@ -106,6 +106,15 @@ class kolab_storage
), true);
}
+ // adjust some configurable settings
+ if ($event_scheduling_prop = $rcmail->config->get('kolab_event_scheduling_properties', null)) {
+ kolab_format_event::$scheduling_properties = (array)$event_scheduling_prop;
+ }
+ // adjust some configurable settings
+ if ($task_scheduling_prop = $rcmail->config->get('kolab_task_scheduling_properties', null)) {
+ kolab_format_task::$scheduling_properties = (array)$task_scheduling_prop;
+ }
+
return self::$ready;
}
commit 5990d292e91d1c979c19223855eda346ba3a248f
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Feb 12 10:34:40 2015 +0100
Suppress default link action
diff --git a/plugins/libcalendaring/libcalendaring.js b/plugins/libcalendaring/libcalendaring.js
index a959b9a..0a2949d 100644
--- a/plugins/libcalendaring/libcalendaring.js
+++ b/plugins/libcalendaring/libcalendaring.js
@@ -1139,6 +1139,7 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
$('.rsvp-buttons').on('click', 'a.reply-comment-toggle', function(e){
$(this).hide().parent().find('textarea').show().focus();
+ return false;
});
if (rcmail.env.action == 'get-attachment' && rcmail.gui_objects['attachmentframe']) {
commit 26ef4c64f8474a2fff869e4f5645cbca5de65aca
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Feb 12 10:34:08 2015 +0100
Shift end time according to the current duration when changing start time (for convenience)
diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index a8c01ac..57a5ce5 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -4032,7 +4032,7 @@ function rcube_calendar_ui(settings)
open: autocomplete_open,
change: event_times_changed,
select: function(event, ui) {
- $(this).val(ui.item[0]);
+ $(this).val(ui.item[0]).change();
return false;
}
})
@@ -4047,6 +4047,16 @@ function rcube_calendar_ui(settings)
};
});
+ // adjust end time when changing start
+ $('#edit-starttime').change(function(e) {
+ var dstart = $('#edit-startdate'),
+ newstart = parse_datetime(this.value, dstart.val()),
+ newend = new Date(newstart.getTime() + dstart.data('duration') * 1000);
+ $('#edit-endtime').val($.fullCalendar.formatDate(newend, me.settings['time_format']));
+ $('#edit-enddate').val($.fullCalendar.formatDate(newend, me.settings['date_format']));
+ event_times_changed();
+ });
+
// register events on alarms and recurrence fields
me.init_alarms_edit('#edit-alarms');
me.init_recurrence_edit('#eventedit');
More information about the commits
mailing list