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

This commit is contained in:
Thomas Bruederli 2015-03-18 20:23:58 +01:00
parent 4f2736373a
commit 17a3783b9a
4 changed files with 109 additions and 16 deletions

View file

@ -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

View file

@ -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,51 +2169,106 @@ 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);
}
}
return false;
}
/**
* 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);
}
/**

View file

@ -868,7 +868,7 @@ a.miniColors-trigger {
}
#event-changelog-table .revision {
width: 7em;
width: 6em;
}
#event-changelog-table .date {

View file

@ -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();
}