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

Thomas Brüderli bruederli at kolabsys.com
Wed Feb 18 11:30:20 CET 2015


 plugins/calendar/drivers/kolab/kolab_driver.php |   81 +++++++++++++++++++-----
 1 file changed, 67 insertions(+), 14 deletions(-)

New commits:
commit b47b13a35ebb65cecbe028a177deed10752ee7cc
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed Feb 18 11:30:16 2015 +0100

    Dynamically update attendees on exceptions in 'all' and 'future' save mode

diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index f2a9269..7b4c639 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -1045,19 +1045,41 @@ class kolab_driver extends calendar_driver
           $event['end'] = $master['end'];
         }
 
+        // when saving an instance in 'all' mode, copy recurrence exceptions over
+        if ($old['recurrence_id']) {
+          $event['recurrence'] = $master['recurrence'];
+        }
+
         // TODO: forward changes to exceptions (which do not yet have differing values stored)
+        if (is_array($event['recurrence']) && is_array($event['recurrence']['EXCEPTIONS']) && !$with_exceptions) {
+          // determine added and removed attendees
+          $old_attendees = $current_attendees = $added_attendees = array();
+          foreach ((array)$old['attendees'] as $attendee) {
+            $old_attendees[] = $attendee['email'];
+          }
+          foreach ((array)$event['attendees'] as $attendee) {
+            $current_attendees[] = $attendee['email'];
+            if (!in_array($attendee['email'], $old_attendees)) {
+              $added_attendees[] = $attendee;
+            }
+          }
+          $removed_attendees = array_diff($old_attendees, $current_attendees);
 
-        // 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']) && 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'] :
-                rcube_utils::anytodatetime($exception['_instance'], $old['start']->getTimezone());
-            if (is_a($recurrence_id, 'DateTime')) {
-              $recurrence_id->add($date_shift);
-              $event['recurrence']['EXCEPTIONS'][$i]['recurrence_date'] = $recurrence_id;
-              $event['recurrence']['EXCEPTIONS'][$i]['_instance'] = $recurrence_id->format($recurrence_id_format);
+            self::merge_attendee_data($event['recurrence']['EXCEPTIONS'][$i], $added_attendees, $removed_attendees);
+          }
+
+          // 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) {
+            $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'] :
+                  rcube_utils::anytodatetime($exception['_instance'], $old['start']->getTimezone());
+              if (is_a($recurrence_id, 'DateTime')) {
+                $recurrence_id->add($date_shift);
+                $event['recurrence']['EXCEPTIONS'][$i]['recurrence_date'] = $recurrence_id;
+                $event['recurrence']['EXCEPTIONS'][$i]['_instance'] = $recurrence_id->format($recurrence_id_format);
+              }
             }
           }
         }
@@ -1121,6 +1143,22 @@ class kolab_driver extends calendar_driver
     $saved = false;
     $existing = null;
 
+    // determine added and removed attendees
+    $added_attendees = $removed_attendees = array();
+    if ($savemode == 'future') {
+      $old_attendees = $current_attendees = array();
+      foreach ((array)$old['attendees'] as $attendee) {
+        $old_attendees[] = $attendee['email'];
+      }
+      foreach ((array)$event['attendees'] as $attendee) {
+        $current_attendees[] = $attendee['email'];
+        if (!in_array($attendee['email'], $old_attendees)) {
+          $added_attendees[] = $attendee;
+        }
+      }
+      $removed_attendees = array_diff($old_attendees, $current_attendees);
+    }
+
     foreach ($master['recurrence']['EXCEPTIONS'] as $i => $exception) {
       // update a specific instance
       if ($exception['_instance'] == $old['_instance']) {
@@ -1139,7 +1177,11 @@ class kolab_driver extends calendar_driver
       // merge the new event properties onto future exceptions
       if ($savemode == 'future' && $exception['_instance'] >= $old['_instance']) {
         unset($event['thisandfuture']);
-        self::merge_exception_data($master['recurrence']['EXCEPTIONS'][$i], $event);
+        self::merge_exception_data($master['recurrence']['EXCEPTIONS'][$i], $event, array('attendees'));
+
+        if (!empty($added_attendees) || !empty($removed_attendees)) {
+          self::merge_attendee_data($master['recurrence']['EXCEPTIONS'][$i], $added_attendees, $removed_attendees);
+        }
       }
     }
 /*
@@ -1174,10 +1216,14 @@ class kolab_driver extends calendar_driver
    *
    * @param array The event object to be altered
    * @param array The overlay event object to be merged over $event
+   * @param array List of properties not allowed to be overwritten
    */
-  public static function merge_exception_data(&$event, $overlay)
+  public static function merge_exception_data(&$event, $overlay, $blacklist = null)
   {
-    static $forbidden = array('id','uid','recurrence','recurrence_date','thisandfuture','organizer','_attachments');
+    $forbidden = array('id','uid','recurrence','recurrence_date','thisandfuture','organizer','_attachments');
+
+    if (is_array($blacklist))
+      $forbidden = array_merge($forbidden, $blacklist);
 
     // compute date offset from the exception
     if ($overlay['start'] instanceof DateTime && $overlay['recurrence_date'] instanceof DateTime) {
@@ -1213,7 +1259,7 @@ class kolab_driver extends calendar_driver
    * @param array The event object to be altered
    * @param array List of hash arrays each represeting an updated/added attendee
    */
-  public static function merge_attendee_data(&$event, $attendees)
+  public static function merge_attendee_data(&$event, $attendees, $removed = null)
   {
     if (!empty($attendees) && !is_array($attendees[0])) {
       $attendees = array($attendees);
@@ -1234,6 +1280,13 @@ class kolab_driver extends calendar_driver
         $event['attendees'][] = $attendee;
       }
     }
+
+    // filter out removed attendees
+    if (!empty($removed)) {
+      $event['attendees'] = array_filter($event['attendees'], function($attendee) use ($removed) {
+        return !in_array($attendee['email'], $removed);
+      });
+    }
   }
 
   /**




More information about the commits mailing list