plugins/zipdownload/CHANGELOG
New file @@ -0,0 +1,34 @@ Roundcube Webmail ZipDownload ============================= 2012-09-20 ========== * Added style for new Larry skin * Made plugin work with 0.8 version of Roundcube * Save attachments to temp files before adding to zip archive (memory!) 2011 03 12 ========== * Convert charset for filenames inside zip 2010 08 30 ========== * Get all messages in folder, not just the first page 2010 08 12 ========== * Use $.inArray() instead of Array.indexOf() 2010 08 07 ========== * Add the ability to download a folder as zip * Add the ability to download selection of messages as zip * Add config file to control download options 2010 05 29 ========== * Remove tnef_decode, now done by message class (r3680) 2010 02 21 ========== * First version plugins/zipdownload/README
New file @@ -0,0 +1,35 @@ Roundcube Webmail ZipDownload ============================= This plugin adds an option to download all attachments to a message in one zip file, when a message has multiple attachments. The plugin also allows the download of a selection of messages in 1 zip file and the download of entire folders. Requirements ============ * php_zip extension (including ZipArchive class) Either install it via PECL or for PHP >= 5.2 compile with --enable-zip option License ======= This plugin is released under the GNU General Public License Version 3 or later (http://www.gnu.org/licenses/gpl.html). Even if skins might contain some programming work, they are not considered as a linked part of the plugin and therefore skins DO NOT fall under the provisions of the GPL license. See the README file located in the core skins folder for details on the skin license. Install ======= * Place this plugin folder into plugins directory of Roundcube * Add zipdownload to $rcmail_config['plugins'] in your Roundcube config NB: When downloading the plugin from GitHub you will need to create a directory called zipdownload and place the files in there, ignoring the root directory in the downloaded archive Config ====== The default config file is plugins/zipdownload/config.inc.php.dist Rename this to plugins/zipdownload/config.inc.php plugins/zipdownload/config.inc.php
New file @@ -0,0 +1,21 @@ <?php /** * ZipDownload configuration file */ // Zip attachments // Only show the link when there are more than this many attachments // -1 to prevent downloading of attachments as zip $rcmail_config['zipdownload_attachments'] = 1; // Zip entire folders $rcmail_config['zipdownload_folder'] = true; // Zip selection of messages $rcmail_config['zipdownload_selection'] = true; // Charset to use for filenames inside the zip # $rcmail_config['zipdownload_charset'] = 'ASCII'; ?> plugins/zipdownload/config.inc.php.dist
New file @@ -0,0 +1,21 @@ <?php /** * ZipDownload configuration file */ // Zip attachments // Only show the link when there are more than this many attachments // -1 to prevent downloading of attachments as zip $rcmail_config['zipdownload_attachments'] = 1; // Zip entire folders $rcmail_config['zipdownload_folder'] = false; // Zip selection of messages $rcmail_config['zipdownload_selection'] = false; // Charset to use for filenames inside the zip $rcmail_config['zipdownload_charset'] = 'ISO-8859-1'; ?> plugins/zipdownload/localization/ca_ES.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Drakon */ $labels = array(); $labels['downloadall'] = 'Descarregar tots els adjunts'; $labels['downloadfolder'] = 'Descarregar carpeta'; $messages = array(); ?> plugins/zipdownload/localization/cs_CZ.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Tomáš Šafařík */ $labels = array(); $labels['downloadall'] = 'Stáhnout všechny přílohy'; $labels['downloadfolder'] = 'Stáhnout složku'; $messages = array(); ?> plugins/zipdownload/localization/da_DK.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: John Loft Christiansen */ $labels = array(); $labels['downloadall'] = 'Download alle som .zip-fil'; $labels['downloadfolder'] = 'Download folder som .zip-fil'; $messages = array(); ?> plugins/zipdownload/localization/de_CH.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: jedix */ $labels = array(); $labels['downloadall'] = 'Alle Anhänge herunterladen'; $labels['downloadfolder'] = 'Ordner herunterladen'; $messages = array(); ?> plugins/zipdownload/localization/de_DE.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: jedix */ $labels = array(); $labels['downloadall'] = 'Alle Anhänge herunterladen'; $labels['downloadfolder'] = 'Ordner herunterladen'; $messages = array(); ?> plugins/zipdownload/localization/en_GB.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Philip Weir */ $labels = array(); $labels['downloadall'] = 'Download all attachments'; $labels['downloadfolder'] = 'Download folder'; $messages = array(); ?> plugins/zipdownload/localization/en_US.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Philip Weir */ $labels = array(); $labels['downloadall'] = 'Download all attachments'; $labels['downloadfolder'] = 'Download folder'; $messages = array(); ?> plugins/zipdownload/localization/es_AR.inc
New file @@ -0,0 +1,9 @@ <?php /* Author: gboksar */ $labels = array(); $labels['downloadall'] = 'Descargar Todo'; $messages = array(); ?> plugins/zipdownload/localization/es_ES.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: David Garabana Barro */ $labels = array(); $labels['downloadall'] = 'Descargar todos los adjuntos'; $labels['downloadfolder'] = 'Descargar carpeta'; $messages = array(); ?> plugins/zipdownload/localization/et_EE.inc
New file @@ -0,0 +1,9 @@ <?php /* Author: Henrik Pihl */ $labels = array(); $labels['downloadall'] = 'Laadi alla kõik manused'; $messages = array(); ?> plugins/zipdownload/localization/fr_FR.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Olivier Le Brouster */ $labels = array(); $labels['downloadall'] = 'Télécharger toutes les pièces jointes'; $labels['downloadfolder'] = 'Télécharger le répertoire'; $messages = array(); ?> plugins/zipdownload/localization/gl_ES.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: David Garabana Barro */ $labels = array(); $labels['downloadall'] = 'Descargar tódolos adxuntos'; $labels['downloadfolder'] = 'Descargar o cartafol'; $messages = array(); ?> plugins/zipdownload/localization/hu_HU.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Németh János */ $labels = array(); $labels['downloadall'] = 'Összes csatolmány letöltése'; $labels['downloadfolder'] = 'Könyvtár letöltése'; $messages = array(); ?> plugins/zipdownload/localization/it_IT.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Roberto Puzzanghera */ $labels = array(); $labels['downloadall'] = 'Scarica tutti gli allegati'; $labels['downloadfolder'] = 'Scarica cartella'; $messages = array(); ?> plugins/zipdownload/localization/nl_NL.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Wouter Kevenaar*/ $labels = array(); $labels['downloadall'] = 'Alle bijlagen downloaden'; $labels['downloadfolder'] = 'Map downloaden'; $messages = array(); ?> plugins/zipdownload/localization/pl_PL.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: DZIOBAK */ $labels = array(); $labels['downloadall'] = 'Pobierz wszystkie jako ZIP'; $labels['downloadfolder'] = 'Pobierz folder'; $messages = array(); ?> plugins/zipdownload/localization/pt_BR.inc
New file @@ -0,0 +1,9 @@ <?php /* Author: Alexandre Gorges */ $labels = array(); $labels['downloadall'] = 'Baixar todos os anexos'; $messages = array(); ?> plugins/zipdownload/localization/ro_RO.inc
New file @@ -0,0 +1,9 @@ <?php /* Author: Ovidiu Bica */ $labels = array(); $labels['downloadall'] = 'Descarca toate atasamentele.'; $messages = array(); ?> plugins/zipdownload/localization/ru_RU.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Peter Zotov */ $labels = array(); $labels['downloadall'] = 'Загрузить все вложения'; $labels['downloadfolder'] = 'Загрузить каталог'; $messages = array(); ?> plugins/zipdownload/localization/tr_TR.inc
New file @@ -0,0 +1,10 @@ <?php /* Author: Mustafa Icer */ $labels = array(); $labels['downloadall'] = 'Tüm ek dosyaları indir'; $labels['downloadfolder'] = 'klasörü indir'; $messages = array(); ?> plugins/zipdownload/package.xml
New file @@ -0,0 +1,89 @@ <?xml version="1.0" encoding="UTF-8"?> <package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>zipdownload</name> <channel>pear.roundcube.net</channel> <summary>Download multiple attachments or messages in one zip file</summary> <description>Adds an option to download all attachments to a message in one zip file, when a message has multiple attachments. Also allows the download of a selection of messages in one zip file and the download of entire folders.</description> <lead> <name>Philip Weir</name> <user>JohnDoh</user> <email>roundcube@tehinterweb.co.uk</email> <active>no</active> </lead> <lead> <name>Thomas Bruederli</name> <user>bruederli</user> <email>roundcube@gmail.com</email> <active>yes</active> </lead> <date>2012-09-20</date> <time>19:16:00</time> <version> <release>2.0</release> <api>2.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license> <notes>Repo only</notes> <contents> <dir baseinstalldir="/" name="/"> <file name="zipdownload.php" role="php"> <tasks:replace from="@name@" to="name" type="package-info"/> <tasks:replace from="@package_version@" to="version" type="package-info"/> </file> <file name="zipdownload.js" role="data"> <tasks:replace from="@name@" to="name" type="package-info"/> <tasks:replace from="@package_version@" to="version" type="package-info"/> </file> <file name="config.inc.php.dist" role="data"/> <file name="CHANGELOG" role="data"/> <file name="README" role="data"/> <file name="localization/ca_ES.inc" role="data"/> <file name="localization/cs_CZ.inc" role="data"/> <file name="localization/da_DK.inc" role="data"/> <file name="localization/de_CH.inc" role="data"/> <file name="localization/de_DE.inc" role="data"/> <file name="localization/en_GB.inc" role="data"/> <file name="localization/en_US.inc" role="data"/> <file name="localization/es_AR.inc" role="data"/> <file name="localization/es_ES.inc" role="data"/> <file name="localization/et_EE.inc" role="data"/> <file name="localization/fr_FR.inc" role="data"/> <file name="localization/gl_ES.inc" role="data"/> <file name="localization/hu_HU.inc" role="data"/> <file name="localization/it_IT.inc" role="data"/> <file name="localization/nl_NL.inc" role="data"/> <file name="localization/pl_PL.inc" role="data"/> <file name="localization/pt_BR.inc" role="data"/> <file name="localization/ro_RO.inc" role="data"/> <file name="localization/ru_RU.inc" role="data"/> <file name="localization/tr_TR.inc" role="data"/> <file name="skins/classic/zip.png" role="data"/> <file name="skins/classic/zipdownload.css" role="data"/> <file name="skins/larry/zipdownload.css" role="data"/> </dir> <!-- / --> </contents> <dependencies> <required> <php> <min>5.2.1</min> </php> <pearinstaller> <min>1.7.0</min> </pearinstaller> <extension> <name>zip</name> <channel>pecl.php.net</channel> <providesextension>zip</providesextension> </extension> </required> </dependencies> <phprelease/> </package> plugins/zipdownload/skins/classic/zip.png
plugins/zipdownload/skins/classic/zipdownload.css
New file @@ -0,0 +1,8 @@ /* Roundcube Zipdownload plugin styles for classic skin */ a.zipdownload { display: inline-block; padding: 0 0 2px 20px; background: url(zip.png) 0 1px no-repeat; font-style: italic; } plugins/zipdownload/skins/larry/zipdownload.css
New file @@ -0,0 +1,7 @@ /* Roundcube Zipdownload plugin styles for skin "Larry" */ a.zipdownload { display: inline-block; margin-top: 1.5em; padding: 3px 5px 4px 5px; } plugins/zipdownload/zipdownload.js
New file @@ -0,0 +1,33 @@ /** * ZipDownload plugin script */ function rcmail_zipmessages() { if (rcmail.message_list && rcmail.message_list.get_selection().length > 1) { rcmail.goto_url('plugin.zipdownload.zip_messages', '_mbox=' + urlencode(rcmail.env.mailbox) + '&_uid=' + rcmail.message_list.get_selection().join(',')); } } $(document).ready(function() { if (window.rcmail) { rcmail.addEventListener('init', function(evt) { // register command (directly enable in message view mode) rcmail.register_command('plugin.zipdownload.zip_folder', function() { rcmail.goto_url('plugin.zipdownload.zip_folder', '_mbox=' + urlencode(rcmail.env.mailbox)); }, rcmail.env.messagecount > 0); if (rcmail.message_list && rcmail.env.zipdownload_selection) { rcmail.message_list.addEventListener('select', function(list) { rcmail.enable_command('download', list.get_selection().length > 0); }); // check in contextmenu plugin exists and if so allow multiple message download if (rcmail.contextmenu_disable_multi) rcmail.contextmenu_disable_multi.splice($.inArray('#download', rcmail.contextmenu_disable_multi), 1); } }); rcmail.addEventListener('listupdate', function(props) { rcmail.enable_command('plugin.zipdownload.zip_folder', rcmail.env.messagecount > 0); } ); rcmail.addEventListener('beforedownload', function(props) { rcmail_zipmessages(); } ); } }); plugins/zipdownload/zipdownload.php
New file @@ -0,0 +1,267 @@ <?php /** * ZipDownload * * Plugin to allow the download of all message attachments in one zip file * * @version @package_version@ * @requires php_zip extension (including ZipArchive class) * @author Philip Weir * @author Thomas Bruderli */ class zipdownload extends rcube_plugin { public $task = 'mail'; private $charset = 'ASCII'; /** * Plugin initialization */ public function init() { // check requirements first if (!class_exists('ZipArchive', false)) { rcube::raise_error(array( 'code' => 520, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "php_zip extension is required for the zipdownload plugin"), true, false); return; } $rcmail = rcmail::get_instance(); $this->charset = $rcmail->config->get('zipdownload_charset', RCMAIL_CHARSET); $this->load_config(); $this->add_texts('localization'); if ($rcmail->config->get('zipdownload_attachments', 1) > -1 && ($rcmail->action == 'show' || $rcmail->action == 'preview')) $this->add_hook('template_object_messageattachments', array($this, 'attachment_ziplink')); $this->register_action('plugin.zipdownload.zip_attachments', array($this, 'download_attachments')); $this->register_action('plugin.zipdownload.zip_messages', array($this, 'download_selection')); $this->register_action('plugin.zipdownload.zip_folder', array($this, 'download_folder')); if ($rcmail->config->get('zipdownload_folder', false) || $rcmail->config->get('zipdownload_selection', false)) { $this->include_script('zipdownload.js'); $this->api->output->set_env('zipdownload_selection', $rcmail->config->get('zipdownload_selection', false)); if ($rcmail->config->get('zipdownload_folder', false) && ($rcmail->action == '' || $rcmail->action == 'show')) { $zipdownload = $this->api->output->button(array('command' => 'plugin.zipdownload.zip_folder', 'type' => 'link', 'classact' => 'active', 'content' => $this->gettext('downloadfolder'))); $this->api->add_content(html::tag('li', array('class' => 'separator_above'), $zipdownload), 'mailboxoptions'); } } } /** * Place a link/button after attachments listing to trigger download */ public function attachment_ziplink($p) { $rcmail = rcmail::get_instance(); // only show the link if there is more than the configured number of attachments if (substr_count($p['content'], '<li') > $rcmail->config->get('zipdownload_attachments', 1)) { $link = html::a(array( 'href' => rcmail_url('plugin.zipdownload.zip_attachments', array('_mbox' => $rcmail->output->env['mailbox'], '_uid' => $rcmail->output->env['uid'])), 'class' => 'button zipdownload', ), Q($this->gettext('downloadall')) ); // append link to attachments list, slightly different in some skins switch (rcube::get_instance()->config->get('skin')) { case 'classic': $p['content'] = str_replace('</ul>', html::tag('li', array('class' => 'zipdownload'), $link) . '</ul>', $p['content']); break; default: $p['content'] .= $link; break; } $this->include_stylesheet($this->local_skin_path() . '/zipdownload.css'); } return $p; } /** * Handler for attachment download action */ public function download_attachments() { $rcmail = rcmail::get_instance(); $imap = $rcmail->storage; $temp_dir = $rcmail->config->get('temp_dir'); $tmpfname = tempnam($temp_dir, 'zipdownload'); $tempfiles = array($tmpfname); $message = new rcube_message(get_input_value('_uid', RCUBE_INPUT_GET)); // open zip file $zip = new ZipArchive(); $zip->open($tmpfname, ZIPARCHIVE::OVERWRITE); foreach ($message->attachments as $part) { $pid = $part->mime_id; $part = $message->mime_parts[$pid]; $disp_name = $this->_convert_filename($part->filename, $part->charset); if ($part->body) { $orig_message_raw = $part->body; $zip->addFromString($disp_name, $orig_message_raw); } else { $tmpfn = tempnam($temp_dir, 'zipattach'); $tmpfp = fopen($tmpfn, 'w'); $imap->get_message_part($message->uid, $part->mime_id, $part, null, $tmpfp, true); $tempfiles[] = $tmpfn; fclose($tmpfp); $zip->addFile($tmpfn, $disp_name); } } $zip->close(); $filename = ($message->subject ? $message->subject : 'roundcube') . '.zip'; $this->_deliver_zipfile($tmpfname, $filename); // delete temporary files from disk foreach ($tempfiles as $tmpfn) unlink($tmpfn); exit; } /** * Handler for message download action */ public function download_selection() { if (isset($_REQUEST['_uid'])) { $uids = explode(",", get_input_value('_uid', RCUBE_INPUT_GPC)); if (sizeof($uids) > 0) $this->_download_messages($uids); } } /** * Handler for folder download action */ public function download_folder() { $imap = rcmail::get_instance()->storage; $mbox_name = $imap->get_folder(); // initialize searching result if search_filter is used if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') { $imap->search($mbox_name, $_SESSION['search_filter'], RCMAIL_CHARSET); } // fetch message headers for all pages $uids = array(); if ($count = $imap->count($mbox_name, $imap->get_threading() ? 'THREADS' : 'ALL', FALSE)) { for ($i = 0; ($i * $imap->get_pagesize()) <= $count; $i++) { $a_headers = $imap->list_messages($mbox_name, ($i + 1)); foreach ($a_headers as $n => $header) { if (empty($header)) continue; array_push($uids, $header->uid); } } } if (sizeof($uids) > 0) $this->_download_messages($uids); } /** * Helper method to packs all the given messages into a zip archive * * @param array List of message UIDs to download */ private function _download_messages($uids) { $rcmail = rcmail::get_instance(); $imap = $rcmail->storage; $temp_dir = $rcmail->config->get('temp_dir'); $tmpfname = tempnam($temp_dir, 'zipdownload'); $tempfiles = array($tmpfname); // open zip file $zip = new ZipArchive(); $zip->open($tmpfname, ZIPARCHIVE::OVERWRITE); foreach ($uids as $key => $uid){ $headers = $imap->get_message_headers($uid); $subject = rcube_mime::decode_mime_string((string)$headers->subject); $subject = $this->_convert_filename($subject); $subject = substr($subject, 0, 16); if (isset($subject) && $subject !="") $disp_name = $subject . ".eml"; else $disp_name = "message_rfc822.eml"; $disp_name = $uid . "_" . $disp_name; $tmpfn = tempnam($temp_dir, 'zipmessage'); $tmpfp = fopen($tmpfn, 'w'); $imap->get_raw_body($uid, $tmpfp); $tempfiles[] = $tmpfn; fclose($tmpfp); $zip->addFile($tmpfn, $disp_name); } $zip->close(); $this->_deliver_zipfile($tmpfname, $imap->get_folder() . '.zip'); // delete temporary files from disk foreach ($tempfiles as $tmpfn) unlink($tmpfn); exit; } /** * Helper method to send the zip archive to the browser */ private function _deliver_zipfile($tmpfname, $filename) { $browser = new rcube_browser; send_nocacheing_headers(); if ($browser->ie && $browser->ver < 7) $filename = rawurlencode(abbreviate_string($filename, 55)); else if ($browser->ie) $filename = rawurlencode($filename); else $filename = addcslashes($filename, '"'); // send download headers header("Content-Type: application/octet-stream"); if ($browser->ie) header("Content-Type: application/force-download"); // don't kill the connection if download takes more than 30 sec. @set_time_limit(0); header("Content-Disposition: attachment; filename=\"". $filename ."\""); header("Content-length: " . filesize($tmpfname)); readfile($tmpfname); } /** * Helper function to convert filenames to the configured charset */ private function _convert_filename($str, $from = RCMAIL_CHARSET) { return strtr(rcube_charset_convert($str, $from, $this->charset), array(':'=>'', '/'=>'-')); } } ?>