plugins/libkolab

Thomas Brüderli bruederli at kolabsys.com
Wed Mar 13 17:39:53 CET 2013


 plugins/libkolab/lib/kolab_storage_folder.php |   39 ++++++++++++++++++++------
 1 file changed, 31 insertions(+), 8 deletions(-)

New commits:
commit 69bc310cc53645550704a05998f9528769962cd5
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed Mar 13 17:39:41 2013 +0100

    Fix saving of recurrence exceptions for v2: create unique UIDs, correctly save this-and-future instances with (modified) recurrence rule

diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php
index e4fc5de..dd0e8d2 100644
--- a/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/plugins/libkolab/lib/kolab_storage_folder.php
@@ -718,22 +718,35 @@ class kolab_storage_folder
 
             // save every exception as individual object
             foreach((array)$object['recurrence']['EXCEPTIONS'] as $exception) {
-                $exception['uid'] = $object['uid'] . '-' . $exception['start']->format('Ymd');
-                $exception['recurrence-id'] = $exception['start']->format('Y-m-d');
+                $exception['uid'] = self::recurrence_exception_uid($object['uid'], $exception['start']->format('Ymd'));
                 $exception['sequence'] = $object['sequence'] + 1;
 
-                unset($exception['recurrence'], $exception['organizer'], $exception['attendees']);
-                $this->save($exception, $type, $exception['uid']);
-
-                // set UNTIL date if we have a thisandfuture exception
                 if ($exception['thisandfuture']) {
+                    $exception['recurrence'] = $object['recurrence'];
+
+                    // adjust the recurrence duration of the exception
+                    if ($object['recurrence']['COUNT']) {
+                        $recurrence = new kolab_date_recurrence($object['_formatobj']);
+                        if ($end = $recurrence->end()) {
+                            unset($exception['recurrence']['COUNT']);
+                            $exception['recurrence']['UNTIL'] = new DateTime('@'.$end);
+                        }
+                    }
+
+                    // set UNTIL date if we have a thisandfuture exception
                     $untildate = clone $exception['start'];
                     $untildate->sub(new DateInterval('P1D'));
                     $object['recurrence']['UNTIL'] = $untildate;
                     unset($object['recurrence']['COUNT']);
                 }
-                else if (!$exdates[$exception['start']->format('Y-m-d')])
-                    $object['recurrence']['EXDATE'][] = clone $exception['start'];
+                else {
+                    if (!$exdates[$exception['start']->format('Y-m-d')])
+                        $object['recurrence']['EXDATE'][] = clone $exception['start'];
+                    unset($exception['recurrence']);
+                }
+
+                unset($exception['recurrence']['EXCEPTIONS'], $exception['_formatobj'], $exception['_msguid']);
+                $this->save($exception, $type, $exception['uid']);
             }
 
             unset($object['recurrence']['EXCEPTIONS']);
@@ -741,6 +754,16 @@ class kolab_storage_folder
     }
 
     /**
+     * Generate an object UID with the given recurrence-ID in a way that it is
+     * unique (the original UID is not a substring) but still recoverable.
+     */
+    private static function recurrence_exception_uid($uid, $recurrence_id)
+    {
+        $offset = -2;
+        return substr($uid, 0, $offset) . '-' . $recurrence_id . '-' . substr($uid, $offset);
+    }
+
+    /**
      * Delete the specified object from this folder.
      *
      * @param  mixed   $object  The Kolab object to delete or object UID





More information about the commits mailing list