2 commits - plugins/calendar plugins/libkolab

Thomas Brüderli bruederli at kolabsys.com
Wed Mar 18 20:25:23 CET 2015


 plugins/calendar/calendar.php                   |    3 
 plugins/calendar/calendar_ui.js                 |    8 -
 plugins/calendar/drivers/kolab/kolab_driver.php |  110 +++++++++++++++++++++---
 plugins/calendar/skins/larry/calendar.css       |    2 
 plugins/libkolab/lib/kolab_format.php           |   10 +-
 5 files changed, 113 insertions(+), 20 deletions(-)

New commits:
commit 17a3783b9ad79ebcd55c104b7b4f66b1ee25cd8b
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed Mar 18 20:23:58 2015 +0100

    Allow to load attachments from old revisions + implement resting of old revisions if write permissions are granted

diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index 5f27d74..e70a4ca 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -1879,8 +1879,9 @@ class calendar extends rcube_plugin
     $event_id = rcube_utils::get_input_value('_event', rcube_utils::INPUT_GPC);
     $calendar = rcube_utils::get_input_value('_cal', rcube_utils::INPUT_GPC);
     $id       = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC);
+    $rev      = rcube_utils::get_input_value('_rev', rcube_utils::INPUT_GPC);
 
-    $event = array('id' => $event_id, 'calendar' => $calendar);
+    $event = array('id' => $event_id, 'calendar' => $calendar, 'rev' => $rev);
     $attachment = $this->driver->get_attachment($id, $event);
 
     // show part page
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index 8671b10..c1cace9 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -1620,7 +1620,13 @@ class kolab_driver extends calendar_driver
     if (!($storage = $this->get_calendar($event['calendar'])))
       return false;
 
-    $event = $storage->get_event($event['id']);
+    // get old revision of event
+    if ($event['rev']) {
+      $event = $this->get_event_revison($event, $event['rev'], true);
+    }
+    else {
+      $event = $storage->get_event($event['id']);
+    }
 
     if ($event && !empty($event['_attachments'])) {
       foreach ($event['_attachments'] as $att) {
@@ -1642,6 +1648,29 @@ class kolab_driver extends calendar_driver
     if (!($cal = $this->get_calendar($event['calendar'])))
       return false;
 
+    // get old revision of event
+    if ($event['rev']) {
+      if (empty($this->bonnie_api)) {
+        return false;
+      }
+
+      $cid = substr($id, 4);
+
+      // call Bonnie API and get the raw mime message
+      list($uid, $mailbox, $msguid) = $this->_resolve_event_identity($event);
+      if ($msg_raw = $this->bonnie_api->rawdata('event', $uid, $event['rev'], $mailbox, $msguid)) {
+        // parse the message and find the part with the matching content-id
+        $message = rcube_mime::parse_message($msg_raw);
+        foreach ((array)$message->parts as $part) {
+          if ($part->headers['content-id'] && trim($part->headers['content-id'], '<>') == $cid) {
+            return $part->body;
+          }
+        }
+      }
+
+      return false;
+    }
+
     return $cal->get_attachment_body($id, $event);
   }
 
@@ -2002,9 +2031,9 @@ class kolab_driver extends calendar_driver
       return false;
     }
 
-    list($uid, $mailbox) = $this->_resolve_event_identity($event);
+    list($uid, $mailbox, $msguid) = $this->_resolve_event_identity($event);
 
-    $result = $this->bonnie_api->changelog('event', $uid, $mailbox);
+    $result = $this->bonnie_api->changelog('event', $uid, $mailbox, $msguid);
     if (is_array($result) && $result['uid'] == $uid) {
       return $result['changes'];
     }
@@ -2028,10 +2057,10 @@ class kolab_driver extends calendar_driver
       return false;
     }
 
-    list($uid, $mailbox) = $this->_resolve_event_identity($event);
+    list($uid, $mailbox, $msguid) = $this->_resolve_event_identity($event);
 
     // call Bonnie API
