Branch 'roundcubemail-plugins-kolab-3.0' - 14 commits - plugins/calendar plugins/kolab_addressbook plugins/libcalendaring plugins/libkolab

Aleksander Machniak machniak at kolabsys.com
Mon Jun 24 13:11:27 CEST 2013


 plugins/calendar/calendar.php                          |    3 
 plugins/calendar/calendar_ui.js                        |    3 
 plugins/calendar/drivers/calendar_driver.php           |    1 
 plugins/calendar/drivers/kolab/kolab_calendar.php      |   81 +-------------
 plugins/calendar/drivers/kolab/kolab_driver.php        |   76 ++++++++-----
 plugins/calendar/lib/calendar_ical.php                 |   57 +++-------
 plugins/kolab_addressbook/lib/rcube_kolab_contacts.php |   57 ++++++----
 plugins/libcalendaring/libcalendaring.php              |    2 
 plugins/libkolab/lib/kolab_format_contact.php          |   51 +--------
 plugins/libkolab/lib/kolab_format_event.php            |   93 -----------------
 plugins/libkolab/lib/kolab_format_xcal.php             |   21 ---
 plugins/libkolab/lib/kolab_storage_folder.php          |   82 +-------------
 12 files changed, 129 insertions(+), 398 deletions(-)

New commits:
commit d42d47518c9af6ea8ecc31f8b23e8a7a24be387f
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 13:09:44 2013 +0200

    Revert "Expose URI attachments as 'links' for event objects"
    
    This reverts commit b111a369e3485b751fa8a2c010f1a358210d62e7.

diff --git a/plugins/libkolab/lib/kolab_format_event.php b/plugins/libkolab/lib/kolab_format_event.php
index c9dc779..d472ac5 100644
--- a/plugins/libkolab/lib/kolab_format_event.php
+++ b/plugins/libkolab/lib/kolab_format_event.php
@@ -86,13 +86,6 @@ class kolab_format_event extends kolab_format_xcal
             $attach->setUri('cid:' . $cid, $attr['mimetype']);
             $vattach->push($attach);
         }
-
-        foreach ((array)$object['links'] as $link) {
-            $attach = new Attachment;
-            $attach->setUri($link, null);
-            $vattach->push($attach);
-        }
-
         $this->obj->setAttachments($vattach);
 
         // cache this data
@@ -159,9 +152,6 @@ class kolab_format_event extends kolab_format_xcal
                     'content'  => $data,
                 );
             }
-            else if (substr($attach->uri(), 0, 4) == 'http') {
-                $object['links'][] = $attach->uri();
-            }
         }
 
         $this->data = $object;


commit f14e8fec687dc02165e4bb7f97aaade8f8d262f8
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 13:04:19 2013 +0200

    Revert "Adapt libkolab and kolab_addressbook to support type parameters for email addresses"
    
    This reverts commit 9fc4a17451e2e700de8e29e68033bc5479f68ca0.
    
    Conflicts:
    
    	plugins/libkolab/lib/kolab_format_contact.php

diff --git a/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php b/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php
index 5437056..d94e4c8 100644
--- a/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php
+++ b/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php
@@ -44,7 +44,7 @@ class rcube_kolab_contacts extends rcube_addressbook
       'jobtitle'     => array('limit' => 1),
       'organization' => array('limit' => 1),
       'department'   => array('limit' => 1),
-      'email'        => array('subtypes' => array('home','work','other')),
+      'email'        => array('subtypes' => null),
       'phone'        => array(),
       'address'      => array('subtypes' => array('home','work','office')),
       'website'      => array('subtypes' => array('homepage','blog')),
@@ -1037,15 +1037,21 @@ class rcube_kolab_contacts extends rcube_addressbook
     {
         $record['ID'] = $this->_uid2id($record['uid']);
 
-        // convert email, website, phone values
-        foreach (array('email'=>'address', 'website'=>'url', 'phone'=>'number') as $col => $propname) {
-            if (is_array($record[$col])) {
-                $values = $record[$col];
-                unset($record[$col]);
-                foreach ((array)$values as $i => $val) {
-                    $key = $col . ($val['type'] ? ':' . $val['type'] : '');
-                    $record[$key][] = $val[$propname];
-                }
+        if (is_array($record['phone'])) {
+            $phones = $record['phone'];
+            unset($record['phone']);
+            foreach ((array)$phones as $i => $phone) {
+                $key = 'phone' . ($phone['type'] ? ':' . $phone['type'] : '');
+                $record[$key][] = $phone['number'];
+            }
+        }
+
+        if (is_array($record['website'])) {
+            $urls = $record['website'];
+            unset($record['website']);
+            foreach ((array)$urls as $i => $url) {
+                $key = 'website' . ($url['type'] ? ':' . $url['type'] : '');
+                $record[$key][] = $url['url'];
             }
         }
 
@@ -1094,22 +1100,31 @@ class rcube_kolab_contacts extends rcube_addressbook
         else if (!$contact['uid'] && $old['uid'])
             $contact['uid'] = $old['uid'];
 
+        $contact['email'] = array_filter($this->get_col_values('email', $contact, true));
         $contact['im']    = array_filter($this->get_col_values('im', $contact, true));
 
-        // convert email, website, phone values
-        foreach (array('email'=>'address', 'website'=>'url', 'phone'=>'number') as $col => $propname) {
-            $contact[$col] = array();
-            foreach ($this->get_col_values($col, $contact) as $type => $values) {
-                foreach ((array)$values as $val) {
-                    if (!empty($val)) {
-                        $contact[$col][] = array($propname => $val, 'type' => $type);
-                    }
+        $websites  = array();
+        $phones    = array();
+        $addresses = array();
+
+        foreach ($this->get_col_values('website', $contact) as $type => $values) {
+            foreach ((array)$values as $url) {
+                if (!empty($url)) {
+                    $websites[] = array('url' => $url, 'type' => $type);
                 }
-                unset($contact[$col.':'.$type]);
             }
+            unset($contact['website:'.$type]);
+        }
+
+        foreach ($this->get_col_values('phone', $contact) as $type => $values) {
+            foreach ((array)$values as $phone) {
+                if (!empty($phone)) {
+                    $phones[] = array('number' => $phone, 'type' => $type);
+                }
+            }
+            unset($contact['phone:'.$type]);
         }
 
-        $addresses = array();
         foreach ($this->get_col_values('address', $contact) as $type => $values) {
             foreach ((array)$values as $adr) {
                 // skip empty address
@@ -1130,6 +1145,8 @@ class rcube_kolab_contacts extends rcube_addressbook
             unset($contact['address:'.$type]);
         }
 
+        $contact['website'] = $websites;
+        $contact['phone']   = $phones;
         $contact['address'] = $addresses;
 
         // copy meta data (starting with _) from old object
diff --git a/plugins/libkolab/lib/kolab_format_contact.php b/plugins/libkolab/lib/kolab_format_contact.php
index 3852fb7..2f8bd14 100644
--- a/plugins/libkolab/lib/kolab_format_contact.php
+++ b/plugins/libkolab/lib/kolab_format_contact.php
@@ -47,12 +47,6 @@ class kolab_format_contact extends kolab_format
         'other'   => Telephone::Textphone,
     );
 
-    public $emailtypes = array(
-        'home' => Email::Home,
-        'work' => Email::Work,
-        'other' => Email::NoType,
-    );
-
     public $addresstypes = array(
         'home' => Address::Home,
         'work' => Address::Work,
@@ -131,21 +125,10 @@ class kolab_format_contact extends kolab_format
         }
         $org->setRelateds($rels);
 
-        // im, email, url
+        // email, im, url
+        $this->obj->setEmailAddresses(self::array2vector($object['email']));
         $this->obj->setIMaddresses(self::array2vector($object['im']));
 
-        if (class_exists('vectoremail')) {
-            $vemails = new vectoremail;
-            foreach ((array)$object['email'] as $email) {
-                $type = $this->emailtypes[$email['type']];
-                $vemails->push(new Email($email['address'], intval($type)));
-            }
-        }
-        else {
-            $vemails = self::array2vector(array_map(function($v){ return $v['address']; }, $object['email']));
-        }
-        $this->obj->setEmailAddresses($vemails);
-
         $vurls = new vectorurl;
         foreach ((array)$object['website'] as $url) {
             $type = $url['type'] == 'blog' ? Url::Blog : Url::NoType;
@@ -305,19 +288,8 @@ class kolab_format_contact extends kolab_format
             $this->read_relateds($org->relateds(), $object);
         }
 
-        $object['im'] = self::vector2array($this->obj->imAddresses());
-
-        $emails = $this->obj->emailAddresses();
-        if ($emails instanceof vectoremail) {
-            $emailtypes = array_flip($this->emailtypes);
-            for ($i=0; $i < $emails->size(); $i++) {
-                $email = $emails->get($i);
-                $object['email'][] = array('address' => $email->address(), 'type' => $emailtypes[$email->types()]);
-            }
-        }
-        else {
-            $object['email'] = self::vector2array($emails);
-        }
+        $object['email']   = self::vector2array($this->obj->emailAddresses());
+        $object['im']      = self::vector2array($this->obj->imAddresses());
 
         $urls = $this->obj->urls();
         for ($i=0; $i < $urls->size(); $i++) {


commit 2880b3526afd15983b829c2d1e40a5b90d91b34d
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 13:02:50 2013 +0200

    Revert "Save changes in a recurring event as exception to the master event"
    
    This reverts commit 29a8a9ae4dd21fd84890ff0f9d2b445ea37a702a.
    
    Conflicts:
    
    	plugins/calendar/drivers/kolab/kolab_calendar.php
    	plugins/calendar/drivers/kolab/kolab_driver.php
    	plugins/libkolab/lib/kolab_format_event.php

diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index d6cfbec..028b553 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -1091,7 +1091,6 @@ class calendar extends rcube_plugin
       $event['recurrence_text'] = $this->_recurrence_text($event['recurrence']);
       if ($event['recurrence']['UNTIL'])
         $event['recurrence']['UNTIL'] = $this->lib->adjust_timezone($event['recurrence']['UNTIL'])->format('c');
-      unset($event['recurrence']['EXCEPTIONS']);
     }
 
     foreach ((array)$event['attachments'] as $k => $attachment) {
@@ -1122,7 +1121,7 @@ class calendar extends rcube_plugin
       'title'       => strval($event['title']),
       'description' => strval($event['description']),
       'location'    => strval($event['location']),
-      'className'   => ($addcss ? 'fc-event-cal-'.asciiwords($event['calendar'], true).' ' : '') . 'fc-event-cat-' . asciiwords(strtolower(join('-', (array)$event['categories'])), true),
+      'className'   => ($addcss ? 'fc-event-cal-'.asciiwords($event['calendar'], true).' ' : '') . 'fc-event-cat-' . asciiwords(strtolower($event['categories']), true),
       'allDay'      => ($event['allday'] == 1),
     ) + $event;
   }
diff --git a/plugins/calendar/drivers/calendar_driver.php b/plugins/calendar/drivers/calendar_driver.php
index a9402e1..ef3cdb1 100644
--- a/plugins/calendar/drivers/calendar_driver.php
+++ b/plugins/calendar/drivers/calendar_driver.php
@@ -46,7 +46,6 @@
  *           'COUNT' => 1..n,   // number of times
  *                      // + more properties (see http://www.kanzaki.com/docs/ical/recur.html)
  *          'EXDATE' => array(),  // list of DateTime objects of exception Dates/Times
- *      'EXCEPTIONS' => array(<event>),  list of event objects which denote exceptions in the recurrence chain
  *    ),
  * 'recurrence_id' => 'ID of the recurrence group',   // usually the ID of the starting event
  *    'categories' => 'Event category',
diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index da78a81..5b88b82 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -312,7 +312,7 @@ class kolab_calendar
    * @return boolean True on success, False on error
    */
 
-  public function update_event($event, $exception_id = null)
+  public function update_event($event)
   {
     $updated = false;
     $old = $this->storage->get_object($event['id']);
@@ -333,11 +333,6 @@ class kolab_calendar
     else {
       $updated = true;
       $this->events[$event['id']] = $this->_to_rcube_event($object);
-
-      // refresh local cache with recurring instances
-      if ($exception_id) {
-        $this->_get_recurring_events($object, $event['start'], $event['end'], $exception_id);
-      }
     }
 
     return $updated;
@@ -418,29 +413,6 @@ class kolab_calendar
       $end->add(new DateInterval($intvl));
     }
 
-    // add recurrence exceptions to output
-    $i = 0;
-    $events = array();
-    $exdates = array();
-    if (is_array($event['recurrence']['EXCEPTIONS'])) {
-        foreach ($event['recurrence']['EXCEPTIONS'] as $exception) {
-            $rec_event = $this->_to_rcube_event($exception);
-            $rec_event['id'] = $event['uid'] . '-' . ++$i;
-            $rec_event['recurrence_id'] = $event['uid'];
-            $rec_event['_instance'] = $i;
-            $events[] = $rec_event;
-
-            // found the specifically requested instance, exiting...
-            if ($rec_event['id'] == $event_id) {
-              $this->events[$rec_event['id']] = $rec_event;
-              return $events;
-            }
-
-            // remember this exception's date
-            $exdates[$rec_event['start']->format('Y-m-d')] = $rec_event['id'];
-        }
-    }
-
     // use libkolab to compute recurring events
     if (class_exists('kolabcalendaring')) {
         $recurrence = new kolab_date_recurrence($object);
@@ -451,6 +423,8 @@ class kolab_calendar
         $recurrence = new calendar_recurrence($this->cal, $event);
     }
 
+    $i = 0;
+    $events = array();
     while ($next_event = $recurrence->next_instance()) {
       // skip if there's an exception at this date
       if ($exdates[$next_event['start']->format('Y-m-d')])
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index 9b70018..fe9f25a 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -580,8 +580,6 @@ class kolab_driver extends calendar_driver
     // keep saved exceptions (not submitted by the client)
     if ($old['recurrence']['EXDATE'])
       $event['recurrence']['EXDATE'] = $old['recurrence']['EXDATE'];
-    if ($old['recurrence']['EXCEPTIONS'])
-      $event['recurrence']['EXCEPTIONS'] = $old['recurrence']['EXCEPTIONS'];
 
     switch ($savemode) {
       case 'new':
@@ -599,11 +597,26 @@ class kolab_driver extends calendar_driver
         break;
         
       case 'current':
-        // save as exception to master event
+        // modifying the first instance => just move to next occurence
+        if ($master['id'] == $event['id']) {
+          $recurring = reset($storage->_get_recurring_events($event, $event['start'], null, $event['id'].'-1'));
+          $master['start'] = $recurring['start'];
+          $master['end'] = $recurring['end'];
+          if ($master['recurrence']['COUNT'])
+            $master['recurrence']['COUNT']--;
+        }
+        else {  // add exception to master event
+          $master['recurrence']['EXDATE'][] = $old['start'];
+		}
+
+        $storage->update_event($master);
+        
+        // insert new event for this occurence
+        $event += $old;
         $event['recurrence'] = array();
-        $master['recurrence']['EXCEPTIONS'][] = $event;
-#       $master['recurrence']['EXDATE'][] = $event['start'];
-        $success = $storage->update_event($master);
+        unset($event['recurrence_id']);
+        $event['uid'] = $this->cal->generate_uid();
+        $success = $storage->insert_event($event);
         break;
         
       case 'future':
@@ -634,20 +647,6 @@ class kolab_driver extends calendar_driver
         }
 
       default:  // 'all' is default
-
-        // remove some internal properties which should not be saved
-        unset($event['_savemode'], $event['_fromcalendar'], $event['_identity']);
-
-        // save properties to a recurrence exception instance
-        if ($old['recurrence_id']) {
-            $i = $old['_instance'] - 1;
-            if (!empty($master['recurrence']['EXCEPTIONS'][$i])) {
-                $master['recurrence']['EXCEPTIONS'][$i] = $event;
-                $success = $storage->update_event($master, $old['id']);
-                break;
-            }
-        }
-
         $event['id'] = $master['id'];
         $event['uid'] = $master['uid'];
 
diff --git a/plugins/libkolab/lib/kolab_format_event.php b/plugins/libkolab/lib/kolab_format_event.php
index 933fbee..c9dc779 100644
--- a/plugins/libkolab/lib/kolab_format_event.php
+++ b/plugins/libkolab/lib/kolab_format_event.php
@@ -30,19 +30,6 @@ class kolab_format_event extends kolab_format_xcal
     protected $read_func = 'readEvent';
     protected $write_func = 'writeEvent';
 
-    /**
-     * Default constructor
-     */
-    function __construct($data = null, $version = 3.0)
-    {
-        parent::__construct(is_string($data) ? $data : null, $version);
-
-        // got an Event object as argument
-        if (is_object($data) && is_a($data, $this->objclass)) {
-            $this->obj = $data;
-            $this->loaded = true;
-        }
-    }
 
     /**
      * Clones into an instance of libcalendaring's extended EventCal class
@@ -108,18 +95,6 @@ class kolab_format_event extends kolab_format_xcal
 
         $this->obj->setAttachments($vattach);
 
-        // save recurrence exceptions
-        if ($object['recurrence']['EXCEPTIONS']) {
-            $vexceptions = new vectorevent;
-            foreach((array)$object['recurrence']['EXCEPTIONS'] as $exception) {
-                $exevent = new kolab_format_event;
-                $exevent->set($this->compact_exception($exception, $object));  // only save differing values
-                $exevent->obj->setRecurrenceID(self::get_datetime($exception['start'], null, true), false);
-                $vexceptions->push($exevent->obj);
-            }
-            $this->obj->setExceptions($vexceptions);
-        }
-
         // cache this data
         $this->data = $object;
         unset($this->data['_formatobj']);
@@ -189,30 +164,6 @@ class kolab_format_event extends kolab_format_xcal
             }
         }
 
-        // read exception event objects
-        if ($exceptions = $this->obj->exceptions()) {
-            for ($i=0; $i < $exceptions->size(); $i++) {
-                if (($exobj = $exceptions->get($i))) {
-                    $exception = new kolab_format_event($exobj);
-                    if ($exception->is_valid()) {
-                        $object['recurrence']['EXCEPTIONS'][] = $this->expand_exception($exception->to_array(), $object);
-                    }
-                }
-            }
-        }
-
-        // merge with additional data, e.g. attachments from the message
-        if ($data) {
-            foreach ($data as $idx => $value) {
-                if (is_array($value)) {
-                    $object[$idx] = array_merge((array)$object[$idx], $value);
-                }
-                else {
-                    $object[$idx] = $value;
-                }
-            }
-        }
-
         $this->data = $object;
         return $this->data;
     }
@@ -236,46 +187,4 @@ class kolab_format_event extends kolab_format_xcal
 
         return $tags;
     }
-
-    /**
-     * Reduce the exception container to attributes which differ from the master event
-     */
-    private function compact_exception($exception, $master)
-    {
-      static $mandatory = array('uid','created','start');
-      static $forbidden = array('recurrence','attendees','sequence');
-
-      $out = $exception;
-      foreach ($exception as $prop => $val) {
-        if (in_array($prop, $mandatory))
-          continue;
-
-        if (is_object($exception[$prop]) && is_a($exception[$prop], 'DateTime'))
-          $equals = $exception[$prop] <> $master[$prop];
-        else
-          $equals = $exception[$prop] == $master[$prop];
-
-        if ($equals || in_array($prop, $forbidden)) {
-          unset($out[$prop]);
-        }
-      }
-
-      return $exception;
-    }
-
-    /**
-     * Copy attributes not specified by the exception from the master event
-     */
-    private function expand_exception($exception, $master)
-    {
-      static $forbidden = array('recurrence');
-
-      foreach ($master as $prop => $value) {
-        if (empty($exception[$prop]) && !in_array($prop, $forbidden))
-          $exception[$prop] = $value;
-      }
-
-      return $exception;
-    }
-
 }
diff --git a/plugins/libkolab/lib/kolab_format_xcal.php b/plugins/libkolab/lib/kolab_format_xcal.php
index b37b727..e9a28e1 100644
--- a/plugins/libkolab/lib/kolab_format_xcal.php
+++ b/plugins/libkolab/lib/kolab_format_xcal.php
@@ -111,7 +111,7 @@ abstract class kolab_format_xcal extends kolab_format
         );
 
         // read organizer and attendees
-        if (($organizer = $this->obj->organizer()) && ($organizer->email() || $organizer->name())) {
+        if ($organizer = $this->obj->organizer()) {
             $object['organizer'] = array(
                 'email' => $organizer->email(),
                 'name' => $organizer->name(),
@@ -170,9 +170,9 @@ abstract class kolab_format_xcal extends kolab_format
                 $object['recurrence']['BYMONTH'] = join(',', self::vector2array($bymonth));
             }
 
-            if ($exdates = $this->obj->exceptionDates()) {
-                for ($i=0; $i < $exdates->size(); $i++) {
-                    if ($exdate = self::php_datetime($exdates->get($i)))
+            if ($exceptions = $this->obj->exceptionDates()) {
+                for ($i=0; $i < $exceptions->size(); $i++) {
+                    if ($exdate = self::php_datetime($exceptions->get($i)))
                         $object['recurrence']['EXDATE'][] = $exdate;
                 }
             }


commit 8ea287e37f46f7ebd51c7dafdf6ad8693a0fd801
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 13:00:42 2013 +0200

    Revert "Make this-and-future recurrence exceptions work"
    
    This reverts commit a616fa629fd0fda66675571c580723d23fc60610.
    
    Conflicts:
    
    	plugins/libkolab/lib/kolab_format_event.php

diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index ddccd6d..d5a86a7 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -524,9 +524,8 @@ function rcube_calendar_ui(settings)
       
       // show warning if editing a recurring event
       if (event.id && event.recurrence) {
-        var sel = event.thisandfuture ? 'future' : 'all';
         $('#edit-recurring-warning').show();
-        $('input.edit-recurring-savemode[value="'+sel+'"]').prop('checked', true);
+        $('input.edit-recurring-savemode[value="all"]').prop('checked', true);
       }
       else
         $('#edit-recurring-warning').hide();
diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index e5af7b0..da78a81 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -422,33 +422,23 @@ class kolab_calendar
     $i = 0;
     $events = array();
     $exdates = array();
-    $futuredata = array();
     if (is_array($event['recurrence']['EXCEPTIONS'])) {
-      // copy the recurrence rule from the master event (to be used in the UI)
-      $recurrence_rule = $event['recurrence'];
-      unset($recurrence_rule['EXCEPTIONS'], $recurrence_rule['EXDATE']);
-
-      foreach ($event['recurrence']['EXCEPTIONS'] as $exception) {
-        $rec_event = $this->_to_rcube_event($exception);
-        $rec_event['id'] = $event['uid'] . '-' . ++$i;
-        $rec_event['recurrence_id'] = $event['uid'];
-        $rec_event['recurrence'] = $recurrence_rule;
-        $rec_event['_instance'] = $i;
-        $events[] = $rec_event;
-
-        // found the specifically requested instance, exiting...
-        if ($rec_event['id'] == $event_id) {
-          $this->events[$rec_event['id']] = $rec_event;
-          return $events;
-        }
+        foreach ($event['recurrence']['EXCEPTIONS'] as $exception) {
+            $rec_event = $this->_to_rcube_event($exception);
+            $rec_event['id'] = $event['uid'] . '-' . ++$i;
+            $rec_event['recurrence_id'] = $event['uid'];
+            $rec_event['_instance'] = $i;
+            $events[] = $rec_event;
+
+            // found the specifically requested instance, exiting...
+            if ($rec_event['id'] == $event_id) {
+              $this->events[$rec_event['id']] = $rec_event;
+              return $events;
+            }
 
-        // remember this exception's date
-        $exdate = $rec_event['start']->format('Y-m-d');
-        $exdates[$exdate] = $rec_event['id'];
-        if ($rec_event['thisandfuture']) {
-          $futuredata[$exdate] = $rec_event;
+            // remember this exception's date
+            $exdates[$rec_event['start']->format('Y-m-d')] = $rec_event['id'];
         }
-      }
     }
 
     // use libkolab to compute recurring events
@@ -456,29 +446,20 @@ class kolab_calendar
         $recurrence = new kolab_date_recurrence($object);
     }
     else {
-      // fallback to local recurrence implementation
-      require_once($this->cal->home . '/lib/calendar_recurrence.php');
-      $recurrence = new calendar_recurrence($this->cal, $event);
+        // fallback to local recurrence implementation
+        require_once($this->cal->home . '/lib/calendar_recurrence.php');
+        $recurrence = new calendar_recurrence($this->cal, $event);
     }
 
     while ($next_event = $recurrence->next_instance()) {
       // skip if there's an exception at this date
-      $datestr = $next_event['start']->format('Y-m-d');
-      if ($exdates[$datestr]) {
-        // use this event data for future recurring instances
-        if ($futuredata[$datestr])
-          $overlay_data = $futuredata[$datestr];
+      if ($exdates[$next_event['start']->format('Y-m-d')])
         continue;
-      }
 
       // add to output if in range
       $rec_id = $event['uid'] . '-' . ++$i;
       if (($next_event['start'] <= $end && $next_event['end'] >= $start) || ($event_id && $rec_id == $event_id)) {
         $rec_event = $this->_to_rcube_event($next_event);
-
-        if ($overlay_data)  // copy data from a 'this-and-future' exception
-          $this->_merge_event_data($rec_event, $overlay_data);
-
         $rec_event['id'] = $rec_id;
         $rec_event['recurrence_id'] = $event['uid'];
         $rec_event['_instance'] = $i;
@@ -502,27 +483,6 @@ class kolab_calendar
   }
 
   /**
-   * Merge certain properties from the overlay event to the base event object
-   *
-   * @param array The event object to be altered
-   * @param array The overlay event object to be merged over $event
-   */
-  private function _merge_event_data(&$event, $overlay)
-  {
-    static $forbidden = array('id','uid','created','changed','recurrence','organizer','attendees','sequence');
-
-    foreach ($overlay as $prop => $value) {
-      // adjust time of the recurring event instance
-      if ($prop == 'start' || $prop == 'end') {
-        if (is_object($event[$prop]) && is_a($event[$prop], 'DateTime'))
-          $event[$prop]->setTime($value->format('G'), intval($value->format('i')), intval($value->format('s')));
-      }
-      else if ($prop[0] != '_' && !in_array($prop, $forbidden))
-        $event[$prop] = $value;
-    }
-  }
-
-  /**
    * Convert from Kolab_Format to internal representation
    */
   private function _to_rcube_event($record)
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index f873166..9b70018 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -424,14 +424,6 @@ class kolab_driver extends calendar_driver
         $savemode = $event['_savemode'];
       }
 
-      // removing an exception instance
-      if ($event['recurrence_id']) {
-        $i = $event['_instance'] - 1;
-        if (!empty($master['recurrence']['EXCEPTIONS'][$i])) {
-          unset($master['recurrence']['EXCEPTIONS'][$i]);
-        }
-      }
-
       switch ($savemode) {
         case 'current':
           $_SESSION['calendar_restore_event_data'] = $master;
@@ -605,12 +597,43 @@ class kolab_driver extends calendar_driver
         
         $success = $storage->insert_event($event);
         break;
-
-      case 'future':
+        
       case 'current':
-        // recurring instances shall not store recurrence rules
+        // save as exception to master event
         $event['recurrence'] = array();
-        $event['thisandfuture'] = $savemode == 'future';
+        $master['recurrence']['EXCEPTIONS'][] = $event;
+#       $master['recurrence']['EXDATE'][] = $event['start'];
+        $success = $storage->update_event($master);
+        break;
+        
+      case 'future':
+        if ($master['id'] != $event['id']) {
+          // set until-date on master event
+          $master['recurrence']['UNTIL'] = clone $old['start'];
+          $master['recurrence']['UNTIL']->sub(new DateInterval('P1D'));
+          unset($master['recurrence']['COUNT']);
+          $storage->update_event($master);
+          
+          // save this instance as new recurring event
+          $event += $old;
+          $event['uid'] = $this->cal->generate_uid();
+          
+          // if recurrence COUNT, update value to the correct number of future occurences
+          if ($event['recurrence']['COUNT']) {
+            $event['recurrence']['COUNT'] -= $old['_instance'];
+          }
+          
+          // remove fixed weekday, will be re-set to the new weekday in kolab_calendar::insert_event()
+          if (strlen($event['recurrence']['BYDAY']) == 2)
+            unset($event['recurrence']['BYDAY']);
+          if ($master['recurrence']['BYMONTH'] == $master['start']->format('n'))
+            unset($event['recurrence']['BYMONTH']);
+          
+          $success = $storage->insert_event($event);
+          break;
+        }
+
+      default:  // 'all' is default
 
         // remove some internal properties which should not be saved
         unset($event['_savemode'], $event['_fromcalendar'], $event['_identity']);
@@ -625,12 +648,6 @@ class kolab_driver extends calendar_driver
             }
         }
 
-        // save as new exception to master event
-        $master['recurrence']['EXCEPTIONS'][] = $event;
-        $success = $storage->update_event($master);
-        break;
-
-      default:  // 'all' is default
         $event['id'] = $master['id'];
         $event['uid'] = $master['uid'];
 
diff --git a/plugins/libkolab/lib/kolab_format_event.php b/plugins/libkolab/lib/kolab_format_event.php
index acf0b67..933fbee 100644
--- a/plugins/libkolab/lib/kolab_format_event.php
+++ b/plugins/libkolab/lib/kolab_format_event.php
@@ -114,7 +114,7 @@ class kolab_format_event extends kolab_format_xcal
             foreach((array)$object['recurrence']['EXCEPTIONS'] as $exception) {
                 $exevent = new kolab_format_event;
                 $exevent->set($this->compact_exception($exception, $object));  // only save differing values
-                $exevent->obj->setRecurrenceID(self::get_datetime($exception['start'], null, true), (bool)$exception['thisandfuture']);
+                $exevent->obj->setRecurrenceID(self::get_datetime($exception['start'], null, true), false);
                 $vexceptions->push($exevent->obj);
             }
             $this->obj->setExceptions($vexceptions);
@@ -190,7 +190,7 @@ class kolab_format_event extends kolab_format_xcal
         }
 
         // read exception event objects
-        if (($exceptions = $this->obj->exceptions()) && $exceptions->size()) {
+        if ($exceptions = $this->obj->exceptions()) {
             for ($i=0; $i < $exceptions->size(); $i++) {
                 if (($exobj = $exceptions->get($i))) {
                     $exception = new kolab_format_event($exobj);
@@ -200,10 +200,6 @@ class kolab_format_event extends kolab_format_xcal
                 }
             }
         }
-        // this is an exception object
-        else if ($this->obj->recurrenceID()->isValid()) {
-          $object['thisandfuture'] = $this->obj->thisAndFuture();
-        }
 
         // merge with additional data, e.g. attachments from the message
         if ($data) {
@@ -242,15 +238,25 @@ class kolab_format_event extends kolab_format_xcal
     }
 
     /**
-     * Remove some attributes from the exception container
+     * Reduce the exception container to attributes which differ from the master event
      */
     private function compact_exception($exception, $master)
     {
-      $forbidden = array('recurrence','organizer','attendees','sequence');
+      static $mandatory = array('uid','created','start');
+      static $forbidden = array('recurrence','attendees','sequence');
+
+      $out = $exception;
+      foreach ($exception as $prop => $val) {
+        if (in_array($prop, $mandatory))
+          continue;
 
-      foreach ($forbidden as $prop) {
-        if (array_key_exists($prop, $exception)) {
-          unset($exception[$prop]);
+        if (is_object($exception[$prop]) && is_a($exception[$prop], 'DateTime'))
+          $equals = $exception[$prop] <> $master[$prop];
+        else
+          $equals = $exception[$prop] == $master[$prop];
+
+        if ($equals || in_array($prop, $forbidden)) {
+          unset($out[$prop]);
         }
       }
 
@@ -262,8 +268,10 @@ class kolab_format_event extends kolab_format_xcal
      */
     private function expand_exception($exception, $master)
     {
+      static $forbidden = array('recurrence');
+
       foreach ($master as $prop => $value) {
-        if (empty($exception[$prop]) && !empty($value))
+        if (empty($exception[$prop]) && !in_array($prop, $forbidden))
           $exception[$prop] = $value;
       }
 


commit 8fb3a422f5e4af08490856b6632a1771762d1907
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:57:45 2013 +0200

    Revert "Don't attempt to serialize recurrence EXCEPTIONS"
    
    This reverts commit eeb55a32c0b876a6d215f446eea85707fa2d030b.
    
    Conflicts:
    
    	plugins/libcalendaring/libcalendaring.php

diff --git a/plugins/libcalendaring/libcalendaring.php b/plugins/libcalendaring/libcalendaring.php
index 5185f17..5a33536 100644
--- a/plugins/libcalendaring/libcalendaring.php
+++ b/plugins/libcalendaring/libcalendaring.php
@@ -732,8 +732,6 @@ class libcalendaring extends rcube_plugin
                     $val[$i] = $ex->format('Ymd\THis');
                 $val = join(',', (array)$val);
                 break;
-            case 'EXCEPTIONS':
-                continue 2;
             }
             $rrule .= $k . '=' . $val . ';';
         }


commit 02a0c84cb96775fda42e566ab393e5979c71ee0e
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:56:46 2013 +0200

    Revert "Properly export recurrence exceptions to iCal"
    
    This reverts commit e95f9bd7b6cd23e4c16fa6d0f8a54c279b4b9908.

diff --git a/plugins/calendar/lib/calendar_ical.php b/plugins/calendar/lib/calendar_ical.php
index f1716f4..e4c8e74 100644
--- a/plugins/calendar/lib/calendar_ical.php
+++ b/plugins/calendar/lib/calendar_ical.php
@@ -347,32 +347,27 @@ class calendar_ical
    * @param  boolean Directly send data to stdout instead of returning
    * @return string  Events in iCalendar format (http://tools.ietf.org/html/rfc5545)
    */
-  public function export($events, $method = null, $write = false, $recurrence_id = null)
+  public function export($events, $method = null, $write = false)
   {
-      if (!$recurrence_id) {
-        $ical = "BEGIN:VCALENDAR" . self::EOL;
-        $ical .= "VERSION:2.0" . self::EOL;
-        $ical .= "PRODID:-//Roundcube Webmail " . RCMAIL_VERSION . "//NONSGML Calendar//EN" . self::EOL;
-        $ical .= "CALSCALE:GREGORIAN" . self::EOL;
-
-        if ($method)
-          $ical .= "METHOD:" . strtoupper($method) . self::EOL;
-
-        if ($write) {
-          echo $ical;
-          $ical = '';
-        }
+      $ical = "BEGIN:VCALENDAR" . self::EOL;
+      $ical .= "VERSION:2.0" . self::EOL;
+      $ical .= "PRODID:-//Roundcube Webmail " . RCMAIL_VERSION . "//NONSGML Calendar//EN" . self::EOL;
+      $ical .= "CALSCALE:GREGORIAN" . self::EOL;
+      
+      if ($method)
+        $ical .= "METHOD:" . strtoupper($method) . self::EOL;
+        
+      if ($write) {
+        echo $ical;
+        $ical = '';
       }
-
+      
       foreach ($events as $event) {
         $vevent = "BEGIN:VEVENT" . self::EOL;
         $vevent .= "UID:" . self::escape($event['uid']) . self::EOL;
         $vevent .= $this->format_datetime("DTSTAMP", $event['changed'] ?: new DateTime(), false, true) . self::EOL;
         if ($event['sequence'])
-          $vevent .= "SEQUENCE:" . intval($event['sequence']) . self::EOL;
-        if ($recurrence_id)
-          $vevent .= $recurrence_id . self::EOL;
-        
+            $vevent .= "SEQUENCE:" . intval($event['sequence']) . self::EOL;
         // correctly set all-day dates
         if ($event['allday']) {
           $event['end'] = clone $event['end'];
@@ -394,7 +389,7 @@ class calendar_ical
         if (!empty($event['location'])) {
           $vevent .= "LOCATION:" . self::escape($event['location']) . self::EOL;
         }
-        if ($event['recurrence'] && !$recurrence_id) {
+        if ($event['recurrence']) {
           $vevent .= "RRULE:" . libcalendaring::to_rrule($event['recurrence'], self::EOL) . self::EOL;
         }
         if(!empty($event['categories'])) {
@@ -431,30 +426,18 @@ class calendar_ical
         // TODO: export attachments
         
         $vevent .= "END:VEVENT" . self::EOL;
-
-        // append recurrence exceptions
-        if ($event['recurrence']['EXCEPTIONS'] && !$recurrence_id) {
-          foreach ($event['recurrence']['EXCEPTIONS'] as $ex) {
-            $exdate = clone $event['start'];
-            $exdate->setDate($ex['start']->format('Y'), $ex['start']->format('n'), $ex['start']->format('j'));
-            $vevent .= $this->export(array($ex), null, false,
-              $this->format_datetime('RECURRENCE-ID', $exdate, $event['allday']));
-          }
-        }
-
+        
         if ($write)
           echo rcube_vcard::rfc2425_fold($vevent);
         else
           $ical .= $vevent;
       }
       
-      if (!$recurrence_id) {
-        $ical .= "END:VCALENDAR" . self::EOL;
+      $ical .= "END:VCALENDAR" . self::EOL;
       
-        if ($write) {
-          echo $ical;
-          return true;
-        }
+      if ($write) {
+        echo $ical;
+        return true;
       }
 
       // fold lines to 75 chars


commit 8ac67c4b87d9bf90b004c703b15c8deee7d1fc90
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:55:36 2013 +0200

    Revert "Keep libkolab API for event recurrence exceptions consistent for Kolab v2. The format doesn't allow to save exceptions inline, thus save them as individual events"
    
    This reverts commit 6776c49a19e597bd94597df0ec6fc13a5580e079.

diff --git a/plugins/libkolab/lib/kolab_format_event.php b/plugins/libkolab/lib/kolab_format_event.php
index 2db745c..acf0b67 100644
--- a/plugins/libkolab/lib/kolab_format_event.php
+++ b/plugins/libkolab/lib/kolab_format_event.php
@@ -190,7 +190,7 @@ class kolab_format_event extends kolab_format_xcal
         }
 
         // read exception event objects
-        if (($exceptions = $this->obj->exceptions()) && is_object($exceptions) && $exceptions->size()) {
+        if (($exceptions = $this->obj->exceptions()) && $exceptions->size()) {
             for ($i=0; $i < $exceptions->size(); $i++) {
                 if (($exobj = $exceptions->get($i))) {
                     $exception = new kolab_format_event($exobj);
diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php
index cf2c8bd..7831140 100644
--- a/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/plugins/libkolab/lib/kolab_storage_folder.php
@@ -546,9 +546,9 @@ class kolab_storage_folder
 
             // detect old Kolab 2.0 format
             if (strpos($xmlhead, '<' . $xmltype) !== false && strpos($xmlhead, 'xmlns=') === false)
-                $format_version = '2.0';
+                $format_version = 2.0;
             else
-                $format_version = '3.0'; // assume 3.0
+                $format_version = 3.0; // assume 3.0
         }
 
         // get Kolab format handler for the given type
@@ -587,6 +587,7 @@ class kolab_storage_folder
         return false;
     }
 
+
     /**
      * Save an object in this folder.
      *
@@ -657,11 +658,6 @@ class kolab_storage_folder
             }
         }
 
-        // save recurrence exceptions as individual objects due to lack of support in Kolab v2 format
-        if (kolab_storage::$version == '2.0' && $object['recurrence']['EXCEPTIONS']) {
-            $this->save_recurrence_exceptions($object, $type);
-        }
-
         // check IMAP BINARY extension support for 'file' objects
         // allow configuration to workaround bug in Cyrus < 2.4.17
         $rcmail = rcube::get_instance();
@@ -669,12 +665,6 @@ class kolab_storage_folder
 
         // generate and save object message
         if ($raw_msg = $this->build_message($object, $type, $binary)) {
-            // resolve old msguid before saving
-            if ($uid && empty($object['_msguid']) && ($msguid = $this->cache->uid2msguid($uid))) {
-                $object['_msguid'] = $msguid;
-                $object['_mailbox'] = $this->name;
-            }
-
             if (is_array($raw_msg)) {
                 $result = $this->imap->save_message($this->name, $raw_msg[0], $raw_msg[1], true, null, null, $binary);
                 @unlink($raw_msg[0]);
@@ -688,6 +678,10 @@ class kolab_storage_folder
                 $this->imap->delete_message($object['_msguid'], $object['_mailbox']);
                 $this->cache->set($object['_msguid'], false, $object['_mailbox']);
             }
+            else if ($result && $uid && ($msguid = $this->cache->uid2msguid($uid))) {
+                $this->imap->delete_message($msguid, $this->name);
+                $this->cache->set($object['_msguid'], false);
+            }
 
             // update cache with new UID
             if ($result) {
@@ -699,45 +693,6 @@ class kolab_storage_folder
         return $result;
     }
 
-    /**
-     * Save recurrence exceptions as individual objects.
-     * The Kolab v2 format doesn't allow us to save fully embedded exception objects.
-     *
-     * @param array Hash array with event properties
-     * @param string Object type
-     */
-    private function save_recurrence_exceptions(&$object, $type = null)
-    {
-        if ($object['recurrence']['EXCEPTIONS']) {
-            $exdates = array();
-            foreach ((array)$object['recurrence']['EXDATE'] as $exdate) {
-                $key = is_a($exdate, 'DateTime') ? $exdate->format('Y-m-d') : strval($exdate);
-                $exdates[$key] = 1;
-            }
-
-            // 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['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']) {
-                    $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'];
-            }
-
-            unset($object['recurrence']['EXCEPTIONS']);
-        }
-    }
 
     /**
      * Delete the specified object from this folder.


commit d363efb7909b05c6e281d9eddd3821d6bafd5a13
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:54:40 2013 +0200

    Revert "Fix saving of recurrence exceptions for v2: create unique UIDs, correctly save this-and-future instances with (modified) recurrence rule"
    
    This reverts commit eb715970740a17e8f379edfcabe0d16155e2e1b1.

diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php
index 98f8511..cf2c8bd 100644
--- a/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/plugins/libkolab/lib/kolab_storage_folder.php
@@ -717,35 +717,22 @@ class kolab_storage_folder
 
             // save every exception as individual object
             foreach((array)$object['recurrence']['EXCEPTIONS'] as $exception) {
-                $exception['uid'] = self::recurrence_exception_uid($object['uid'], $exception['start']->format('Ymd'));
+                $exception['uid'] = $object['uid'] . '-' . $exception['start']->format('Ymd');
+                $exception['recurrence-id'] = $exception['start']->format('Y-m-d');
                 $exception['sequence'] = $object['sequence'] + 1;
 
-                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);
-                        }
-                    }
+                unset($exception['recurrence'], $exception['organizer'], $exception['attendees']);
+                $this->save($exception, $type, $exception['uid']);
 
-                    // set UNTIL date if we have a thisandfuture exception
+                // set UNTIL date if we have a thisandfuture exception
+                if ($exception['thisandfuture']) {
                     $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'];
-                    unset($exception['recurrence']);
-                }
-
-                unset($exception['recurrence']['EXCEPTIONS'], $exception['_formatobj'], $exception['_msguid']);
-                $this->save($exception, $type, $exception['uid']);
+                else if (!$exdates[$exception['start']->format('Y-m-d')])
+                    $object['recurrence']['EXDATE'][] = clone $exception['start'];
             }
 
             unset($object['recurrence']['EXCEPTIONS']);
@@ -753,16 +740,6 @@ 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


commit e0e9dc290005f8b58e1c9153b8905cce277b823b
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:54:02 2013 +0200

    Revert "Set savemode to 'current' for recurrence exceptions (#1725)"
    
    This reverts commit 6719e1053dadb0d0fb6e74718233771becaf14db.

diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index 4626414..ddccd6d 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -524,7 +524,7 @@ function rcube_calendar_ui(settings)
       
       // show warning if editing a recurring event
       if (event.id && event.recurrence) {
-        var sel = event.thisandfuture ? 'future' : (event.isexception ? 'current' : 'all');
+        var sel = event.thisandfuture ? 'future' : 'all';
         $('#edit-recurring-warning').show();
         $('input.edit-recurring-savemode[value="'+sel+'"]').prop('checked', true);
       }
diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index ce6e0ec..e5af7b0 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -434,7 +434,6 @@ class kolab_calendar
         $rec_event['recurrence_id'] = $event['uid'];
         $rec_event['recurrence'] = $recurrence_rule;
         $rec_event['_instance'] = $i;
-        $rec_event['isexception'] = 1;
         $events[] = $rec_event;
 
         // found the specifically requested instance, exiting...


commit c305701742e62dda384f7e1e71239f66999bdd83
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:51:11 2013 +0200

    Revert "Add support for CUTYPE parameter for event attendees"
    
    This reverts commit 9fe8791236a5f23c27b015d82a6b7b3c806a550c.

diff --git a/plugins/libkolab/lib/kolab_format_xcal.php b/plugins/libkolab/lib/kolab_format_xcal.php
index f173a2e..b37b727 100644
--- a/plugins/libkolab/lib/kolab_format_xcal.php
+++ b/plugins/libkolab/lib/kolab_format_xcal.php
@@ -43,14 +43,6 @@ abstract class kolab_format_xcal extends kolab_format
         'CHAIR' => kolabformat::Chair,
     );
 
-    protected $cutype_map = array(
-        'INDIVIDUAL' => kolabformat::CutypeIndividual,
-        'GROUP'      => kolabformat::CutypeGroup,
-        'ROOM'       => kolabformat::CutypeRoom,
-        'RESOURCE'   => kolabformat::CutypeResource,
-        'UNKNOWN'    => kolabformat::CutypeUnknown,
-    );
-
     protected $rrule_type_map = array(
         'MINUTELY' => RecurrenceRule::Minutely,
         'HOURLY' => RecurrenceRule::Hourly,
@@ -127,7 +119,6 @@ abstract class kolab_format_xcal extends kolab_format
         }
 
         $role_map = array_flip($this->role_map);
-        $cutype_map = array_flip($this->cutype_map);
         $part_status_map = array_flip($this->part_status_map);
         $attvec = $this->obj->attendees();
         for ($i=0; $i < $attvec->size(); $i++) {
@@ -136,7 +127,6 @@ abstract class kolab_format_xcal extends kolab_format
             if ($cr->email() != $object['organizer']['email']) {
                 $object['attendees'][] = array(
                     'role' => $role_map[$attendee->role()],
-                    'cutype' => $cutype_map[$attendee->cutype()],
                     'status' => $part_status_map[$attendee->partStat()],
                     'rsvp' => $attendee->rsvp(),
                     'email' => $cr->email(),
@@ -258,7 +248,6 @@ abstract class kolab_format_xcal extends kolab_format
                 $att->setContact($cr);
                 $att->setPartStat($this->part_status_map[$attendee['status']]);
                 $att->setRole($this->role_map[$attendee['role']] ? $this->role_map[$attendee['role']] : kolabformat::Required);
-                $att->setCutype($this->cutype_map[$attendee['cutype']] ? $this->cutype_map[$attendee['cutype']] : kolabformat::CutypeIndividual);
                 $att->setRSVP((bool)$attendee['rsvp']);
 
                 if ($att->isValid()) {


commit 26f12b6873f5380224b1a82aee21e97110624117
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:50:49 2013 +0200

    Revert "Add support for URL property in xcal based objects"
    
    This reverts commit 64afdf923ec93fd6ae689c3fa06ba10138929a7f.

diff --git a/plugins/libkolab/lib/kolab_format_xcal.php b/plugins/libkolab/lib/kolab_format_xcal.php
index 868316c..f173a2e 100644
--- a/plugins/libkolab/lib/kolab_format_xcal.php
+++ b/plugins/libkolab/lib/kolab_format_xcal.php
@@ -244,12 +244,6 @@ abstract class kolab_format_xcal extends kolab_format
         $this->obj->setClassification($this->sensitivity_map[$object['sensitivity']]);
         $this->obj->setCategories(self::array2vector($object['categories']));
 
-        $vurls = new vectorurl;
-        foreach ((array)$object['url'] as $url) {
-            $vurls->push(new Url(strval($url));
-        }
-        $this->obj->setUrls($vurls);
-
         // process event attendees
         $attendees = new vectorattendee;
         foreach ((array)$object['attendees'] as $attendee) {


commit dc46469af806dba5210b64696d2a715371b9c766
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:50:31 2013 +0200

    Revert "Fix syntax error"
    
    This reverts commit 84439e3acf414cf1903cc112cab6767eaec4761b.

diff --git a/plugins/libkolab/lib/kolab_format_xcal.php b/plugins/libkolab/lib/kolab_format_xcal.php
index 4983e99..868316c 100644
--- a/plugins/libkolab/lib/kolab_format_xcal.php
+++ b/plugins/libkolab/lib/kolab_format_xcal.php
@@ -246,7 +246,7 @@ abstract class kolab_format_xcal extends kolab_format
 
         $vurls = new vectorurl;
         foreach ((array)$object['url'] as $url) {
-            $vurls->push(new Url(strval($url)));
+            $vurls->push(new Url(strval($url));
         }
         $this->obj->setUrls($vurls);
 


commit f035de27021e0ae81c21e5311c67a681d6b80db1
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:49:33 2013 +0200

    Revert "Fix usage of KolabEvent url setter/getter"
    
    This reverts commit ba7303572f1d5553900ee5f6789662fbd05f7ffc.

diff --git a/plugins/libkolab/lib/kolab_format_xcal.php b/plugins/libkolab/lib/kolab_format_xcal.php
index 1f4c894..4983e99 100644
--- a/plugins/libkolab/lib/kolab_format_xcal.php
+++ b/plugins/libkolab/lib/kolab_format_xcal.php
@@ -111,7 +111,6 @@ abstract class kolab_format_xcal extends kolab_format
             'title'       => $this->obj->summary(),
             'location'    => $this->obj->location(),
             'description' => $this->obj->description(),
-            'url'         => $this->obj->url(),
             'status'      => $status_map[$this->obj->status()],
             'sensitivity' => $sensitivity_map[$this->obj->classification()],
             'priority'    => $this->obj->priority(),
@@ -244,7 +243,12 @@ abstract class kolab_format_xcal extends kolab_format
         $this->obj->setPriority($object['priority']);
         $this->obj->setClassification($this->sensitivity_map[$object['sensitivity']]);
         $this->obj->setCategories(self::array2vector($object['categories']));
-        $this->obj->setUrl(strval($object['url']));
+
+        $vurls = new vectorurl;
+        foreach ((array)$object['url'] as $url) {
+            $vurls->push(new Url(strval($url)));
+        }
+        $this->obj->setUrls($vurls);
 
         // process event attendees
         $attendees = new vectorattendee;


commit 46dc2e93ad2feaf2a15c9bb0cb988ecae16ec75f
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Mon Jun 24 12:48:29 2013 +0200

    Revert "Fix contact fulltext indexing with new email subtypes"
    
    This reverts commit 9321a10124d1fbba87f8a25114fd583e385c2b66.

diff --git a/plugins/libkolab/lib/kolab_format_contact.php b/plugins/libkolab/lib/kolab_format_contact.php
index 9944c3d..3852fb7 100644
--- a/plugins/libkolab/lib/kolab_format_contact.php
+++ b/plugins/libkolab/lib/kolab_format_contact.php
@@ -31,7 +31,7 @@ class kolab_format_contact extends kolab_format
     protected $read_func = 'readContact';
     protected $write_func = 'writeContact';
 
-    public static $fulltext_cols = array('name', 'firstname', 'surname', 'middlename', 'email:address');
+    public static $fulltext_cols = array('name', 'firstname', 'surname', 'middlename', 'email');
 
     public $phonetypes = array(
         'home'    => Telephone::Home,
@@ -383,18 +383,7 @@ class kolab_format_contact extends kolab_format
     {
         $data = '';
         foreach (self::$fulltext_cols as $col) {
-            list($col, $field) = explode(':', $colname);
-
-            if ($field) {
-                $a = array();
-                foreach ((array)$this->data[$col] as $attr)
-                    $a[] = $attr[$field];
-                $val = join(' ', $a);
-            }
-            else {
-                $val = is_array($this->data[$col]) ? join(' ', $this->data[$col]) : $this->data[$col];
-            }
-
+            $val = is_array($this->data[$col]) ? join(' ', $this->data[$col]) : $this->data[$col];
             if (strlen($val))
                 $data .= $val . ' ';
         }





More information about the commits mailing list