Finish attachment handling and display for events
This commit is contained in:
parent
c9664e2bb7
commit
1b09ae2801
10 changed files with 117 additions and 85 deletions
|
@ -1069,6 +1069,11 @@ class calendar extends rcube_plugin
|
|||
$settings['identity'] = array('name' => $identity['name'], 'email' => $identity['email'], 'emails' => ';' . join(';', $identity['emails']));
|
||||
}
|
||||
|
||||
// define list of file types which can be displayed inline
|
||||
// same as in program/steps/mail/show.inc
|
||||
$mimetypes = $this->rc->config->get('client_mimetypes', 'text/plain,text/html,text/xml,image/jpeg,image/gif,image/png,application/x-javascript,application/pdf,application/x-shockwave-flash');
|
||||
$settings['mimetypes'] = is_string($mimetypes) ? explode(',', $mimetypes) : (array)$mimetypes;
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
|
@ -1534,12 +1539,8 @@ class calendar extends rcube_plugin
|
|||
}
|
||||
|
||||
ob_end_clean();
|
||||
send_nocacheing_headers();
|
||||
|
||||
if (isset($_SESSION['calendar_attachment']))
|
||||
$attachment = $_SESSION['calendar_attachment'];
|
||||
else
|
||||
$attachment = $_SESSION['calendar_attachment'] = $this->driver->get_attachment($id, $event);
|
||||
$attachment = $GLOBALS['calendar_attachment'] = $this->driver->get_attachment($id, $event);
|
||||
|
||||
// show part page
|
||||
if (!empty($_GET['_frame'])) {
|
||||
|
@ -1550,12 +1551,16 @@ class calendar extends rcube_plugin
|
|||
exit;
|
||||
}
|
||||
|
||||
$this->rc->session->remove('calendar_attachment');
|
||||
|
||||
if ($attachment) {
|
||||
$mimetype = strtolower($attachment['mimetype']);
|
||||
list($ctype_primary, $ctype_secondary) = explode('/', $mimetype);
|
||||
|
||||
$body = $this->driver->get_attachment_body($id, $event);
|
||||
|
||||
// TODO: allow post-processing of the attachment body
|
||||
//$plugin = $RCMAIL->plugins->exec_hook('message_part_get',
|
||||
// array('uid' => $MESSAGE->uid, 'id' => $part->mime_id, 'mimetype' => $mimetype, 'part' => $part, 'download' => !empty($_GET['_download'])));
|
||||
|
||||
$browser = $this->rc->output->browser;
|
||||
|
||||
// send download headers
|
||||
|
@ -1573,8 +1578,6 @@ class calendar extends rcube_plugin
|
|||
header("Content-Transfer-Encoding: binary");
|
||||
}
|
||||
|
||||
$body = $this->driver->get_attachment_body($id, $event);
|
||||
|
||||
// display page, @TODO: support text/plain (and maybe some other text formats)
|
||||
if ($mimetype == 'text/html' && empty($_GET['_download'])) {
|
||||
$OUTPUT = new rcube_html_page();
|
||||
|
@ -1614,7 +1617,7 @@ class calendar extends rcube_plugin
|
|||
*/
|
||||
public function attachment_frame($attrib)
|
||||
{
|
||||
$attachment = $_SESSION['calendar_attachment'];
|
||||
$attachment = $GLOBALS['calendar_attachment'];
|
||||
|
||||
$mimetype = strtolower($attachment['mimetype']);
|
||||
list($ctype_primary, $ctype_secondary) = explode('/', $mimetype);
|
||||
|
|
|
@ -260,7 +260,7 @@ function rcube_calendar_ui(settings)
|
|||
var qstring = '_id='+urlencode(att.id)+'&_event='+urlencode(event.recurrence_id||event.id)+'&_cal='+urlencode(event.calendar);
|
||||
|
||||
// open attachment in frame if it's of a supported mimetype
|
||||
if (id && att.mimetype && $.inArray(att.mimetype, rcmail.mimetypes)>=0) {
|
||||
if (id && att.mimetype && $.inArray(att.mimetype, settings.mimetypes)>=0) {
|
||||
rcmail.attachment_win = window.open(rcmail.env.comm_path+'&_action=get-attachment&'+qstring+'&_frame=1', 'rcubeeventattachment');
|
||||
if (rcmail.attachment_win) {
|
||||
window.setTimeout(function() { rcmail.attachment_win.focus(); }, 10);
|
||||
|
@ -268,6 +268,8 @@ function rcube_calendar_ui(settings)
|
|||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
rcmail.goto_url('get-attachment', qstring+'&_download=1', false);
|
||||
};
|
||||
|
||||
|
|
|
@ -169,14 +169,6 @@ class kolab_calendar
|
|||
return $this->storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the attachment body
|
||||
*/
|
||||
public function get_attachment_body($id)
|
||||
{
|
||||
return $this->storage->getAttachment($id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for a single event object
|
||||
|
@ -427,15 +419,15 @@ class kolab_calendar
|
|||
if ($record['end'] <= $record['start'] && $record['allday'])
|
||||
$record['end'] = $record['start'] + 3600;
|
||||
|
||||
if (!empty($rec['_attachments'])) {
|
||||
foreach ($rec['_attachments'] as $name => $attachment) {
|
||||
// @TODO: 'type' and 'key' are the only supported (no 'size')
|
||||
$attachments[] = array(
|
||||
'id' => $attachment['key'],
|
||||
'mimetype' => $attachment['type'],
|
||||
'name' => $name,
|
||||
);
|
||||
if (!empty($record['_attachments'])) {
|
||||
foreach ($record['_attachments'] as $name => $attachment) {
|
||||
if ($attachment !== false) {
|
||||
$attachment['name'] = $name;
|
||||
$attachments[] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
$record['attachments'] = $attachments;
|
||||
}
|
||||
|
||||
$sensitivity_map = array_flip($this->sensitivity_map);
|
||||
|
@ -461,28 +453,31 @@ class kolab_calendar
|
|||
|
||||
// in Horde attachments are indexed by name
|
||||
$object['_attachments'] = array();
|
||||
if (!empty($event['attachments'])) {
|
||||
if (is_array($event['attachments'])) {
|
||||
$collisions = array();
|
||||
foreach ($event['attachments'] as $idx => $attachment) {
|
||||
// Roundcube ID has nothing to do with Horde ID, remove it
|
||||
if ($attachment['content'])
|
||||
unset($attachment['id']);
|
||||
|
||||
// Horde code assumes that there will be no more than
|
||||
// one file with the same name: make filenames unique
|
||||
$filename = $attachment['name'];
|
||||
if ($collisions[$filename]++) {
|
||||
$ext = preg_match('/(\.[a-z0-9]{1,6})$/i', $filename, $m) ? $m[1] : null;
|
||||
$attachment['name'] = basename($filename, $ext) . '-' . $collisions[$filename] . $ext;
|
||||
// flagged for deletion => set to false
|
||||
if ($attachment['_deleted']) {
|
||||
$object['_attachments'][$attachment['name']] = false;
|
||||
}
|
||||
else {
|
||||
// Horde code assumes that there will be no more than
|
||||
// one file with the same name: make filenames unique
|
||||
$filename = $attachment['name'];
|
||||
if ($collisions[$filename]++) {
|
||||
$ext = preg_match('/(\.[a-z0-9]{1,6})$/i', $filename, $m) ? $m[1] : null;
|
||||
$attachment['name'] = basename($filename, $ext) . '-' . $collisions[$filename] . $ext;
|
||||
}
|
||||
|
||||
// set type parameter
|
||||
if ($attachment['mimetype'])
|
||||
$attachment['type'] = $attachment['mimetype'];
|
||||
|
||||
$object['_attachments'][$attachment['name']] = $attachment;
|
||||
unset($event['attachments'][$idx]);
|
||||
$object['_attachments'][$attachment['name']] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
unset($event['attachments']);
|
||||
}
|
||||
|
||||
// translate sensitivity property
|
||||
|
|
|
@ -579,7 +579,7 @@ class kolab_driver extends calendar_driver
|
|||
if (!empty($old['attachments'])) {
|
||||
foreach ($old['attachments'] as $idx => $att) {
|
||||
if ($att['id'] == $attachment) {
|
||||
unset($old['attachments'][$idx]);
|
||||
$old['attachments'][$idx]['_deleted'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -592,12 +592,12 @@ class kolab_driver extends calendar_driver
|
|||
// skip entries without content (could be existing ones)
|
||||
if (!$attachment['data'] && !$attachment['path'])
|
||||
continue;
|
||||
// we'll read file contacts into memory, Horde/Kolab classes does the same
|
||||
// So we cannot save memory, rcube_imap class can do this better
|
||||
|
||||
$attachments[] = array(
|
||||
'name' => $attachment['name'],
|
||||
'type' => $attachment['mimetype'],
|
||||
'content' => $attachment['data'] ? $attachment['data'] : file_get_contents($attachment['path']),
|
||||
'mimetype' => $attachment['mimetype'],
|
||||
'content' => $attachment['data'],
|
||||
'path' => $attachment['path'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ class kolab_driver extends calendar_driver
|
|||
// copy attachment data to new event
|
||||
foreach ((array)$event['attachments'] as $idx => $attachment) {
|
||||
if (!$attachment['data'])
|
||||
$attachment['data'] = $fromcalendar->get_attachment_body($attachment['id']);
|
||||
$attachment['data'] = $fromcalendar->get_attachment_body($attachment['id'], $event);
|
||||
}
|
||||
|
||||
$success = $storage->insert_event($event);
|
||||
|
@ -875,13 +875,14 @@ class kolab_driver extends calendar_driver
|
|||
|
||||
/**
|
||||
* Get attachment body
|
||||
* @see calendar_driver::get_attachment_body()
|
||||
*/
|
||||
public function get_attachment_body($id, $event)
|
||||
{
|
||||
if (!($storage = $this->calendars[$event['calendar']]))
|
||||
if (!($cal = $this->calendars[$event['calendar']]))
|
||||
return false;
|
||||
|
||||
return $storage->get_attachment_body($id);
|
||||
return $cal->storage->get_attachment($event['id'], $id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -657,13 +657,13 @@ class calendar_ui
|
|||
|
||||
if (!empty($this->cal->attachment['name'])) {
|
||||
$table->add('title', Q(rcube_label('filename')));
|
||||
$table->add(null, Q($this->cal->attachment['name']));
|
||||
$table->add(null, '[' . html::a('?'.str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING']), Q(rcube_label('download'))) . ']');
|
||||
$table->add('header', Q($this->cal->attachment['name']));
|
||||
$table->add('download-link', html::a('?'.str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING']), Q(rcube_label('download'))));
|
||||
}
|
||||
|
||||
if (!empty($this->cal->attachment['size'])) {
|
||||
$table->add('title', Q(rcube_label('filesize')));
|
||||
$table->add(null, Q(show_bytes($this->cal->attachment['size'])));
|
||||
$table->add('header', Q(show_bytes($this->cal->attachment['size'])));
|
||||
}
|
||||
|
||||
return $table->show($attrib);
|
||||
|
|
|
@ -286,39 +286,45 @@ a.miniColors-trigger {
|
|||
|
||||
#attachmentcontainer {
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
left: 20px;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
top: 60px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
#attachmentframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #999999;
|
||||
background-color: #F9F9F9;
|
||||
border: 0;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#partheader {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 220px;
|
||||
right: 20px;
|
||||
height: 40px;
|
||||
position: relative;
|
||||
padding: 3px 0;
|
||||
background: #f9f9f9;
|
||||
background: -moz-linear-gradient(top, #fff 0%, #e9e9e9 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fff), color-stop(100%,#e9e9e9));
|
||||
background: -o-linear-gradient(top, #fff 0%, #e9e9e9 100%);
|
||||
background: -ms-linear-gradient(top, #fff 0%, #e9e9e9 100%);
|
||||
background: linear-gradient(top, #fff 0%, #e9e9e9 100%);
|
||||
}
|
||||
|
||||
#partheader table td {
|
||||
padding-left: 2px;
|
||||
padding-right: 4px;
|
||||
vertical-align: middle;
|
||||
font-size: 11px;
|
||||
color: #666;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
#partheader table td.title {
|
||||
color: #666;
|
||||
#partheader table td.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#partheader table td.title a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#edit-attachments {
|
||||
margin-top: 0.6em;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</div>
|
||||
|
||||
<div id="attachmentcontainer" class="uibox">
|
||||
<roundcube:object name="plugin.attachmentframe" id="attachmentframe" style="width:100%; height:100%" />
|
||||
<roundcube:object name="plugin.attachmentframe" id="attachmentframe" class="header-table" style="width:100%" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -1057,7 +1057,7 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
if ($record['photo'] && strlen($record['photo']) < 255 && ($att = $record['_attachments'][$record['photo']])) {
|
||||
// only fetch photo content if requested
|
||||
if ($this->action == 'photo')
|
||||
$record['photo'] = $att['content'] ? $att['content'] : $this->storagefolder->get_attachment($record['uid'], $att['key']);
|
||||
$record['photo'] = $att['content'] ? $att['content'] : $this->storagefolder->get_attachment($record['uid'], $att['id']);
|
||||
}
|
||||
|
||||
// truncate publickey value for display
|
||||
|
@ -1123,7 +1123,7 @@ class rcube_kolab_contacts extends rcube_addressbook
|
|||
if ($contact['photo']) {
|
||||
$attkey = 'photo.attachment';
|
||||
$contact['_attachments'][$attkey] = array(
|
||||
'type' => rc_image_content_type($contact['photo']),
|
||||
'mimetype' => rc_image_content_type($contact['photo']),
|
||||
'content' => preg_match('![^a-z0-9/=+-]!i', $contact['photo']) ? $contact['photo'] : base64_decode($contact['photo']),
|
||||
);
|
||||
$contact['photo'] = $attkey;
|
||||
|
|
|
@ -280,7 +280,17 @@ class kolab_format_event extends kolab_format
|
|||
}
|
||||
$this->obj->setAlarms($valarms);
|
||||
|
||||
// TODO: save attachments
|
||||
// save attachments
|
||||
$vattach = new vectorattachment;
|
||||
foreach ((array)$object['_attachments'] as $name => $attr) {
|
||||
if (empty($attr))
|
||||
continue;
|
||||
$attach = new Attachment;
|
||||
$attach->setLabel($name);
|
||||
$attach->setUri('cid:' . $name, $attr['mimetype']);
|
||||
$vattach->push($attach);
|
||||
}
|
||||
$this->obj->setAttachments($vattach);
|
||||
|
||||
// cache this data
|
||||
unset($object['_formatobj']);
|
||||
|
@ -425,7 +435,22 @@ class kolab_format_event extends kolab_format
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: handle attachments
|
||||
// handle attachments
|
||||
$vattach = $this->obj->attachments();
|
||||
for ($i=0; $i < $vattach->size(); $i++) {
|
||||
$attach = $vattach->get($i);
|
||||
|
||||
// skip cid: attachments which are mime message parts handled by kolab_storage_folder
|
||||
if (substr($attach->uri(), 0, 4) != 'cid') {
|
||||
$name = $attach->label();
|
||||
$data = $attach->data();
|
||||
$object['_attachments'][$name] = array(
|
||||
'mimetype' => $attach->mimetype(),
|
||||
'size' => strlen($data),
|
||||
'content' => $data,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->data = $object;
|
||||
return $this->data;
|
||||
|
|
|
@ -350,8 +350,8 @@ class kolab_storage_folder
|
|||
}
|
||||
else if ($part->filename) {
|
||||
$attachments[$part->filename] = array(
|
||||
'key' => $part->mime_id,
|
||||
'type' => $part->mimetype,
|
||||
'id' => $part->mime_id,
|
||||
'mimetype' => $part->mimetype,
|
||||
'size' => $part->size,
|
||||
);
|
||||
}
|
||||
|
@ -388,13 +388,10 @@ class kolab_storage_folder
|
|||
}
|
||||
|
||||
if ($format->is_valid()) {
|
||||
if ($formatobj)
|
||||
return $format;
|
||||
|
||||
$object = $format->to_array();
|
||||
$object['_msguid'] = $msguid;
|
||||
$object['_mailbox'] = $this->name;
|
||||
$object['_attachments'] = $attachments;
|
||||
$object['_attachments'] = array_merge((array)$object['_attachments'], $attachments);
|
||||
$object['_formatobj'] = $format;
|
||||
|
||||
$this->objcache[$msguid] = $object;
|
||||
|
@ -425,8 +422,8 @@ class kolab_storage_folder
|
|||
$object['_attachments'][$name] = $old['_attachments'][$name];
|
||||
}
|
||||
// load photo.attachment from old Kolab2 format to be directly embedded in xcard block
|
||||
if ($name == 'photo.attachment' && !isset($object['photo']) && !$object['_attachments'][$name]['content'] && $att['key']) {
|
||||
$object['photo'] = $this->get_attachment($object['_msguid'], $att['key'], $object['_mailbox']);
|
||||
if ($name == 'photo.attachment' && !isset($object['photo']) && !$object['_attachments'][$name]['content'] && $att['id']) {
|
||||
$object['photo'] = $this->get_attachment($object['_msguid'], $att['id'], $object['_mailbox']);
|
||||
unset($object['_attachments'][$name]);
|
||||
}
|
||||
}
|
||||
|
@ -601,12 +598,15 @@ class kolab_storage_folder
|
|||
// save object attachments as separate parts
|
||||
// TODO: optimize memory consumption by using tempfiles for transfer
|
||||
foreach ((array)$object['_attachments'] as $name => $att) {
|
||||
if (empty($att['content']) && !empty($att['key'])) {
|
||||
if (empty($att['content']) && !empty($att['id'])) {
|
||||
$msguid = !empty($object['_msguid']) ? $object['_msguid'] : $object['uid'];
|
||||
$att['content'] = $this->get_attachment($msguid, $att['key'], $object['_mailbox']);
|
||||
$att['content'] = $this->get_attachment($msguid, $att['id'], $object['_mailbox']);
|
||||
}
|
||||
if (!empty($att['content'])) {
|
||||
$mime->addAttachment($att['content'], $att['type'], $name, false);
|
||||
$mime->addAttachment($att['content'], $att['mimetype'], $name, false);
|
||||
}
|
||||
else if (!empty($att['path'])) {
|
||||
$mime->addAttachment($att['path'], $att['mimetype'], $name, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -681,7 +681,7 @@ class kolab_storage_folder
|
|||
*/
|
||||
public function getOwner()
|
||||
{
|
||||
console("Call to deprecated method kolab_storage_folder::getOwner()");
|
||||
PEAR::raiseError("Call to deprecated method kolab_storage_folder::getOwner()");
|
||||
return $this->get_owner();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue