summaryrefslogtreecommitdiff
path: root/plugins/odfviewer/odfviewer.php
diff options
context:
space:
mode:
authorThomas <thomas@brotherli.ch>2011-12-06 07:48:24 (GMT)
committerThomas <thomas@brotherli.ch>2011-12-06 07:48:24 (GMT)
commite6aa6390dd913eea30dfd0983a498c9c5f59fcaa (patch)
treeb732ff9fd34b6c3e0893a39f6fb6de693a25c876 /plugins/odfviewer/odfviewer.php
parentfbd78c4fc57c950fcacc54b86d5de84074c266ea (diff)
downloadroundcubemail-plugins-kolab-e6aa6390dd913eea30dfd0983a498c9c5f59fcaa.tar.gz
Initial version of the webODF viewer plugin for Roundcube
Diffstat (limited to 'plugins/odfviewer/odfviewer.php')
-rw-r--r--plugins/odfviewer/odfviewer.php156
1 files changed, 156 insertions, 0 deletions
diff --git a/plugins/odfviewer/odfviewer.php b/plugins/odfviewer/odfviewer.php
new file mode 100644
index 0000000..a64cf85
--- /dev/null
+++ b/plugins/odfviewer/odfviewer.php
@@ -0,0 +1,156 @@
+<?php
+
+/**
+ * Open Document Viewer plugin
+ *
+ * Render Open Documents directly in the preview window
+ * by using the WebODF library by Tobias Hintze http://webodf.org/
+ *
+ * @version 0.2
+ * @author Thomas Bruederli <bruederli@kolabsys.com>
+ *
+ * Copyright (C) 2011, 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 odfviewer extends rcube_plugin
+{
+ public $task = 'mail|logout';
+
+ private $tempdir = 'plugins/odfviewer/files/';
+ private $tempbase = 'plugins/odfviewer/files/';
+
+ private $odf_mimetypes = array(
+ 'application/vnd.oasis.opendocument.chart',
+ 'application/vnd.oasis.opendocument.chart-template',
+ 'application/vnd.oasis.opendocument.formula',
+ 'application/vnd.oasis.opendocument.formula-template',
+ 'application/vnd.oasis.opendocument.graphics',
+ 'application/vnd.oasis.opendocument.graphics-template',
+ 'application/vnd.oasis.opendocument.presentation',
+ 'application/vnd.oasis.opendocument.presentation-template',
+ 'application/vnd.oasis.opendocument.text',
+ 'application/vnd.oasis.opendocument.text-master',
+ 'application/vnd.oasis.opendocument.text-template',
+ 'application/vnd.oasis.opendocument.spreadsheet',
+ 'application/vnd.oasis.opendocument.spreadsheet-template',
+ );
+
+ function init()
+ {
+ $this->tempdir = $this->home . '/files/';
+ $this->tempbase = $this->urlbase . 'files/';
+
+ // webODF 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 = rcmail::get_instance();
+ if ($rcmail->action == 'preview' || $rcmail->action == 'show') {
+ $mimetypes = $rcmail->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');
+ if (!is_array($mimetypes))
+ $mimetypes = explode(',', $mimetypes);
+ $rcmail->config->set('client_mimetypes', array_merge($mimetypes, $this->odf_mimetypes));
+ }
+
+ $this->add_hook('message_part_get', array($this, 'get_part'));
+ $this->add_hook('session_destroy', array($this, 'session_cleanup'));
+ }
+
+ /**
+ * Handler for message attachment download
+ */
+ function get_part($args)
+ {
+ global $IMAP, $MESSAGE;
+
+ if (!$args['download'] && $args['mimetype'] && in_array($args['mimetype'], $this->odf_mimetypes)) {
+ if (empty($_GET['_load'])) {
+ $suffix = preg_match('/(\.\w+)$/', $args['part']->filename, $m) ? $m[1] : '.odt';
+ $fn = md5(session_id() . $_SERVER['REQUEST_URI']) . $suffix;
+
+ // FIXME: copy file to disk because only apache can send the file correctly
+ $tempfn = $this->tempdir . $fn;
+ if (!file_exists($tempfn)) {
+ $fp = fopen($tempfn, 'w');
+ $IMAP->get_message_part($MESSAGE->uid, $args['part']->mime_id, $args['part'], false, $fp);
+ fclose($fp);
+
+ // remember tempfiles in session to clean up on logout
+ $_SESSION['odfviewer']['tempfiles'][] = $fn;
+ }
+
+ // send webODF viewer page
+ $html = file_get_contents($this->home . '/odf.html');
+ header("Content-Type: text/html; charset=" . RCMAIL_CHARSET);
+ echo strtr($html, array(
+ '%%DOCROOT%%' => $this->urlbase,
+ '%%DOCURL%%' => $this->tempbase . $fn, # $_SERVER['REQUEST_URI'].'&_load=1',
+ ));
+ $args['abort'] = true;
+ }
+/*
+ else {
+ if ($_SERVER['REQUEST_METHOD'] == 'HEAD') {
+ header("Content-Length: " . max(10, $args['part']->size)); # content-length has to be present
+ $args['body'] = ' '; # send empty body
+ return $args;
+ }
+ }
+*/
+ }
+
+ return $args;
+ }
+
+ /**
+ * Remove temp files opened during this session
+ */
+ function session_cleanup()
+ {
+ foreach ((array)$_SESSION['odfviewer']['tempfiles'] as $fn) {
+ @unlink($this->tempdir . $fn);
+ }
+
+ // also trigger general garbage collection because not everybody logs out properly
+ $this->gc_cleanup();
+ }
+
+ /**
+ * Garbage collector function for temp files.
+ * Remove temp files older than two days
+ */
+ function gc_cleanup()
+ {
+ $rcmail = rcmail::get_instance();
+
+ $tmp = unslashify($this->tempdir);
+ $expire = mktime() - 172800; // expire in 48 hours
+
+ if ($dir = opendir($tmp)) {
+ while (($fname = readdir($dir)) !== false) {
+ if ($fname[0] == '.')
+ continue;
+
+ if (filemtime($tmp.'/'.$fname) < $expire)
+ @unlink($tmp.'/'.$fname);
+ }
+
+ closedir($dir);
+ }
+ }
+}
+