diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 0e61615f..05cee6c8 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -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); diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index f7683cff..063cbf5a 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -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); }; diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php index 3a2a02af..77631591 100644 --- a/plugins/calendar/drivers/kolab/kolab_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_calendar.php @@ -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 diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index 7744dc03..aea6783c 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -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); } /** diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php index c740e4aa..ba8cc83d 100644 --- a/plugins/calendar/lib/calendar_ui.php +++ b/plugins/calendar/lib/calendar_ui.php @@ -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); diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css index a95d0fcb..cba1149c 100644 --- a/plugins/calendar/skins/larry/calendar.css +++ b/plugins/calendar/skins/larry/calendar.css @@ -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; } diff --git a/plugins/calendar/skins/larry/templates/attachment.html b/plugins/calendar/skins/larry/templates/attachment.html index 439afd40..4d4789da 100644 --- a/plugins/calendar/skins/larry/templates/attachment.html +++ b/plugins/calendar/skins/larry/templates/attachment.html @@ -26,7 +26,7 @@