-    $result = $this->bonnie_api->diff('event', $uid, $rev1, $rev2, $mailbox);
+    $result = $this->bonnie_api->diff('event', $uid, $rev1, $rev2, $mailbox, $msguid);
     if (is_array($result) && $result['uid'] == $uid) {
       $result['rev1'] = $rev1;
       $result['rev2'] = $rev2;
@@ -2140,26 +2169,29 @@ class kolab_driver extends calendar_driver
    * @return array Event object as hash array
    * @see calendar_driver::get_event_revison()
    */
-  public function get_event_revison($event, $rev)
+  public function get_event_revison($event, $rev, $internal = false)
   {
     if (empty($this->bonnie_api)) {
       return false;
     }
 
     $calid = $event['calendar'];
-    list($uid, $mailbox) = $this->_resolve_event_identity($event);
+    list($uid, $mailbox, $msguid) = $this->_resolve_event_identity($event);
 
     // call Bonnie API
-    $result = $this->bonnie_api->get('event', $uid, $rev, $mailbox);
+    $result = $this->bonnie_api->get('event', $uid, $rev, $mailbox, $msguid);
     if (is_array($result) && $result['uid'] == $uid && !empty($result['xml'])) {
       $format = kolab_format::factory('event');
       $format->load($result['xml']);
       $event = $format->to_array();
+      $format->get_attachments($event, true);
+
+      // TODO: get the right instance from a recurring event
 
       if ($format->is_valid()) {
         $event['calendar'] = $calid;
         $event['rev'] = $result['rev'];
-        return self::to_rcube_event($event);
+        return $internal ? $event : self::to_rcube_event($event);
       }
     }
 
@@ -2167,24 +2199,76 @@ class kolab_driver extends calendar_driver
   }
 
   /**
+   * Command the backend to restore a certain revision of an event.
+   * This shall replace the current event with an older version.
+   *
+   * @param mixed  UID string or hash array with event properties:
+   *        id: Event identifier
+   *  calendar: Calendar identifier
+   * @param mixed  $rev Revision number
+   *
+   * @return boolean True on success, False on failure
+   */
+  public function restore_event_revision($event, $rev)
+  {
+    if (empty($this->bonnie_api)) {
+      return false;
+    }
+
+    list($uid, $mailbox, $msguid) = $this->_resolve_event_identity($event);
+    $calendar = $this->get_calendar($event['calendar']);
+    $success = false;
+
+    if ($calendar && $calendar->storage && $calendar->editable) {
+      if ($raw_msg = $this->bonnie_api->rawdata('event', $uid, $rev, $mailbox)) {
+        $imap = $this->rc->get_storage();
+
+        // insert $raw_msg as new message
+        if ($imap->save_message($calendar->storage->name, $raw_msg, null, false)) {
+          $success = true;
+
+          // delete old revision from imap and cache
+          $imap->delete_message($msguid, $calendar->storage->name);
+          $calendar->storage->cache->set($msguid, false);
+        }
+      }
+    }
+
+    return $success;
+  }
+
+  /**
    * Helper method to resolved the given event identifier into uid and folder
    *
-   * @return array (uid,folder) tuple
+   * @return array (uid,folder,msguid) tuple
    */
   private function _resolve_event_identity($event)
   {
-    $mailbox = null;
+    $mailbox = $msguid = null;
     if (is_array($event)) {
-      $uid = $event['id'] ?: $event['uid'];
+      $uid = $event['uid'] ?: $event['id'];
       if (($cal = $this->get_calendar($event['calendar'])) && !($cal instanceof kolab_invitation_calendar)) {
         $mailbox = $cal->get_mailbox_id();
+
+        // get event object from storage in order to get the real object uid an msguid
+        if ($ev = $cal->get_event($event['id'])) {
+          $msguid = $ev['_msguid'];
+          $uid = $ev['uid'];
+        }
       }
     }
     else {
       $uid = $event;
+
+      // get event object from storage in order to get the real object uid an msguid
+      if ($ev = $this->get_event($event)) {
+        $mailbox = $ev['_mailbox'];
+        $msguid = $ev['_msguid'];
+        $uid = $ev['uid'];
+      }
     }
 
-    return array($uid, $mailbox);
+    return array($uid, $mailbox, $msguid);
   }
 
   /**
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css
index 4229b1a..c137fb8 100644
--- a/plugins/calendar/skins/larry/calendar.css
+++ b/plugins/calendar/skins/larry/calendar.css
@@ -868,7 +868,7 @@ a.miniColors-trigger {
 }
 
 #event-changelog-table .revision {
-	width: 7em;
+	width: 6em;
 }
 
 #event-changelog-table .date {
diff --git a/plugins/libkolab/lib/kolab_format.php b/plugins/libkolab/lib/kolab_format.php
index 625483b..5041dd3 100644
--- a/plugins/libkolab/lib/kolab_format.php
+++ b/plugins/libkolab/lib/kolab_format.php
@@ -626,7 +626,7 @@ abstract class kolab_format
      *
      * @param array Hash array reference to append attachment data into
      */
-    public function get_attachments(&$object)
+    public function get_attachments(&$object, $all = false)
     {
         $this->init();
 
@@ -648,6 +648,14 @@ abstract class kolab_format
                     'content'  => $content,
                 );
             }
+            else if ($all && substr($attach->uri(), 0, 4) == 'cid:') {
+                $key = $attach->uri();
+                $object['_attachments'][$key] = array(
+                    'id'       => $key,
+                    'name'     => $attach->label(),
+                    'mimetype' => $attach->mimetype(),
+                );
+            }
             else if (in_array(substr($attach->uri(), 0, 4), array('http','imap'))) {
                 $object['links'][] = $attach->uri();
             }


commit 4f2736373a89f65e544f2ae62979cd471089d7fe
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Wed Mar 18 20:23:28 2015 +0100

    Fix event changelog dialog handling

diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index b3bfbe0..ba0760f 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -1022,7 +1022,7 @@ function rcube_calendar_ui(settings)
         return false
 
       // render dialog
-      $dialog = $('#eventhistory');
+      var $dialog = $('#eventhistory');
 
       // close show dialog first
       if ($dialog.is(':ui-dialog'))
@@ -1034,7 +1034,7 @@ function rcube_calendar_ui(settings)
       };
 
       // hide and reset changelog table
-      $('div.event-dialog-message').remove();
+      $dialog.find('div.event-dialog-message').remove();
       $('#event-changelog-table').show().children('tbody')
         .html('<tr><td colspan="6"><span class="loading">'+ rcmail.gettext('loading') +'</span></td></tr>');
 
@@ -1143,8 +1143,8 @@ function rcube_calendar_ui(settings)
         change = data[i];
         accessible = change.date && change.user;
 
-        if (change.op == 'MOVE' && change.folder) {
-          op_append = ' ⇢ ' + change.folder;
+        if (change.op == 'MOVE' && change.mailbox) {
+          op_append = ' ⇢ ' + change.mailbox;
         }
         else {
           op_append = '';




More information about the commits mailing list