| | |
| | | */ |
| | | class zipdownload extends rcube_plugin |
| | | { |
| | | public $task = 'mail'; |
| | | private $charset = 'ASCII'; |
| | | public $task = 'mail'; |
| | | private $charset = 'ASCII'; |
| | | |
| | | /** |
| | | * Plugin initialization |
| | | */ |
| | | public function init() |
| | | { |
| | | // check requirements first |
| | | if (!class_exists('ZipArchive', false)) { |
| | | rcmail::raise_error(array( |
| | | 'code' => 520, 'type' => 'php', |
| | | 'file' => __FILE__, 'line' => __LINE__, |
| | | 'message' => "php_zip extension is required for the zipdownload plugin"), true, false); |
| | | return; |
| | | } |
| | | /** |
| | | * Plugin initialization |
| | | */ |
| | | public function init() |
| | | { |
| | | // check requirements first |
| | | if (!class_exists('ZipArchive', false)) { |
| | | rcmail::raise_error(array( |
| | | 'code' => 520, |
| | | 'file' => __FILE__, |
| | | 'line' => __LINE__, |
| | | 'message' => "php_zip extension is required for the zipdownload plugin"), true, false); |
| | | return; |
| | | } |
| | | |
| | | $rcmail = rcmail::get_instance(); |
| | | $rcmail = rcmail::get_instance(); |
| | | |
| | | $this->load_config(); |
| | | $this->charset = $rcmail->config->get('zipdownload_charset', RCUBE_CHARSET); |
| | | $this->add_texts('localization'); |
| | | $this->load_config(); |
| | | $this->charset = $rcmail->config->get('zipdownload_charset', RCUBE_CHARSET); |
| | | $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')); |
| | | 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')); |
| | | $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 (($selection = $rcmail->config->get('zipdownload_selection')) || $rcmail->config->get('zipdownload_folder')) { |
| | | $this->include_script('zipdownload.js'); |
| | | $this->api->output->set_env('zipdownload_selection', $selection); |
| | | |
| | | 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'); |
| | | } |
| | | } |
| | | } |
| | | 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(); |
| | | /** |
| | | * 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)) { |
| | | $href = $rcmail->url(array( |
| | | '_action' => 'plugin.zipdownload.zip_attachments', |
| | | '_mbox' => $rcmail->output->env['mailbox'], |
| | | '_uid' => $rcmail->output->env['uid'], |
| | | )); |
| | | // 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)) { |
| | | $href = $rcmail->url(array( |
| | | '_action' => 'plugin.zipdownload.zip_attachments', |
| | | '_mbox' => $rcmail->output->env['mailbox'], |
| | | '_uid' => $rcmail->output->env['uid'], |
| | | )); |
| | | |
| | | $link = html::a(array('href' => $href, 'class' => 'button zipdownload'), |
| | | rcube::Q($this->gettext('downloadall')) |
| | | ); |
| | | $link = html::a(array('href' => $href, 'class' => 'button zipdownload'), |
| | | rcube::Q($this->gettext('downloadall')) |
| | | ); |
| | | |
| | | // append link to attachments list, slightly different in some skins |
| | | switch (rcmail::get_instance()->config->get('skin')) { |
| | | case 'classic': |
| | | $p['content'] = str_replace('</ul>', html::tag('li', array('class' => 'zipdownload'), $link) . '</ul>', $p['content']); |
| | | break; |
| | | // append link to attachments list, slightly different in some skins |
| | | switch (rcmail::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; |
| | | } |
| | | default: |
| | | $p['content'] .= $link; |
| | | break; |
| | | } |
| | | |
| | | $this->include_stylesheet($this->local_skin_path() . '/zipdownload.css'); |
| | | } |
| | | $this->include_stylesheet($this->local_skin_path() . '/zipdownload.css'); |
| | | } |
| | | |
| | | return $p; |
| | | } |
| | | 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(rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET)); |
| | | /** |
| | | * Handler for attachment download action |
| | | */ |
| | | public function download_attachments() |
| | | { |
| | | $rcmail = rcmail::get_instance(); |
| | | $imap = $rcmail->get_storage(); |
| | | $temp_dir = $rcmail->config->get('temp_dir'); |
| | | $tmpfname = tempnam($temp_dir, 'zipdownload'); |
| | | $tempfiles = array($tmpfname); |
| | | $message = new rcube_message(rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET)); |
| | | |
| | | // open zip file |
| | | $zip = new ZipArchive(); |
| | | $zip->open($tmpfname, ZIPARCHIVE::OVERWRITE); |
| | | // 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]; |
| | | $filename = $part->filename; |
| | | foreach ($message->attachments as $part) { |
| | | $pid = $part->mime_id; |
| | | $part = $message->mime_parts[$pid]; |
| | | $filename = $part->filename; |
| | | |
| | | if ($filename === null || $filename === '') { |
| | | $ext = (array) rcube_mime::get_mime_extensions($part->mimetype); |
| | |
| | | } |
| | | } |
| | | |
| | | $disp_name = $this->_convert_filename($filename); |
| | | $disp_name = $this->_convert_filename($filename); |
| | | |
| | | 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); |
| | | } |
| | | 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(); |
| | | |
| | | $zip->close(); |
| | | $filename = ($message->subject ? $message->subject : 'roundcube') . '.zip'; |
| | | $this->_deliver_zipfile($tmpfname, $filename); |
| | | |
| | | $filename = ($message->subject ? $message->subject : 'roundcube') . '.zip'; |
| | | $this->_deliver_zipfile($tmpfname, $filename); |
| | | // delete temporary files from disk |
| | | foreach ($tempfiles as $tmpfn) { |
| | | unlink($tmpfn); |
| | | } |
| | | |
| | | // delete temporary files from disk |
| | | foreach ($tempfiles as $tmpfn) |
| | | unlink($tmpfn); |
| | | exit; |
| | | } |
| | | |
| | | exit; |
| | | } |
| | | /** |
| | | * Handler for message download action |
| | | */ |
| | | public function download_selection() |
| | | { |
| | | if (isset($_REQUEST['_uid'])) { |
| | | $uids = explode(",", rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GPC)); |
| | | |
| | | /** |
| | | * Handler for message download action |
| | | */ |
| | | public function download_selection() |
| | | { |
| | | if (isset($_REQUEST['_uid'])) { |
| | | $uids = explode(",", rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GPC)); |
| | | if (sizeof($uids) > 0) { |
| | | $this->_download_messages($uids); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (sizeof($uids) > 0) |
| | | $this->_download_messages($uids); |
| | | } |
| | | } |
| | | /** |
| | | * Handler for folder download action |
| | | */ |
| | | public function download_folder() |
| | | { |
| | | $imap = rcmail::get_instance()->get_storage(); |
| | | $mbox_name = $imap->get_folder(); |
| | | |
| | | /** |
| | | * 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'], RCUBE_CHARSET); |
| | | } |
| | | |
| | | // initialize searching result if search_filter is used |
| | | if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') { |
| | | $imap->search($mbox_name, $_SESSION['search_filter'], RCUBE_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)); |
| | | |
| | | // 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 $header) { |
| | | if (empty($header)) |
| | | continue; |
| | | |
| | | foreach ($a_headers as $header) { |
| | | if (empty($header)) |
| | | continue; |
| | | array_push($uids, $header->uid); |
| | | } |
| | | } |
| | | } |
| | | |
| | | array_push($uids, $header->uid); |
| | | } |
| | | } |
| | | } |
| | | if (sizeof($uids) > 0) |
| | | $this->_download_messages($uids); |
| | | } |
| | | |
| | | 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->get_storage(); |
| | | $temp_dir = $rcmail->config->get('temp_dir'); |
| | | $tmpfname = tempnam($temp_dir, 'zipdownload'); |
| | | $tempfiles = array($tmpfname); |
| | | |
| | | /** |
| | | * 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); |
| | | |
| | | // open zip file |
| | | $zip = new ZipArchive(); |
| | | $zip->open($tmpfname, ZIPARCHIVE::OVERWRITE); |
| | | |
| | | foreach ($uids as $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); |
| | | foreach ($uids as $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); |
| | | |
| | | $disp_name = ($subject ? $subject : 'message_rfc822') . ".eml"; |
| | | $disp_name = $uid . "_" . $disp_name; |
| | | $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); |
| | | } |
| | | $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(); |
| | | $zip->close(); |
| | | |
| | | $this->_deliver_zipfile($tmpfname, $imap->get_folder() . '.zip'); |
| | | $this->_deliver_zipfile($tmpfname, $imap->get_folder() . '.zip'); |
| | | |
| | | // delete temporary files from disk |
| | | foreach ($tempfiles as $tmpfn) |
| | | unlink($tmpfn); |
| | | // delete temporary files from disk |
| | | foreach ($tempfiles as $tmpfn) { |
| | | unlink($tmpfn); |
| | | } |
| | | |
| | | exit; |
| | | } |
| | | exit; |
| | | } |
| | | |
| | | /** |
| | | * Helper method to send the zip archive to the browser |
| | | */ |
| | | private function _deliver_zipfile($tmpfname, $filename) |
| | | { |
| | | $browser = new rcube_browser; |
| | | $rcmail = rcmail::get_instance(); |
| | | /** |
| | | * Helper method to send the zip archive to the browser |
| | | */ |
| | | private function _deliver_zipfile($tmpfname, $filename) |
| | | { |
| | | $browser = new rcube_browser; |
| | | $rcmail = rcmail::get_instance(); |
| | | |
| | | $rcmail->output->nocacheing_headers(); |
| | | $rcmail->output->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, '"'); |
| | | 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"); |
| | | // 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); |
| | | } |
| | | // 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) |
| | | { |
| | | /** |
| | | * Helper function to convert filenames to the configured charset |
| | | */ |
| | | private function _convert_filename($str) |
| | | { |
| | | $str = rcube_charset::convert($str, RCUBE_CHARSET, $this->charset); |
| | | |
| | | return strtr($str, array(':'=>'', '/'=>'-')); |
| | | } |
| | | return strtr($str, array(':'=>'', '/'=>'-')); |
| | | } |
| | | } |