123 lines
4.3 KiB
PHP
123 lines
4.3 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Inline PDF viewer plugin
|
|
*
|
|
* Render PDF files directly in the preview window
|
|
* by using the JavaScript PDF Reader pdf.js by andreasgal (http://mozilla.github.com/pdf.js)
|
|
*
|
|
* @version 0.1.2
|
|
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
|
*
|
|
* Copyright (C) 2013, Kolab Systems AG
|
|
*
|
|
* 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 pdfviewer extends rcube_plugin
|
|
{
|
|
public $task = 'mail|calendar|tasks|logout';
|
|
|
|
private $pdf_mimetypes = [
|
|
'application/pdf',
|
|
'application/x-pdf',
|
|
'application/acrobat',
|
|
'applications/vnd.pdf',
|
|
'text/pdf',
|
|
'text/x-pdf',
|
|
];
|
|
|
|
/**
|
|
* Plugin initialization
|
|
*/
|
|
public function init()
|
|
{
|
|
// pdf.js only supports IE9 or higher
|
|
$ua = new rcube_browser();
|
|
if ($ua->ie && $ua->ver < 9) {
|
|
return;
|
|
}
|
|
|
|
// extend list of mimetypes that should open in preview
|
|
$rcmail = rcube::get_instance();
|
|
if ($rcmail->action == 'preview' || $rcmail->action == 'show' || $rcmail->task == 'calendar' || $rcmail->task == 'tasks') {
|
|
$mimetypes = (array)$rcmail->config->get('client_mimetypes');
|
|
$rcmail->config->set('client_mimetypes', array_merge($mimetypes, $this->pdf_mimetypes));
|
|
}
|
|
|
|
// only use pdf.js if the browser doesn't support inline PDF rendering
|
|
if (empty($_SESSION['browser_caps']['pdf']) || $ua->opera) {
|
|
$this->add_hook('message_part_get', [$this, 'get_part']);
|
|
}
|
|
|
|
$this->add_hook('message_part_structure', [$this, 'part_structure']);
|
|
}
|
|
|
|
/**
|
|
* Handler for message attachment download
|
|
*/
|
|
public function get_part($args)
|
|
{
|
|
// redirect to viewer/viewer.html
|
|
if (!$args['download'] && $args['mimetype'] && empty($_GET['_load']) && in_array($args['mimetype'], $this->pdf_mimetypes)) {
|
|
$rcmail = rcube::get_instance();
|
|
$file_url = $_SERVER['REQUEST_URI'] . '&_load=1';
|
|
$location = $rcmail->output->asset_url($this->urlbase . 'viewer/viewer.html');
|
|
|
|
header('Location: ' . $location . '?file=' . urlencode($file_url));
|
|
exit;
|
|
}
|
|
|
|
return $args;
|
|
}
|
|
|
|
/**
|
|
* Hook for MIME message parsing.
|
|
* This allows us to fix mimetypes of PDF attachments
|
|
*/
|
|
public function part_structure($args)
|
|
{
|
|
if (!empty($args['structure']->parts)) {
|
|
foreach (array_keys($args['structure']->parts) as $i) {
|
|
$this->fix_mime_part($args['structure']->parts[$i], $args['object']);
|
|
}
|
|
} elseif ($args['structure']->mimetype != $args['mimetype']) {
|
|
$args['mimetype'] = $args['structure'];
|
|
}
|
|
|
|
return $args;
|
|
}
|
|
|
|
/**
|
|
* Helper method to fix potentially invalid mimetypes of PDF attachments
|
|
*/
|
|
private function fix_mime_part($part, $message)
|
|
{
|
|
// Some versions of Outlook create garbage Content-Type:
|
|
// application/pdf.A520491B_3BF7_494D_8855_7FAC2C6C0608
|
|
if (preg_match('/^application\/pdf.+/', $part->mimetype)) {
|
|
$part->mimetype = 'application/pdf';
|
|
}
|
|
|
|
// try to fix invalid application/octet-stream mimetypes for PDF attachments
|
|
if ($part->mimetype == 'application/octet-stream' && preg_match('/\.pdf$/', strval($part->filename))) {
|
|
$body = $message->get_part_body($part->mime_id, false, 2048);
|
|
$real_mimetype = rcube_mime::file_content_type($body, $part->filename, $part->mimetype, true, true);
|
|
if (in_array($real_mimetype, $this->pdf_mimetypes)) {
|
|
$part->mimetype = $real_mimetype;
|
|
}
|
|
}
|
|
|
|
[$part->ctype_primary, $part->ctype_secondary] = explode('/', $part->mimetype);
|
|
}
|
|
}
|