De-duplicate attachments handling code, move it to libkolab plugin
This commit is contained in:
parent
2bd6566387
commit
5b57dd9449
12 changed files with 418 additions and 480 deletions
|
@ -1,64 +0,0 @@
|
|||
<roundcube:object name="doctype" value="html5" />
|
||||
<html>
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<roundcube:include file="/includes/links.html" />
|
||||
</head>
|
||||
<body class="extwin calendar attachmentwin">
|
||||
|
||||
<div id="header">
|
||||
<div id="topline" role="banner" aria-labelledby="aria-label-topnav">
|
||||
<div class="topleft">
|
||||
<roundcube:container name="topline-left" id="topline-left" />
|
||||
</div>
|
||||
<roundcube:container name="topline-center" id="topline-center" />
|
||||
<div class="topright">
|
||||
<roundcube:container name="topline-right" id="topline-right" />
|
||||
<roundcube:button name="close" type="link" label="close" class="closelink" onclick="self.close()" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mainscreen">
|
||||
|
||||
<h1 class="voice"><roundcube:label name="attachment" />: <roundcube:var name="env:filename" /></h1>
|
||||
|
||||
<h2 id="aria-label-toolbar" class="voice"><roundcube:label name="arialabeltoolbar" /></h2>
|
||||
<div id="attachmenttoolbar" class="toolbar fullwidth" role="toolbar" aria-labelledby="aria-label-toolbar">
|
||||
<roundcube:button command="download-attachment" type="link" class="button download disabled" classAct="button download" classSel="button download pressed" label="download" title="download" />
|
||||
<roundcube:button command="print-attachment" type="link" class="button print disabled" classAct="button print" classSel="button print pressed" label="print" title="print" />
|
||||
<roundcube:container name="toolbar" id="messagetoolbar" />
|
||||
</div>
|
||||
|
||||
<div id="mainscreencontent">
|
||||
|
||||
<div id="partheader" class="uibox listbox" role="contentinfo" aria-labelledby="aria-label-contentinfo">
|
||||
<h2 class="boxtitle" id="aria-label-contentinfo"><roundcube:label name="properties" /></h2>
|
||||
<div class="scroller">
|
||||
<roundcube:object name="plugin.attachmentcontrols" class="listing" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="attachmentcontainer" class="uibox" role="main" aria-labelledby="aria-label-messagepart">
|
||||
<h2 id="aria-label-messagepart" class="voice"><roundcube:label name="arialabelattachmentpreview" /></h2>
|
||||
<div class="iframebox">
|
||||
<roundcube:object name="plugin.attachmentframe" id="attachmentframe" frameborder="0" title="arialabelattachmentpreview" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function() {
|
||||
if (window.rcube_splitter) {
|
||||
new rcube_splitter({ id:'mailpartsplitterv', p1:'#partheader', p2:'#attachmentcontainer',
|
||||
orientation:'v', relative:true, start:226, min:150, size:12}).init();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,64 +0,0 @@
|
|||
<roundcube:object name="doctype" value="html5" />
|
||||
<html>
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<roundcube:include file="/includes/links.html" />
|
||||
</head>
|
||||
<body class="extwin calendar attachmentwin">
|
||||
|
||||
<div id="header">
|
||||
<div id="topline" role="banner" aria-labelledby="aria-label-topnav">
|
||||
<div class="topleft">
|
||||
<roundcube:container name="topline-left" id="topline-left" />
|
||||
</div>
|
||||
<roundcube:container name="topline-center" id="topline-center" />
|
||||
<div class="topright">
|
||||
<roundcube:container name="topline-right" id="topline-right" />
|
||||
<roundcube:button name="close" type="link" label="close" class="closelink" onclick="self.close()" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mainscreen">
|
||||
|
||||
<h1 class="voice"><roundcube:label name="attachment" />: <roundcube:var name="env:filename" /></h1>
|
||||
|
||||
<h2 id="aria-label-toolbar" class="voice"><roundcube:label name="arialabeltoolbar" /></h2>
|
||||
<div id="attachmenttoolbar" class="toolbar fullwidth" role="toolbar" aria-labelledby="aria-label-toolbar">
|
||||
<roundcube:button command="download-attachment" type="link" class="button download disabled" classAct="button download" classSel="button download pressed" label="download" title="download" />
|
||||
<roundcube:button command="print-attachment" type="link" class="button print disabled" classAct="button print" classSel="button print pressed" label="print" title="print" />
|
||||
<roundcube:container name="toolbar" id="messagetoolbar" />
|
||||
</div>
|
||||
|
||||
<div id="mainscreencontent">
|
||||
|
||||
<div id="partheader" class="uibox listbox" role="contentinfo" aria-labelledby="aria-label-contentinfo">
|
||||
<h2 class="boxtitle" id="aria-label-contentinfo"><roundcube:label name="properties" /></h2>
|
||||
<div class="scroller">
|
||||
<roundcube:object name="plugin.attachmentcontrols" class="listing" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="attachmentcontainer" class="uibox" role="main" aria-labelledby="aria-label-messagepart">
|
||||
<h2 id="aria-label-messagepart" class="voice"><roundcube:label name="arialabelattachmentpreview" /></h2>
|
||||
<div class="iframebox">
|
||||
<roundcube:object name="plugin.attachmentframe" id="attachmentframe" frameborder="0" title="arialabelattachmentpreview" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function() {
|
||||
if (window.rcube_splitter) {
|
||||
new rcube_splitter({ id:'mailpartsplitterv', p1:'#partheader', p2:'#attachmentcontainer',
|
||||
orientation:'v', relative:true, start:226, min:150, size:12}).init();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1325,11 +1325,13 @@ class kolab_files_engine
|
|||
|
||||
switch ($this->rc->task) {
|
||||
case 'tasks':
|
||||
libcalendaring::get_instance()->attachment_upload(tasklist::SESSION_KEY);
|
||||
$handler = new kolab_attachments_handler();
|
||||
$handler->attachment_upload(tasklist::SESSION_KEY);
|
||||
break;
|
||||
|
||||
case 'calendar':
|
||||
libcalendaring::get_instance()->attachment_upload(calendar::SESSION_KEY, 'cal-');
|
||||
$handler = new kolab_attachments_handler();
|
||||
$handler->attachment_upload(calendar::SESSION_KEY, 'cal-');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1450,19 +1450,4 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
rcmail.addEventListener('plugin.update_itip_object_status', rcube_libcalendaring.update_itip_object_status)
|
||||
.addEventListener('plugin.fetch_itip_object_status', rcube_libcalendaring.fetch_itip_object_status)
|
||||
.addEventListener('plugin.itip_message_processed', rcube_libcalendaring.itip_message_processed);
|
||||
|
||||
if (rcmail.env.action == 'get-attachment' && rcmail.gui_objects.attachmentframe) {
|
||||
rcmail.gui_objects.messagepartframe = rcmail.gui_objects.attachmentframe;
|
||||
rcmail.enable_command('image-scale', 'image-rotate', !!/^image\//.test(rcmail.env.mimetype));
|
||||
rcmail.register_command('print-attachment', function() {
|
||||
var frame = rcmail.get_frame_window(rcmail.gui_objects.attachmentframe.id);
|
||||
if (frame) frame.print();
|
||||
}, true);
|
||||
}
|
||||
|
||||
if (rcmail.env.action == 'get-attachment' && rcmail.env.attachment_download_url) {
|
||||
rcmail.register_command('download-attachment', function() {
|
||||
rcmail.location_href(rcmail.env.attachment_download_url, window);
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1074,273 +1074,6 @@ class libcalendaring extends rcube_plugin
|
|||
}
|
||||
|
||||
|
||||
/********* Attachments handling *********/
|
||||
|
||||
/**
|
||||
* Handler for attachment uploads
|
||||
*/
|
||||
public function attachment_upload($session_key, $id_prefix = '')
|
||||
{
|
||||
// Upload progress update
|
||||
if (!empty($_GET['_progress'])) {
|
||||
$this->rc->upload_progress();
|
||||
}
|
||||
|
||||
$recid = $id_prefix . rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC);
|
||||
$uploadid = rcube_utils::get_input_value('_uploadid', rcube_utils::INPUT_GPC);
|
||||
|
||||
if (!is_array($_SESSION[$session_key]) || $_SESSION[$session_key]['id'] != $recid) {
|
||||
$_SESSION[$session_key] = array();
|
||||
$_SESSION[$session_key]['id'] = $recid;
|
||||
$_SESSION[$session_key]['attachments'] = array();
|
||||
}
|
||||
|
||||
// clear all stored output properties (like scripts and env vars)
|
||||
$this->rc->output->reset();
|
||||
|
||||
if (is_array($_FILES['_attachments']['tmp_name'])) {
|
||||
foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
|
||||
// Process uploaded attachment if there is no error
|
||||
$err = $_FILES['_attachments']['error'][$i];
|
||||
|
||||
if (!$err) {
|
||||
$filename = $_FILES['_attachments']['name'][$i];
|
||||
$attachment = array(
|
||||
'path' => $filepath,
|
||||
'size' => $_FILES['_attachments']['size'][$i],
|
||||
'name' => $filename,
|
||||
'mimetype' => rcube_mime::file_content_type($filepath, $filename, $_FILES['_attachments']['type'][$i]),
|
||||
'group' => $recid,
|
||||
);
|
||||
|
||||
$attachment = $this->rc->plugins->exec_hook('attachment_upload', $attachment);
|
||||
}
|
||||
|
||||
if (!$err && $attachment['status'] && !$attachment['abort']) {
|
||||
$id = $attachment['id'];
|
||||
|
||||
// store new attachment in session
|
||||
unset($attachment['status'], $attachment['abort']);
|
||||
$this->rc->session->append($session_key . '.attachments', $id, $attachment);
|
||||
|
||||
if (($icon = $_SESSION[$session_key . '_deleteicon']) && is_file($icon)) {
|
||||
$button = html::img(array(
|
||||
'src' => $icon,
|
||||
'alt' => $this->rc->gettext('delete')
|
||||
));
|
||||
}
|
||||
else if ($_SESSION[$session_key . '_textbuttons']) {
|
||||
$button = rcube::Q($this->rc->gettext('delete'));
|
||||
}
|
||||
else {
|
||||
$button = '';
|
||||
}
|
||||
|
||||
$link_content = sprintf('<span class="attachment-name">%s</span><span class="attachment-size">(%s)</span>',
|
||||
rcube::Q($attachment['name']), $this->rc->show_bytes($attachment['size']));
|
||||
|
||||
$delete_link = html::a(array(
|
||||
'href' => "#delete",
|
||||
'class' => 'delete',
|
||||
'onclick' => sprintf("return %s.remove_from_attachment_list('rcmfile%s')", rcmail_output::JS_OBJECT_NAME, $id),
|
||||
'title' => $this->rc->gettext('delete'),
|
||||
'aria-label' => $this->rc->gettext('delete') . ' ' . $attachment['name'],
|
||||
), $button);
|
||||
|
||||
$content_link = html::a(array(
|
||||
'href' => "#load",
|
||||
'class' => 'filename',
|
||||
'onclick' => 'return false', // sprintf("return %s.command('load-attachment','rcmfile%s', this, event)", rcmail_output::JS_OBJECT_NAME, $id),
|
||||
), $link_content);
|
||||
|
||||
$content .= $_SESSION[$session_key . '_icon_pos'] == 'left' ? $delete_link.$content_link : $content_link.$delete_link;
|
||||
|
||||
$this->rc->output->command('add2attachment_list', "rcmfile$id", array(
|
||||
'html' => $content,
|
||||
'name' => $attachment['name'],
|
||||
'mimetype' => $attachment['mimetype'],
|
||||
'classname' => 'no-menu ' . rcube_utils::file2class($attachment['mimetype'], $attachment['name']),
|
||||
'complete' => true
|
||||
), $uploadid);
|
||||
}
|
||||
else { // upload failed
|
||||
if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
|
||||
$msg = $this->rc->gettext(array('name' => 'filesizeerror', 'vars' => array(
|
||||
'size' => $this->rc->show_bytes(parse_bytes(ini_get('upload_max_filesize'))))));
|
||||
}
|
||||
else if ($attachment['error']) {
|
||||
$msg = $attachment['error'];
|
||||
}
|
||||
else {
|
||||
$msg = $this->rc->gettext('fileuploaderror');
|
||||
}
|
||||
|
||||
$this->rc->output->command('display_message', $msg, 'error');
|
||||
$this->rc->output->command('remove_from_attachment_list', $uploadid);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// if filesize exceeds post_max_size then $_FILES array is empty,
|
||||
// show filesizeerror instead of fileuploaderror
|
||||
if ($maxsize = ini_get('post_max_size'))
|
||||
$msg = $this->rc->gettext(array('name' => 'filesizeerror', 'vars' => array(
|
||||
'size' => $this->rc->show_bytes(parse_bytes($maxsize)))));
|
||||
else
|
||||
$msg = $this->rc->gettext('fileuploaderror');
|
||||
|
||||
$this->rc->output->command('display_message', $msg, 'error');
|
||||
$this->rc->output->command('remove_from_attachment_list', $uploadid);
|
||||
}
|
||||
|
||||
$this->rc->output->send('iframe');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deliver an event/task attachment to the client
|
||||
* (similar as in Roundcube core program/steps/mail/get.inc)
|
||||
*/
|
||||
public function attachment_get($attachment)
|
||||
{
|
||||
ob_end_clean();
|
||||
|
||||
if ($attachment && $attachment['body']) {
|
||||
// allow post-processing of the attachment body
|
||||
$part = new rcube_message_part;
|
||||
$part->filename = $attachment['name'];
|
||||
$part->size = $attachment['size'];
|
||||
$part->mimetype = $attachment['mimetype'];
|
||||
|
||||
$plugin = $this->rc->plugins->exec_hook('message_part_get', array(
|
||||
'body' => $attachment['body'],
|
||||
'mimetype' => strtolower($attachment['mimetype']),
|
||||
'download' => !empty($_GET['_download']),
|
||||
'part' => $part,
|
||||
));
|
||||
|
||||
if ($plugin['abort'])
|
||||
exit;
|
||||
|
||||
$mimetype = $plugin['mimetype'];
|
||||
list($ctype_primary, $ctype_secondary) = explode('/', $mimetype);
|
||||
|
||||
$browser = $this->rc->output->browser;
|
||||
|
||||
// send download headers
|
||||
if ($plugin['download']) {
|
||||
header("Content-Type: application/octet-stream");
|
||||
if ($browser->ie)
|
||||
header("Content-Type: application/force-download");
|
||||
}
|
||||
else if ($ctype_primary == 'text') {
|
||||
header("Content-Type: text/$ctype_secondary");
|
||||
}
|
||||
else {
|
||||
header("Content-Type: $mimetype");
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
}
|
||||
|
||||
// display page, @TODO: support text/plain (and maybe some other text formats)
|
||||
if ($mimetype == 'text/html' && empty($_GET['_download'])) {
|
||||
$OUTPUT = new rcmail_html_page();
|
||||
// @TODO: use washtml on $body
|
||||
$OUTPUT->write($plugin['body']);
|
||||
}
|
||||
else {
|
||||
// don't kill the connection if download takes more than 30 sec.
|
||||
@set_time_limit(0);
|
||||
|
||||
$filename = $attachment['name'];
|
||||
$filename = preg_replace('[\r\n]', '', $filename);
|
||||
|
||||
if ($browser->ie && $browser->ver < 7)
|
||||
$filename = rawurlencode(abbreviate_string($filename, 55));
|
||||
else if ($browser->ie)
|
||||
$filename = rawurlencode($filename);
|
||||
else
|
||||
$filename = addcslashes($filename, '"');
|
||||
|
||||
$disposition = !empty($_GET['_download']) ? 'attachment' : 'inline';
|
||||
header("Content-Disposition: $disposition; filename=\"$filename\"");
|
||||
|
||||
echo $plugin['body'];
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// if we arrive here, the requested part was not found
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show "loading..." page in attachment iframe
|
||||
*/
|
||||
public function attachment_loading_page()
|
||||
{
|
||||
$url = str_replace('&_preload=1', '', $_SERVER['REQUEST_URI']);
|
||||
$message = $this->rc->gettext('loadingdata');
|
||||
|
||||
header('Content-Type: text/html; charset=' . RCUBE_CHARSET);
|
||||
print "<html>\n<head>\n"
|
||||
. '<meta http-equiv="refresh" content="0; url='.rcube::Q($url).'">' . "\n"
|
||||
. '<meta http-equiv="content-type" content="text/html; charset='.RCUBE_CHARSET.'">' . "\n"
|
||||
. "</head>\n<body>\n$message\n</body>\n</html>";
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template object for attachment display frame
|
||||
*/
|
||||
public function attachment_frame($attrib = array())
|
||||
{
|
||||
$mimetype = strtolower($this->attachment['mimetype']);
|
||||
list($ctype_primary, $ctype_secondary) = explode('/', $mimetype);
|
||||
|
||||
$attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary == 'text' ? '_show=' : '_preload='), $_SERVER['QUERY_STRING']);
|
||||
|
||||
$this->rc->output->add_gui_object('attachmentframe', $attrib['id']);
|
||||
|
||||
return html::iframe($attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function attachment_header($attrib = array())
|
||||
{
|
||||
$rcmail = rcmail::get_instance();
|
||||
$dl_link = strtolower($attrib['downloadlink']) == 'true';
|
||||
$dl_url = $this->rc->url(array('_frame' => null, '_download' => 1) + $_GET);
|
||||
|
||||
$table = new html_table(array('cols' => $dl_link ? 3 : 2));
|
||||
|
||||
if (!empty($this->attachment['name'])) {
|
||||
$table->add('title', rcube::Q($this->rc->gettext('filename')));
|
||||
$table->add('header', rcube::Q($this->attachment['name']));
|
||||
if ($dl_link) {
|
||||
$table->add('download-link', html::a($dl_url, rcube::Q($this->rc->gettext('download'))));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->attachment['mimetype'])) {
|
||||
$table->add('title', rcube::Q($this->rc->gettext('type')));
|
||||
$table->add('header', rcube::Q($this->attachment['mimetype']));
|
||||
}
|
||||
|
||||
if (!empty($this->attachment['size'])) {
|
||||
$table->add('title', rcube::Q($this->rc->gettext('filesize')));
|
||||
$table->add('header', rcube::Q($this->rc->show_bytes($this->attachment['size'])));
|
||||
}
|
||||
|
||||
$this->rc->output->set_env('attachment_download_url', $dl_url);
|
||||
|
||||
return $table->show($attrib);
|
||||
}
|
||||
|
||||
|
||||
/********* iTip message detection *********/
|
||||
|
||||
/**
|
||||
|
|
313
plugins/libkolab/lib/kolab_attachments_handler.php
Normal file
313
plugins/libkolab/lib/kolab_attachments_handler.php
Normal file
|
@ -0,0 +1,313 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Shared code for attachments handling in Kolab plugins
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
* @author Aleksander Machniak <machniak@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2012-2018, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class kolab_attachments_handler
|
||||
{
|
||||
private $rc;
|
||||
private $attachment;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->rc = rcmail::get_instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays attachment preview page
|
||||
*/
|
||||
public function attachment_page($attachment)
|
||||
{
|
||||
$this->attachment = $attachment;
|
||||
|
||||
$this->rc->output->add_handler('plugin.attachmentframe', array($this, 'attachment_frame'));
|
||||
$this->rc->output->add_handler('plugin.attachmentcontrols', array($this, 'attachment_header'));
|
||||
$this->rc->output->set_env('filename', $attachment['name']);
|
||||
$this->rc->output->set_env('mimetype', $attachment['mimetype']);
|
||||
$this->rc->output->send('libkolab.attachment');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for attachment uploads
|
||||
*/
|
||||
public function attachment_upload($session_key, $id_prefix = '')
|
||||
{
|
||||
// Upload progress update
|
||||
if (!empty($_GET['_progress'])) {
|
||||
$this->rc->upload_progress();
|
||||
}
|
||||
|
||||
$recid = $id_prefix . rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC);
|
||||
$uploadid = rcube_utils::get_input_value('_uploadid', rcube_utils::INPUT_GPC);
|
||||
|
||||
if (!is_array($_SESSION[$session_key]) || $_SESSION[$session_key]['id'] != $recid) {
|
||||
$_SESSION[$session_key] = array();
|
||||
$_SESSION[$session_key]['id'] = $recid;
|
||||
$_SESSION[$session_key]['attachments'] = array();
|
||||
}
|
||||
|
||||
// clear all stored output properties (like scripts and env vars)
|
||||
$this->rc->output->reset();
|
||||
|
||||
if (is_array($_FILES['_attachments']['tmp_name'])) {
|
||||
foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
|
||||
// Process uploaded attachment if there is no error
|
||||
$err = $_FILES['_attachments']['error'][$i];
|
||||
|
||||
if (!$err) {
|
||||
$filename = $_FILES['_attachments']['name'][$i];
|
||||
$attachment = array(
|
||||
'path' => $filepath,
|
||||
'size' => $_FILES['_attachments']['size'][$i],
|
||||
'name' => $filename,
|
||||
'mimetype' => rcube_mime::file_content_type($filepath, $filename, $_FILES['_attachments']['type'][$i]),
|
||||
'group' => $recid,
|
||||
);
|
||||
|
||||
$attachment = $this->rc->plugins->exec_hook('attachment_upload', $attachment);
|
||||
}
|
||||
|
||||
if (!$err && $attachment['status'] && !$attachment['abort']) {
|
||||
$id = $attachment['id'];
|
||||
|
||||
// store new attachment in session
|
||||
unset($attachment['status'], $attachment['abort']);
|
||||
$this->rc->session->append($session_key . '.attachments', $id, $attachment);
|
||||
|
||||
if (($icon = $_SESSION[$session_key . '_deleteicon']) && is_file($icon)) {
|
||||
$button = html::img(array(
|
||||
'src' => $icon,
|
||||
'alt' => $this->rc->gettext('delete')
|
||||
));
|
||||
}
|
||||
else if ($_SESSION[$session_key . '_textbuttons']) {
|
||||
$button = rcube::Q($this->rc->gettext('delete'));
|
||||
}
|
||||
else {
|
||||
$button = '';
|
||||
}
|
||||
|
||||
$link_content = sprintf('<span class="attachment-name">%s</span><span class="attachment-size">(%s)</span>',
|
||||
rcube::Q($attachment['name']), $this->rc->show_bytes($attachment['size']));
|
||||
|
||||
$delete_link = html::a(array(
|
||||
'href' => "#delete",
|
||||
'class' => 'delete',
|
||||
'onclick' => sprintf("return %s.remove_from_attachment_list('rcmfile%s')", rcmail_output::JS_OBJECT_NAME, $id),
|
||||
'title' => $this->rc->gettext('delete'),
|
||||
'aria-label' => $this->rc->gettext('delete') . ' ' . $attachment['name'],
|
||||
), $button);
|
||||
|
||||
$content_link = html::a(array(
|
||||
'href' => "#load",
|
||||
'class' => 'filename',
|
||||
'onclick' => 'return false', // sprintf("return %s.command('load-attachment','rcmfile%s', this, event)", rcmail_output::JS_OBJECT_NAME, $id),
|
||||
), $link_content);
|
||||
|
||||
$content .= $_SESSION[$session_key . '_icon_pos'] == 'left' ? $delete_link.$content_link : $content_link.$delete_link;
|
||||
|
||||
$this->rc->output->command('add2attachment_list', "rcmfile$id", array(
|
||||
'html' => $content,
|
||||
'name' => $attachment['name'],
|
||||
'mimetype' => $attachment['mimetype'],
|
||||
'classname' => 'no-menu ' . rcube_utils::file2class($attachment['mimetype'], $attachment['name']),
|
||||
'complete' => true
|
||||
), $uploadid);
|
||||
}
|
||||
else { // upload failed
|
||||
if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
|
||||
$msg = $this->rc->gettext(array('name' => 'filesizeerror', 'vars' => array(
|
||||
'size' => $this->rc->show_bytes(parse_bytes(ini_get('upload_max_filesize'))))));
|
||||
}
|
||||
else if ($attachment['error']) {
|
||||
$msg = $attachment['error'];
|
||||
}
|
||||
else {
|
||||
$msg = $this->rc->gettext('fileuploaderror');
|
||||
}
|
||||
|
||||
$this->rc->output->command('display_message', $msg, 'error');
|
||||
$this->rc->output->command('remove_from_attachment_list', $uploadid);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// if filesize exceeds post_max_size then $_FILES array is empty,
|
||||
// show filesizeerror instead of fileuploaderror
|
||||
if ($maxsize = ini_get('post_max_size'))
|
||||
$msg = $this->rc->gettext(array('name' => 'filesizeerror', 'vars' => array(
|
||||
'size' => $this->rc->show_bytes(parse_bytes($maxsize)))));
|
||||
else
|
||||
$msg = $this->rc->gettext('fileuploaderror');
|
||||
|
||||
$this->rc->output->command('display_message', $msg, 'error');
|
||||
$this->rc->output->command('remove_from_attachment_list', $uploadid);
|
||||
}
|
||||
|
||||
$this->rc->output->send('iframe');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deliver an event/task attachment to the client
|
||||
* (similar as in Roundcube core program/steps/mail/get.inc)
|
||||
*/
|
||||
public function attachment_get($attachment)
|
||||
{
|
||||
ob_end_clean();
|
||||
|
||||
if ($attachment && $attachment['body']) {
|
||||
// allow post-processing of the attachment body
|
||||
$part = new rcube_message_part;
|
||||
$part->filename = $attachment['name'];
|
||||
$part->size = $attachment['size'];
|
||||
$part->mimetype = $attachment['mimetype'];
|
||||
|
||||
$plugin = $this->rc->plugins->exec_hook('message_part_get', array(
|
||||
'body' => $attachment['body'],
|
||||
'mimetype' => strtolower($attachment['mimetype']),
|
||||
'download' => !empty($_GET['_download']),
|
||||
'part' => $part,
|
||||
));
|
||||
|
||||
if ($plugin['abort'])
|
||||
exit;
|
||||
|
||||
$mimetype = $plugin['mimetype'];
|
||||
list($ctype_primary, $ctype_secondary) = explode('/', $mimetype);
|
||||
|
||||
$browser = $this->rc->output->browser;
|
||||
|
||||
// send download headers
|
||||
if ($plugin['download']) {
|
||||
header("Content-Type: application/octet-stream");
|
||||
if ($browser->ie)
|
||||
header("Content-Type: application/force-download");
|
||||
}
|
||||
else if ($ctype_primary == 'text') {
|
||||
header("Content-Type: text/$ctype_secondary");
|
||||
}
|
||||
else {
|
||||
header("Content-Type: $mimetype");
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
}
|
||||
|
||||
// display page, @TODO: support text/plain (and maybe some other text formats)
|
||||
if ($mimetype == 'text/html' && empty($_GET['_download'])) {
|
||||
$OUTPUT = new rcmail_html_page();
|
||||
// @TODO: use washtml on $body
|
||||
$OUTPUT->write($plugin['body']);
|
||||
}
|
||||
else {
|
||||
// don't kill the connection if download takes more than 30 sec.
|
||||
@set_time_limit(0);
|
||||
|
||||
$filename = $attachment['name'];
|
||||
$filename = preg_replace('[\r\n]', '', $filename);
|
||||
|
||||
if ($browser->ie && $browser->ver < 7)
|
||||
$filename = rawurlencode(abbreviate_string($filename, 55));
|
||||
else if ($browser->ie)
|
||||
$filename = rawurlencode($filename);
|
||||
else
|
||||
$filename = addcslashes($filename, '"');
|
||||
|
||||
$disposition = !empty($_GET['_download']) ? 'attachment' : 'inline';
|
||||
header("Content-Disposition: $disposition; filename=\"$filename\"");
|
||||
|
||||
echo $plugin['body'];
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// if we arrive here, the requested part was not found
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show "loading..." page in attachment iframe
|
||||
*/
|
||||
public function attachment_loading_page()
|
||||
{
|
||||
$url = str_replace('&_preload=1', '', $_SERVER['REQUEST_URI']);
|
||||
$message = $this->rc->gettext('loadingdata');
|
||||
|
||||
header('Content-Type: text/html; charset=' . RCUBE_CHARSET);
|
||||
print "<html>\n<head>\n"
|
||||
. '<meta http-equiv="refresh" content="0; url='.rcube::Q($url).'">' . "\n"
|
||||
. '<meta http-equiv="content-type" content="text/html; charset='.RCUBE_CHARSET.'">' . "\n"
|
||||
. "</head>\n<body>\n$message\n</body>\n</html>";
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template object for attachment display frame
|
||||
*/
|
||||
public function attachment_frame($attrib = array())
|
||||
{
|
||||
$mimetype = strtolower($this->attachment['mimetype']);
|
||||
list($ctype_primary, $ctype_secondary) = explode('/', $mimetype);
|
||||
|
||||
$attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary == 'text' ? '_show=' : '_preload='), $_SERVER['QUERY_STRING']);
|
||||
|
||||
$this->rc->output->add_gui_object('attachmentframe', $attrib['id']);
|
||||
|
||||
return html::iframe($attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function attachment_header($attrib = array())
|
||||
{
|
||||
$rcmail = rcmail::get_instance();
|
||||
$dl_link = strtolower($attrib['downloadlink']) == 'true';
|
||||
$dl_url = $this->rc->url(array('_frame' => null, '_download' => 1) + $_GET);
|
||||
$table = new html_table(array('cols' => $dl_link ? 3 : 2));
|
||||
|
||||
if (!empty($this->attachment['name'])) {
|
||||
$table->add('title', rcube::Q($this->rc->gettext('filename')));
|
||||
$table->add('header', rcube::Q($this->attachment['name']));
|
||||
|
||||
if ($dl_link) {
|
||||
$table->add('download-link', html::a($dl_url, rcube::Q($this->rc->gettext('download'))));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->attachment['mimetype'])) {
|
||||
$table->add('title', rcube::Q($this->rc->gettext('type')));
|
||||
$table->add('header', rcube::Q($this->attachment['mimetype']));
|
||||
}
|
||||
|
||||
if (!empty($this->attachment['size'])) {
|
||||
$table->add('title', rcube::Q($this->rc->gettext('filesize')));
|
||||
$table->add('header', rcube::Q($this->rc->show_bytes($this->attachment['size'])));
|
||||
}
|
||||
|
||||
$this->rc->output->set_env('attachment_download_url', $dl_url);
|
||||
|
||||
return $table->show($attrib);
|
||||
}
|
||||
}
|
|
@ -64,4 +64,23 @@
|
|||
</div>
|
||||
<roundcube:endif />
|
||||
|
||||
<script>
|
||||
window.rcmail && rcmail.addEventListener('init', function(evt) {
|
||||
if (rcmail.gui_objects.attachmentframe) {
|
||||
rcmail.gui_objects.messagepartframe = rcmail.gui_objects.attachmentframe;
|
||||
rcmail.enable_command('image-scale', 'image-rotate', !!/^image\//.test(rcmail.env.mimetype));
|
||||
rcmail.register_command('print-attachment', function() {
|
||||
var frame = rcmail.get_frame_window(rcmail.gui_objects.attachmentframe.id);
|
||||
if (frame) frame.print();
|
||||
}, true);
|
||||
}
|
||||
|
||||
if (rcmail.env.attachment_download_url) {
|
||||
rcmail.register_command('download-attachment', function() {
|
||||
rcmail.location_href(rcmail.env.attachment_download_url, window);
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<roundcube:include file="includes/footer.html" />
|
|
@ -85,3 +85,54 @@ a.button.input-group-text {
|
|||
line-height: 19px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.libkolab.attachmentwin #attachmenttoolbar {
|
||||
position: relative;
|
||||
top: -6px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.libkolab.attachmentwin #attachmentcontainer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 232px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.libkolab.attachmentwin #attachmentframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.libkolab.attachmentwin #partheader {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 220px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.libkolab.attachmentwin #partheader table {
|
||||
table-layout: fixed;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.libkolab.attachmentwin #partheader table td {
|
||||
color: #666;
|
||||
padding: 4px 6px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.libkolab.attachmentwin #partheader table td.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.libkolab.attachmentwin #partheader table td.title {
|
||||
width: 60px;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<roundcube:include file="/includes/links.html" />
|
||||
</head>
|
||||
<body class="extwin tasklist attachmentwin">
|
||||
<body class="extwin libkolab attachmentwin">
|
||||
|
||||
<div id="header">
|
||||
<div id="topline" role="banner" aria-labelledby="aria-label-topnav">
|
||||
|
@ -53,10 +53,27 @@
|
|||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function() {
|
||||
if (window.rcube_splitter) {
|
||||
new rcube_splitter({ id:'mailpartsplitterv', p1:'#partheader', p2:'#attachmentcontainer',
|
||||
orientation:'v', relative:true, start:226, min:150, size:12}).init();
|
||||
}
|
||||
if (window.rcube_splitter) {
|
||||
new rcube_splitter({ id:'mailpartsplitterv', p1:'#partheader', p2:'#attachmentcontainer',
|
||||
orientation:'v', relative:true, start:226, min:150, size:12}).init();
|
||||
}
|
||||
});
|
||||
|
||||
window.rcmail && rcmail.addEventListener('init', function(evt) {
|
||||
if (rcmail.gui_objects.attachmentframe) {
|
||||
rcmail.gui_objects.messagepartframe = rcmail.gui_objects.attachmentframe;
|
||||
rcmail.enable_command('image-scale', 'image-rotate', !!/^image\//.test(rcmail.env.mimetype));
|
||||
rcmail.register_command('print-attachment', function() {
|
||||
var frame = rcmail.get_frame_window(rcmail.gui_objects.attachmentframe.id);
|
||||
if (frame) frame.print();
|
||||
}, true);
|
||||
}
|
||||
|
||||
if (rcmail.env.attachment_download_url) {
|
||||
rcmail.register_command('download-attachment', function() {
|
||||
rcmail.location_href(rcmail.env.attachment_download_url, window);
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
|
@ -102,7 +102,7 @@
|
|||
<roundcube:object name="plugin.identity_select" id="edit-identities-list" />
|
||||
</div>
|
||||
<h3 id="aria-label-attendeestable" class="voice"><roundcube:label name="tasklist.arialabeleventassignments" /></h3>
|
||||
<roundcube:object name="plugin.attendees_list" id="edit-attendees-table" class="records-table edit-attendees-table" coltitle="attendee" aria-labelledby="aria-label-attendeestable" />
|
||||
<roundcube:object name="plugin.attendees_list" id="edit-attendees-table" class="records-table edit-attendees-table no-img table-sm" coltitle="attendee" aria-labelledby="aria-label-attendeestable" />
|
||||
<roundcube:object name="plugin.attendees_form" id="edit-attendees-form" />
|
||||
<roundcube:include file="/templates/freebusylegend.html" />
|
||||
</fieldset>
|
||||
|
|
|
@ -1376,58 +1376,6 @@ div.messagetasklinks .messagetaskref input.complete {
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
.tasklist.attachmentwin #attachmenttoolbar {
|
||||
position: relative;
|
||||
top: -6px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.tasklist.attachmentwin #attachmentcontainer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 232px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.tasklist.attachmentwin #attachmentframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.tasklist.attachmentwin #partheader {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 220px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.tasklist.attachmentwin #partheader table {
|
||||
table-layout: fixed;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tasklist.attachmentwin #partheader table td {
|
||||
color: #666;
|
||||
padding: 4px 6px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tasklist.attachmentwin #partheader table td.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tasklist.attachmentwin #partheader table td.title {
|
||||
width: 60px;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.form-section label + div {
|
||||
line-height: 2;
|
||||
vertical-align: top;
|
||||
|
|
|
@ -1749,7 +1749,8 @@ class tasklist extends rcube_plugin
|
|||
*/
|
||||
public function attachment_upload()
|
||||
{
|
||||
$this->lib->attachment_upload(self::SESSION_KEY);
|
||||
$handler = new kolab_attachments_handler();
|
||||
$handler->attachment_upload(self::SESSION_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1757,9 +1758,11 @@ class tasklist extends rcube_plugin
|
|||
*/
|
||||
public function attachment_get()
|
||||
{
|
||||
$handler = new kolab_attachments_handler();
|
||||
|
||||
// show loading page
|
||||
if (!empty($_GET['_preload'])) {
|
||||
return $this->lib->attachment_loading_page();
|
||||
return $handler->attachment_loading_page();
|
||||
}
|
||||
|
||||
$task = rcube_utils::get_input_value('_t', rcube_utils::INPUT_GPC);
|
||||
|
@ -1767,22 +1770,17 @@ class tasklist extends rcube_plugin
|
|||
$id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC);
|
||||
$rev = rcube_utils::get_input_value('_rev', rcube_utils::INPUT_GPC);
|
||||
|
||||
$task = array('id' => $task, 'list' => $list, 'rev' => $rev);
|
||||
$task = array('id' => $task, 'list' => $list, 'rev' => $rev);
|
||||
$attachment = $this->driver->get_attachment($id, $task);
|
||||
|
||||
// show part page
|
||||
if (!empty($_GET['_frame'])) {
|
||||
$this->lib->attachment = $attachment;
|
||||
$this->register_handler('plugin.attachmentframe', array($this->lib, 'attachment_frame'));
|
||||
$this->register_handler('plugin.attachmentcontrols', array($this->lib, 'attachment_header'));
|
||||
$this->rc->output->set_env('filename', $attachment['name']);
|
||||
$this->rc->output->set_env('mimetype', $attachment['mimetype']);
|
||||
$this->rc->output->send('tasklist.attachment');
|
||||
$handler->attachment_page($attachment);
|
||||
}
|
||||
// deliver attachment content
|
||||
else if ($attachment) {
|
||||
$attachment['body'] = $this->driver->get_attachment_body($id, $task);
|
||||
$this->lib->attachment_get($attachment);
|
||||
$handler->attachment_get($attachment);
|
||||
}
|
||||
|
||||
// if we arrive here, the requested part was not found
|
||||
|
|
Loading…
Add table
Reference in a new issue