Branch 'dev/recurring-invitations' - plugins/calendar plugins/libkolab

Thomas Brüderli bruederli at kolabsys.com
Sun Feb 15 16:33:47 CET 2015


 plugins/calendar/calendar.php                   |    8 ++--
 plugins/calendar/drivers/kolab/kolab_driver.php |   17 +-------
 plugins/libkolab/config.inc.php.dist            |    2 -
 plugins/libkolab/lib/kolab_format_event.php     |   12 +++++-
 plugins/libkolab/lib/kolab_format_task.php      |   10 +++++
 plugins/libkolab/lib/kolab_format_xcal.php      |   48 ++++++++++++++++++------
 6 files changed, 65 insertions(+), 32 deletions(-)

New commits:
commit 12591358e600dd3b0ad91a8f29345354e34000ac
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Sun Feb 15 16:33:39 2015 +0100

    Consider a change in recurrence rule significant for rescheduling (#4366)

diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index f1e66ec..880086d 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -993,7 +993,7 @@ class calendar extends rcube_plugin
         if ($success = $this->driver->edit_rsvp($event, $status)) {
           $noreply = rcube_utils::get_input_value('noreply', rcube_utils::INPUT_GPC);
           $noreply = intval($noreply) || $status == 'needs-action' || $itip_sending === 0;
-          $reload  = $event['calendar'] != $ev['calendar'] ? 2 : 1;
+          $reload  = $event['calendar'] != $ev['calendar'] || $event['recurrence'] ? 2 : 1;
           $organizer = null;
           $emails = $this->get_user_emails();
 
@@ -1131,8 +1131,6 @@ class calendar extends rcube_plugin
       // make sure we have the complete record
       $event = $action == 'remove' ? $old : $this->driver->get_event($event);
 
-      // TODO: on change of a recurring (main) event, also send updates to differing attendess of recurrence exceptions
-
       // only notify if data really changed (TODO: do diff check on client already)
       if (!$old || $action == 'remove' || self::event_diff($event, $old)) {
         $sent = $this->notify_attendees($event, $old, $action, $event['_comment']);
@@ -1990,6 +1988,8 @@ class calendar extends rcube_plugin
         $sent = -100;
     }
 
+    // TODO: on change of a recurring (main) event, also send updates to differing attendess of recurrence exceptions
+
     // send CANCEL message to removed attendees
     foreach ((array)$old['attendees'] as $attendee) {
       if ($attendee['ROLE'] == 'ORGANIZER' || !$attendee['email'] || in_array(strtolower($attendee['email']), $current))
@@ -2215,7 +2215,7 @@ class calendar extends rcube_plugin
   public static function event_diff($a, $b)
   {
     $diff = array();
-    $ignore = array('changed' => 1, 'attachments' => 1, 'recurrence' => 1, '_notify' => 1, '_owner' => 1);
+    $ignore = array('changed' => 1, 'attachments' => 1, '_notify' => 1, '_owner' => 1, '_savemode' => 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 4b450f8..815f51e 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -1035,26 +1035,13 @@ class kolab_driver extends calendar_driver
    */
   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;
+      return false;
     }
 
     // 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;
-      }
-    }
+    $reschedule = kolab_format_event::check_rescheduling($event, $old);
 
     // reset all attendee status to needs-action (#4360)
     if ($update && $reschedule && is_array($event['attendees'])) {
diff --git a/plugins/libkolab/config.inc.php.dist b/plugins/libkolab/config.inc.php.dist
index 6e4b613..3a8476c 100644
--- a/plugins/libkolab/config.inc.php.dist
+++ b/plugins/libkolab/config.inc.php.dist
@@ -41,7 +41,7 @@ $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');
+$config['kolab_event_scheduling_properties'] = array('start', 'end', 'allday', 'recurrence', '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
diff --git a/plugins/libkolab/lib/kolab_format_event.php b/plugins/libkolab/lib/kolab_format_event.php
index bf17149..f3c52df 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 static $scheduling_properties = array('start', 'end', 'allday', 'location', 'status', 'cancelled');
+    public static $scheduling_properties = array('start', 'end', 'allday', 'recurrence', 'location', 'status', 'cancelled');
 
     protected $objclass = 'Event';
     protected $read_func = 'readEvent';
@@ -100,6 +100,7 @@ class kolab_format_event extends kolab_format_xcal
             foreach((array)$object['recurrence']['EXCEPTIONS'] as $i => $exception) {
                 $exevent = new kolab_format_event;
                 $exevent->set(($compacted = $this->compact_exception($exception, $object)));  // only save differing values
+                console('COMPACTED', $compacted);
 
                 // get value for recurrence-id
                 if (!empty($exception['recurrence_date']) && is_a($exception['recurrence_date'], 'DateTime')) {
@@ -274,4 +275,13 @@ class kolab_format_event extends kolab_format_xcal
         return $exception;
     }
 
+    /**
+     * Identify changes considered relevant for scheduling
+     *
+     * @see kolab_format_xcal::check_rescheduling()
+     */
+    public static function check_rescheduling($object, $old, $checks = null)
+    {
+        return parent::check_rescheduling($object, $old, $checks ?: self::$scheduling_properties);
+    }
 }
diff --git a/plugins/libkolab/lib/kolab_format_task.php b/plugins/libkolab/lib/kolab_format_task.php
index ee0ca6a..2c0cda5 100644
--- a/plugins/libkolab/lib/kolab_format_task.php
+++ b/plugins/libkolab/lib/kolab_format_task.php
@@ -126,4 +126,14 @@ class kolab_format_task extends kolab_format_xcal
 
         return $tags;
     }
+
+    /**
+     * Identify changes considered relevant for scheduling
+     *
+     * @see kolab_format_xcal::check_rescheduling()
+     */
+    public static function check_rescheduling($object, $old, $checks = null)
+    {
+        return parent::check_rescheduling($object, $old, $checks ?: self::$scheduling_properties);
+    }
 }
diff --git a/plugins/libkolab/lib/kolab_format_xcal.php b/plugins/libkolab/lib/kolab_format_xcal.php
index d0f89b6..8d751a6 100644
--- a/plugins/libkolab/lib/kolab_format_xcal.php
+++ b/plugins/libkolab/lib/kolab_format_xcal.php
@@ -321,17 +321,8 @@ 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."
-                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) {
-                        $a = $a->format('Y-m-d');
-                        $b = $b->format('Y-m-d');
-                    }
-                    if ($a != $b) {
-                        $object['sequence']++;
-                        break;
-                    }
+                if (self::check_rescheduling($object, $old)) {
+                    $object['sequence']++;
                 }
             }
         }
@@ -637,4 +628,39 @@ abstract class kolab_format_xcal extends kolab_format
 
         return $tags;
     }
+
+    /**
+     * Identify changes considered relevant for scheduling
+     * 
+     * @param array Hash array with NEW object properties
+     * @param array Hash array with OLD object properties
+     * @param array List of object properties to check for changes
+     *
+     * @return boolean True if changes affect scheduling, False otherwise
+     */
+    public static function check_rescheduling($object, $old, $checks = null)
+    {
+        $reschedule = false;
+
+        foreach ($checks ?: self::$scheduling_properties as $prop) {
+            $a = $old[$prop];
+            $b = $object[$prop];
+            if ($object['allday'] && ($prop == 'start' || $prop == 'end') && $a instanceof DateTime && $b instanceof DateTime) {
+                $a = $a->format('Y-m-d');
+                $b = $b->format('Y-m-d');
+            }
+            if ($prop == 'recurrence') {
+                unset($a['EXCEPTIONS']);
+                unset($b['EXCEPTIONS']);
+                $a = array_filter($a);
+                $b = array_filter($b);
+            }
+            if ($a != $b) {
+                $reschedule = true;
+                break;
+            }
+        }
+
+        return $reschedule;
+    }
 }
\ No newline at end of file




More information about the commits mailing list