summaryrefslogtreecommitdiff
path: root/program/steps
diff options
context:
space:
mode:
Diffstat (limited to 'program/steps')
-rw-r--r--program/steps/addressbook/copy.inc6
-rw-r--r--program/steps/addressbook/func.inc2
-rw-r--r--program/steps/addressbook/import.inc7
-rw-r--r--program/steps/addressbook/move.inc6
-rw-r--r--program/steps/addressbook/save.inc4
-rw-r--r--program/steps/mail/autocomplete.inc9
-rw-r--r--program/steps/mail/check_recent.inc34
-rw-r--r--program/steps/mail/compose.inc122
-rw-r--r--program/steps/mail/copy.inc11
-rw-r--r--program/steps/mail/func.inc336
-rw-r--r--program/steps/mail/get.inc6
-rw-r--r--program/steps/mail/import.inc115
-rw-r--r--program/steps/mail/list.inc16
-rw-r--r--program/steps/mail/list_contacts.inc48
-rw-r--r--program/steps/mail/mark.inc20
-rw-r--r--program/steps/mail/move_del.inc44
-rw-r--r--program/steps/mail/search.inc61
-rw-r--r--program/steps/mail/search_contacts.inc12
-rw-r--r--program/steps/mail/sendmail.inc45
-rw-r--r--program/steps/mail/show.inc2
-rw-r--r--program/steps/mail/viewsource.inc4
-rw-r--r--program/steps/settings/edit_folder.inc1
-rw-r--r--program/steps/settings/edit_identity.inc2
-rw-r--r--program/steps/settings/edit_prefs.inc4
-rw-r--r--program/steps/settings/edit_response.inc2
-rw-r--r--program/steps/settings/folders.inc23
-rw-r--r--program/steps/settings/func.inc37
-rw-r--r--program/steps/settings/responses.inc2
-rw-r--r--program/steps/settings/save_identity.inc4
-rw-r--r--program/steps/settings/save_prefs.inc28
-rw-r--r--program/steps/utils/html2text.inc7
-rw-r--r--program/steps/utils/modcss.inc54
-rw-r--r--program/steps/utils/spell.inc3
-rw-r--r--program/steps/utils/text2html.inc33
34 files changed, 699 insertions, 411 deletions
diff --git a/program/steps/addressbook/copy.inc b/program/steps/addressbook/copy.inc
index 9114cb1fd..e4e276591 100644
--- a/program/steps/addressbook/copy.inc
+++ b/program/steps/addressbook/copy.inc
@@ -88,9 +88,9 @@ foreach ($cids as $source => $cid) {
}
}
else {
- $record = $result->first();
- $ids[] = $record['ID'];
- $errormsg = empty($a_record['email']) ? 'contactnameexists' : 'contactexists';
+ $record = $result->first();
+ $ids[] = $record['ID'];
+ $errormsg = empty($email) ? 'contactnameexists' : 'contactexists';
}
}
diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc
index b33396baf..be0dd2a33 100644
--- a/program/steps/addressbook/func.inc
+++ b/program/steps/addressbook/func.inc
@@ -160,7 +160,7 @@ function rcmail_contact_source($source=null, $init_env=false, $writable=false)
return $CONTACTS;
$OUTPUT->set_env('readonly', $CONTACTS->readonly);
- $OUTPUT->set_env('source', $source);
+ $OUTPUT->set_env('source', (string) $source);
// reduce/extend $CONTACT_COLTYPES with specification from the current $CONTACT object
if (is_array($CONTACTS->coltypes)) {
diff --git a/program/steps/addressbook/import.inc b/program/steps/addressbook/import.inc
index 33e473242..5dee5c06a 100644
--- a/program/steps/addressbook/import.inc
+++ b/program/steps/addressbook/import.inc
@@ -308,10 +308,11 @@ function rcmail_import_buttons($attrib)
$out = $OUTPUT->button(array('command' => 'list', 'prop' => $target, 'label' => 'done') + $attrib);
}
else {
- $out = $OUTPUT->button(array('command' => 'list', 'label' => 'cancel') + $attrib);
- $out .= ' ';
+ $cancel = $OUTPUT->button(array('command' => 'list', 'label' => 'cancel') + $attrib);
$attrib['class'] = trim($attrib['class'] . ' mainaction');
- $out .= $OUTPUT->button(array('command' => 'import', 'label' => 'import') + $attrib);
+ $out = $OUTPUT->button(array('command' => 'import', 'label' => 'import') + $attrib);
+ $out .= ' ';
+ $out .= $cancel;
}
return $out;
diff --git a/program/steps/addressbook/move.inc b/program/steps/addressbook/move.inc
index 6a70e7bda..7a730af77 100644
--- a/program/steps/addressbook/move.inc
+++ b/program/steps/addressbook/move.inc
@@ -97,9 +97,9 @@ foreach ($cids as $source => $source_cids) {
}
}
else {
- $record = $result->first();
- $ids[] = $record['ID'];
- $errormsg = empty($a_record['email']) ? 'contactnameexists' : 'contactexists';
+ $record = $result->first();
+ $ids[] = $record['ID'];
+ $errormsg = empty($email) ? 'contactnameexists' : 'contactexists';
}
}
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 94556f96b..7451f433b 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -165,6 +165,10 @@ if (!empty($cid)) {
$a_js_cols[] = rcube::Q((string)$record[$col]);
}
+ // performance: unset some big data items we don't need here
+ $record = array_intersect_key($record, array('ID' => 1,'email' => 1,'name' => 1));
+ $record['_type'] = 'person';
+
// update the changed col in list
$OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source, $record);
diff --git a/program/steps/mail/autocomplete.inc b/program/steps/mail/autocomplete.inc
index c15de92cf..71b337a53 100644
--- a/program/steps/mail/autocomplete.inc
+++ b/program/steps/mail/autocomplete.inc
@@ -49,7 +49,7 @@ $mode = (int) $RCMAIL->config->get('addressbook_search_mode');
$single = (bool) $RCMAIL->config->get('autocomplete_single');
$search = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC, true);
$source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC);
-$sid = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC);
+$reqid = rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC);
if (strlen($source)) {
$book_types = array($source);
@@ -90,7 +90,7 @@ if (!empty($book_types) && strlen($search)) {
// skip duplicates
if (!in_array($contact, $contacts)) {
- $contacts[] = $contact;
+ $contacts[] = array('name' => $contact, 'type' => $sql_arr['_type']);
$sort_keys[] = sprintf('%s %03d', $sql_arr['name'] , $idx++);
if (count($contacts) >= $MAXNUM) {
@@ -118,7 +118,7 @@ if (!empty($book_types) && strlen($search)) {
if ($group_prop['email']) {
$idx = 0;
foreach ((array)$group_prop['email'] as $email) {
- $contacts[] = format_email_recipient($email, $group['name']);
+ $contacts[] = array('name' => format_email_recipient($email, $group['name']), 'type' => 'group');
$sort_keys[] = sprintf('%s %03d', $group['name'] , $idx++);
if (count($contacts) >= $MAXNUM) {
@@ -131,6 +131,7 @@ if (!empty($book_types) && strlen($search)) {
$sort_keys[] = $group['name'];
$contacts[] = array(
'name' => $group['name'] . ' (' . intval($result->count) . ')',
+ 'type' => 'group',
'id' => $group['ID'],
'source' => $id
);
@@ -154,5 +155,5 @@ if (!empty($book_types) && strlen($search)) {
}
}
-$OUTPUT->command('ksearch_query_results', $contacts, $search, $sid);
+$OUTPUT->command('ksearch_query_results', $contacts, $search, $reqid);
$OUTPUT->send();
diff --git a/program/steps/mail/check_recent.inc b/program/steps/mail/check_recent.inc
index d2d27a2ca..70f4c03a6 100644
--- a/program/steps/mail/check_recent.inc
+++ b/program/steps/mail/check_recent.inc
@@ -5,7 +5,7 @@
| program/steps/mail/check_recent.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2010, The Roundcube Dev Team |
+ | Copyright (C) 2005-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -21,7 +21,7 @@
// If there's no folder or messages list, there's nothing to update
// This can happen on 'refresh' request
-if (empty($_REQUEST['_folderlist']) && empty($_REQUEST['_list'])) {
+if (empty($_POST['_folderlist']) && empty($_POST['_list'])) {
return;
}
@@ -29,10 +29,18 @@ $trash = $RCMAIL->config->get('trash_mbox');
$current = $RCMAIL->storage->get_folder();
$check_all = $RCMAIL->action != 'refresh' || (bool)$RCMAIL->config->get('check_all_folders');
+$search_request = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC);
+if ($search_request && $_SESSION['search_request'] != $search_request) {
+ $search_request = null;
+}
+
// list of folders to check
if ($check_all) {
$a_mailboxes = $RCMAIL->storage->list_folders_subscribed('', '*', 'mail');
}
+else if ($search_request && is_object($_SESSION['search'][1])) {
+ $a_mailboxes = (array) $_SESSION['search'][1]->get_parameters('MAILBOX');
+}
else {
$a_mailboxes = (array) $current;
if ($current != 'INBOX') {
@@ -46,7 +54,7 @@ $a_mailboxes = $plugin['folders'];
// check recent/unseen counts
foreach ($a_mailboxes as $mbox_name) {
- $is_current = $mbox_name == $current;
+ $is_current = $mbox_name == $current || ($search_request && is_object($_SESSION['search'][1]) && in_array($mbox_name, (array)$_SESSION['search'][1]->get_parameters('MAILBOX')));
if ($is_current) {
// Synchronize mailbox cache, handle flag changes
$RCMAIL->storage->folder_sync($mbox_name);
@@ -66,21 +74,23 @@ foreach ($a_mailboxes as $mbox_name) {
if ($status && $is_current) {
// refresh saved search set
- $search_request = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC);
- if ($search_request && isset($_SESSION['search'])
- && $_SESSION['search_request'] == $search_request
- ) {
+ if ($search_request && isset($_SESSION['search'])) {
+ unset($search_request); // only do this once
$_SESSION['search'] = $RCMAIL->storage->refresh_search();
+ if ($_SESSION['search'][1]->multi)
+ $mbox_name = '';
}
- if (!empty($_GET['_quota']))
+ if (!empty($_POST['_quota'])) {
$OUTPUT->command('set_quota', $RCMAIL->quota_content());
+ }
- $OUTPUT->set_env('exists', $RCMAIL->storage->count($mbox_name, 'EXISTS'));
+ $OUTPUT->set_env('exists', $RCMAIL->storage->count($mbox_name, 'EXISTS', true));
// "No-list" mode, don't get messages
- if (empty($_GET['_list']))
+ if (empty($_POST['_list'])) {
continue;
+ }
// get overall message count; allow caching because rcube_storage::folder_status()
// did a refresh but only in list mode
@@ -116,7 +126,7 @@ foreach ($a_mailboxes as $mbox_name) {
}
}
// handle flag updates
- else if ($is_current && ($uids = rcube_utils::get_input_value('_uids', rcube_utils::INPUT_GPC))) {
+ else if ($is_current && ($uids = rcube_utils::get_input_value('_uids', rcube_utils::INPUT_GPC)) && empty($search_request)) {
$data = $RCMAIL->storage->folder_data($mbox_name);
if (empty($_SESSION['list_mod_seq']) || $_SESSION['list_mod_seq'] != $data['HIGHESTMODSEQ']) {
@@ -136,7 +146,7 @@ foreach ($a_mailboxes as $mbox_name) {
// set trash folder state
if ($mbox_name === $trash) {
- $OUTPUT->command('set_trash_count', $RCMAIL->storage->count($mbox_name, 'EXISTS'));
+ $OUTPUT->command('set_trash_count', $RCMAIL->storage->count($mbox_name, 'EXISTS', true));
}
}
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index db485fda8..6a0139d72 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -62,36 +62,6 @@ if (!is_array($COMPOSE)) {
rcmail_process_compose_params($COMPOSE);
- // add attachments listed by message_compose hook
- if (is_array($plugin['attachments'])) {
- foreach ($plugin['attachments'] as $attach) {
- // we have structured data
- if (is_array($attach)) {
- $attachment = $attach;
- }
- // only a file path is given
- else {
- $filename = basename($attach);
- $attachment = array(
- 'group' => $COMPOSE_ID,
- 'name' => $filename,
- 'mimetype' => rcube_mime::file_content_type($attach, $filename),
- 'path' => $attach,
- );
- }
-
- // save attachment if valid
- if (($attachment['data'] && $attachment['name']) || ($attachment['path'] && file_exists($attachment['path']))) {
- $attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment);
- }
-
- if ($attachment['status'] && !$attachment['abort']) {
- unset($attachment['data'], $attachment['status'], $attachment['abort']);
- $COMPOSE['attachments'][$attachment['id']] = $attachment;
- }
- }
- }
-
// check if folder for saving sent messages exists and is subscribed (#1486802)
if ($sent_folder = $COMPOSE['param']['sent_mbox']) {
rcmail_check_sent_folder($sent_folder, true);
@@ -111,7 +81,8 @@ $OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubj
'nobodywarning', 'notsentwarning', 'notuploadedwarning', 'savingmessage', 'sendingmessage',
'messagesaved', 'converting', 'editorwarning', 'searching', 'uploading', 'uploadingmany',
'fileuploaderror', 'sendmessage', 'savenewresponse', 'responsename', 'responsetext', 'save',
- 'savingresponse', 'restoresavedcomposedata', 'restoremessage', 'delete', 'restore', 'ignore');
+ 'savingresponse', 'restoresavedcomposedata', 'restoremessage', 'delete', 'restore', 'ignore',
+ 'selectimportfile');
$OUTPUT->set_pagetitle($RCMAIL->gettext('compose'));
@@ -208,14 +179,20 @@ if (!empty($msg_uid) && empty($COMPOSE['as_attachment'])) {
if (!$MESSAGE->headers) {
// error
}
- else if ($compose_mode == RCUBE_COMPOSE_REPLY) {
- $COMPOSE['reply_uid'] = $msg_uid;
- $COMPOSE['reply_msgid'] = $MESSAGE->headers->messageID;
- $COMPOSE['references'] = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID);
+ else if ($compose_mode == RCUBE_COMPOSE_FORWARD || $compose_mode == RCUBE_COMPOSE_REPLY) {
+ if ($compose_mode == RCUBE_COMPOSE_REPLY) {
+ $COMPOSE['reply_uid'] = $msg_uid;
- if (!empty($COMPOSE['param']['all'])) {
- $MESSAGE->reply_all = $COMPOSE['param']['all'];
+ if (!empty($COMPOSE['param']['all'])) {
+ $MESSAGE->reply_all = $COMPOSE['param']['all'];
+ }
}
+ else {
+ $COMPOSE['forward_uid'] = $msg_uid;
+ }
+
+ $COMPOSE['reply_msgid'] = $MESSAGE->headers->messageID;
+ $COMPOSE['references'] = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID);
// Save the sent message in the same folder of the message being replied to
if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $COMPOSE['mailbox'])
@@ -271,6 +248,10 @@ else {
}
}
+if (!empty($COMPOSE['reply_msgid'])) {
+ $OUTPUT->set_env('reply_msgid', $COMPOSE['reply_msgid']);
+}
+
$MESSAGE->compose = array();
// get user's identities
@@ -482,6 +463,11 @@ function rcmail_process_compose_params(&$COMPOSE)
}
}
+ // resolve _forward_uid=* to an absolute list of messages from a search result
+ if ($COMPOSE['param']['forward_uid'] == '*' && is_object($_SESSION['search'][1])) {
+ $COMPOSE['param']['forward_uid'] = $_SESSION['search'][1]->get();
+ }
+
// clean HTML message body which can be submitted by URL
if (!empty($COMPOSE['param']['body'])) {
$COMPOSE['param']['body'] = rcmail_wash_html($COMPOSE['param']['body'], array('safe' => false, 'inline_html' => true), array());
@@ -495,6 +481,36 @@ function rcmail_process_compose_params(&$COMPOSE)
// pipe compose parameters thru plugins
$plugin = $RCMAIL->plugins->exec_hook('message_compose', $COMPOSE);
$COMPOSE['param'] = array_merge($COMPOSE['param'], $plugin['param']);
+
+ // add attachments listed by message_compose hook
+ if (is_array($plugin['attachments'])) {
+ foreach ($plugin['attachments'] as $attach) {
+ // we have structured data
+ if (is_array($attach)) {
+ $attachment = $attach + array('group' => $COMPOSE_ID);
+ }
+ // only a file path is given
+ else {
+ $filename = basename($attach);
+ $attachment = array(
+ 'group' => $COMPOSE_ID,
+ 'name' => $filename,
+ 'mimetype' => rcube_mime::file_content_type($attach, $filename),
+ 'path' => $attach,
+ );
+ }
+
+ // save attachment if valid
+ if (($attachment['data'] && $attachment['name']) || ($attachment['path'] && file_exists($attachment['path']))) {
+ $attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment);
+ }
+
+ if ($attachment['status'] && !$attachment['abort']) {
+ unset($attachment['data'], $attachment['status'], $attachment['abort']);
+ $COMPOSE['attachments'][$attachment['id']] = $attachment;
+ }
+ }
+ }
}
function rcmail_compose_headers($attrib)
@@ -595,7 +611,7 @@ function rcmail_compose_header_from($attrib)
$text = $html = $sql_arr['signature'];
if ($sql_arr['html_signature']) {
- $h2t = new rcube_html2text($sql_arr['signature'], false, false);
+ $h2t = new rcube_html2text($sql_arr['signature'], false, true);
$text = trim($h2t->get_text());
}
else {
@@ -608,7 +624,8 @@ function rcmail_compose_header_from($attrib)
}
if (!$sql_arr['html_signature']) {
- $html = "<pre>" . $html . "</pre>";
+ $t2h = new rcube_text2html($sql_arr['signature'], false);
+ $html = $t2h->get_html();
}
$a_signatures[$identity_id]['text'] = $text;
@@ -810,15 +827,8 @@ function rcmail_compose_part_body($part, $isHtml = false)
}
}
- if ($part->ctype_parameters['format'] == 'flowed') {
- $body = rcube_mime::unfold_flowed($body);
- }
-
// add HTML formatting
- $body = rcmail_plain_body($body);
- if ($body) {
- $body = '<pre>' . $body . '</pre>';
- }
+ $body = rcmail_plain_body($body, $part->ctype_parameters['format'] == 'flowed');
}
}
else {
@@ -1237,6 +1247,7 @@ function rcmail_write_forward_attachments()
$storage = $RCMAIL->get_storage();
$names = array();
+ $refs = array();
$loaded_attachments = array();
foreach ((array)$COMPOSE['attachments'] as $attachment) {
@@ -1247,7 +1258,10 @@ function rcmail_write_forward_attachments()
$index = $storage->index(null, rcmail_sort_column(), rcmail_sort_order());
$COMPOSE['forward_uid'] = $index->get();
}
- else {
+ else if (!is_array($COMPOSE['forward_uid']) && strpos($COMPOSE['forward_uid'], ':')) {
+ $COMPOSE['forward_uid'] = rcube_imap_generic::uncompressMessageSet($COMPOSE['forward_uid']);
+ }
+ else if (is_string($COMPOSE['forward_uid'])) {
$COMPOSE['forward_uid'] = explode(',', $COMPOSE['forward_uid']);
}
@@ -1316,6 +1330,18 @@ function rcmail_write_forward_attachments()
else if ($path) {
@unlink($path);
}
+
+ if ($message->headers->messageID) {
+ $refs[] = $message->headers->messageID;
+ }
+ }
+
+ // set In-Reply-To and References headers
+ if (count($refs) == 1) {
+ $COMPOSE['reply_msgid'] = $refs[0];
+ }
+ if (!empty($refs)) {
+ $COMPOSE['references'] = implode(' ', $refs);
}
}
diff --git a/program/steps/mail/copy.inc b/program/steps/mail/copy.inc
index a392f309f..86586d34d 100644
--- a/program/steps/mail/copy.inc
+++ b/program/steps/mail/copy.inc
@@ -5,7 +5,7 @@
| program/steps/mail/copy.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, The Roundcube Dev Team |
+ | Copyright (C) 2005-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -26,11 +26,14 @@ if (!$OUTPUT->ajax_call) {
// move messages
if (!empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
- $uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST);
$target = rcube_utils::get_input_value('_target_mbox', rcube_utils::INPUT_POST, true);
- $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true);
- $copied = $RCMAIL->storage->copy_message($uids, $target, $mbox);
+ foreach (rcmail::get_uids() as $mbox => $uids) {
+ if ($mbox === $target)
+ $copied++;
+ else
+ $copied += (int)$RCMAIL->storage->copy_message($uids, $target, $mbox);
+ }
if (!$copied) {
// send error message
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 0211fabc4..50b1e8292 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -5,7 +5,7 @@
| program/steps/mail/func.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, The Roundcube Dev Team |
+ | Copyright (C) 2005-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -23,40 +23,8 @@
// always instantiate storage object (but not connect to server yet)
$RCMAIL->storage_init();
-// set imap properties and session vars
-if (strlen(trim($mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true)))) {
- $RCMAIL->storage->set_folder(($_SESSION['mbox'] = $mbox));
-}
-else if ($RCMAIL->storage) {
- $_SESSION['mbox'] = $RCMAIL->storage->get_folder();
-}
-
-if (!empty($_GET['_page'])) {
- $RCMAIL->storage->set_page(($_SESSION['page'] = intval($_GET['_page'])));
-}
-
-$a_threading = $RCMAIL->config->get('message_threading', array());
-$message_sort_col = $RCMAIL->config->get('message_sort_col');
-$message_sort_order = $RCMAIL->config->get('message_sort_col');
-
-// set default sort col/order to session
-if (!isset($_SESSION['sort_col'])) {
- $_SESSION['sort_col'] = $message_sort_col ? $message_sort_col : '';
-}
-if (!isset($_SESSION['sort_order'])) {
- $_SESSION['sort_order'] = strtoupper($message_sort_order) == 'ASC' ? 'ASC' : 'DESC';
-}
-
-// set threads mode
-if (isset($_GET['_threads'])) {
- if ($_GET['_threads'])
- $a_threading[$_SESSION['mbox']] = true;
- else
- unset($a_threading[$_SESSION['mbox']]);
-
- $RCMAIL->user->save_prefs(array('message_threading' => $a_threading));
-}
-$RCMAIL->storage->set_threading($a_threading[$_SESSION['mbox']]);
+// init environment - set current folder, page, list mode
+rcmail_init_env();
// set message set for search result
if (!empty($_REQUEST['_search']) && isset($_SESSION['search'])
@@ -68,6 +36,26 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'])
$OUTPUT->set_env('search_text', $_SESSION['last_text_search']);
}
+// remove mbox part from _uid
+if (($_uid = rcube_utils::get_input_value('_uid', RCUBE_INPUT_GPC)) && !is_array($_uid) && preg_match('/^\d+-.+/', $_uid)) {
+ list($_uid, $mbox) = explode('-', $_uid, 2);
+ if (isset($_GET['_uid'])) $_GET['_uid'] = $_uid;
+ if (isset($_POST['_uid'])) $_POST['_uid'] = $_uid;
+ $_REQUEST['_uid'] = $_uid;
+ unset($_uid);
+
+ // override mbox
+ if (!empty($mbox)) {
+ $_GET['_mbox'] = $mbox;
+ $_POST['_mbox'] = $mbox;
+ $RCMAIL->storage->set_folder(($_SESSION['mbox'] = $mbox));
+ }
+}
+
+if (!empty($_SESSION['browser_caps']) && !$OUTPUT->ajax_call) {
+ $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']);
+}
+
// set main env variables, labels and page title
if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
// connect to storage server and trigger error on failure
@@ -88,6 +76,9 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
}
$OUTPUT->set_env('search_mods', rcmail_search_mods());
+
+ if (!empty($_SESSION['search_scope']))
+ $OUTPUT->set_env('search_scope', $_SESSION['search_scope']);
}
$threading = (bool) $RCMAIL->storage->get_threading();
@@ -117,17 +108,13 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
$RCMAIL->set_env_config(array('delete_junk', 'flag_for_deletion', 'read_when_deleted',
'skip_deleted', 'display_next', 'message_extwin', 'compose_extwin', 'forward_attachment'));
- if (!empty($_SESSION['browser_caps'])) {
- $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']);
- }
-
if (!$OUTPUT->ajax_call) {
$OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage',
- 'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait');
+ 'copy', 'move', 'quota', 'replyall', 'replylist', 'stillsearching');
}
- $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true);
+ $pagetitle = $RCMAIL->localize_foldername($mbox_name, true);
$pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle);
$OUTPUT->set_pagetitle($pagetitle);
@@ -166,6 +153,60 @@ $RCMAIL->register_action_map(array(
));
+/**
+ * Sets storage properties and session
+ */
+function rcmail_init_env()
+{
+ global $RCMAIL;
+
+ $a_threading = $RCMAIL->config->get('message_threading', array());
+ $message_sort_col = $RCMAIL->config->get('message_sort_col');
+ $message_sort_order = $RCMAIL->config->get('message_sort_order');
+
+ // set imap properties and session vars
+ if (!strlen($mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true))) {
+ $mbox = strlen($_SESSION['mbox']) ? $_SESSION['mbox'] : 'INBOX';
+ }
+ if (!($page = intval($_GET['_page']))) {
+ $page = $_SESSION['page'] ? $_SESSION['page'] : 1;
+ }
+
+ $RCMAIL->storage->set_folder($_SESSION['mbox'] = $mbox);
+ $RCMAIL->storage->set_page($_SESSION['page'] = $page);
+
+ // set default sort col/order to session
+ if (!isset($_SESSION['sort_col'])) {
+ $_SESSION['sort_col'] = $message_sort_col ? $message_sort_col : '';
+ }
+ if (!isset($_SESSION['sort_order'])) {
+ $_SESSION['sort_order'] = strtoupper($message_sort_order) == 'ASC' ? 'ASC' : 'DESC';
+ }
+
+ // set threads mode
+ if (isset($_GET['_threads'])) {
+ if ($_GET['_threads']) {
+ // re-set current page number when listing mode changes
+ if (!$a_threading[$_SESSION['mbox']]) {
+ $RCMAIL->storage->set_page($_SESSION['page'] = 1);
+ }
+
+ $a_threading[$_SESSION['mbox']] = true;
+ }
+ else {
+ // re-set current page number when listing mode changes
+ if ($a_threading[$_SESSION['mbox']]) {
+ $RCMAIL->storage->set_page($_SESSION['page'] = 1);
+ }
+
+ unset($a_threading[$_SESSION['mbox']]);
+ }
+
+ $RCMAIL->user->save_prefs(array('message_threading' => $a_threading));
+ }
+
+ $RCMAIL->storage->set_threading($a_threading[$_SESSION['mbox']]);
+}
/**
* Returns default search mods
@@ -298,7 +339,7 @@ function rcmail_message_list($attrib)
$OUTPUT->set_env('sort_col', $_SESSION['sort_col']);
$OUTPUT->set_env('sort_order', $_SESSION['sort_order']);
$OUTPUT->set_env('messages', array());
- $OUTPUT->set_env('coltypes', $a_show_cols);
+ $OUTPUT->set_env('listcols', $a_show_cols);
$OUTPUT->include_script('list.js');
@@ -315,7 +356,7 @@ function rcmail_message_list($attrib)
/**
* return javascript commands to add rows to the message list
*/
-function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null)
+function rcmail_js_message_list($a_headers, $insert_top=false, $a_show_cols=null)
{
global $RCMAIL, $OUTPUT;
@@ -334,6 +375,14 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
$head_replace = true;
}
+ // add 'folder' column to list on multi-folder searches
+ $search_set = $RCMAIL->storage->get_search_set();
+ $multifolder = $search_set && $search_set[1]->multi;
+ if ($multifolder && !in_array('folder', $a_show_cols)) {
+ $a_show_cols[] = 'folder';
+ $head_replace = true;
+ }
+
$mbox = $RCMAIL->storage->get_folder();
// make sure 'threads' and 'subject' columns are present
@@ -342,8 +391,6 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
if (!in_array('threads', $a_show_cols))
array_unshift($a_show_cols, 'threads');
- $_SESSION['list_attrib']['columns'] = $a_show_cols;
-
// Make sure there are no duplicated columns (#1486999)
$a_show_cols = array_unique($a_show_cols);
@@ -364,6 +411,12 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
$OUTPUT->command('set_message_coltypes', $a_show_cols, $thead, $smart_col);
+ if ($multifolder && $_SESSION['search_scope'] == 'all') {
+ $OUTPUT->command('select_folder', '');
+ }
+
+ $OUTPUT->set_env('multifolder_listing', $multifolder);
+
if (empty($a_headers)) {
return;
}
@@ -380,6 +433,14 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
if (empty($header))
continue;
+ // make message UIDs unique by appending the folder name
+ if ($multifolder) {
+ $header->uid .= '-'.$header->folder;
+ $header->flags['skip_mbox_check'] = true;
+ if ($header->parent_uid)
+ $header->parent_uid .= '-'.$header->folder;
+ }
+
$a_msg_cols = array();
$a_msg_flags = array();
@@ -398,6 +459,8 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
$cont = show_bytes($header->$col);
else if ($col == 'date')
$cont = $RCMAIL->format_date($header->date);
+ else if ($col == 'folder')
+ $cont = rcube::Q(rcube_charset::convert($header->folder, 'UTF7-IMAP'));
else
$cont = rcube::Q($header->$col);
@@ -421,7 +484,7 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
$a_msg_flags['prio'] = (int) $header->priority;
$a_msg_flags['ctype'] = rcube::Q($header->ctype);
- $a_msg_flags['mbox'] = $mbox;
+ $a_msg_flags['mbox'] = $header->folder;
// merge with plugin result (Deprecated, use $header->flags)
if (!empty($header->list_flags) && is_array($header->list_flags))
@@ -481,7 +544,7 @@ function rcmail_message_list_head($attrib, $a_show_cols)
$list_menu = '';
}
- $cells = array();
+ $cells = $coltypes = array();
// get name of smart From/To column in folder context
if (array_search('fromto', $a_show_cols) !== false) {
@@ -489,32 +552,39 @@ function rcmail_message_list_head($attrib, $a_show_cols)
}
foreach ($a_show_cols as $col) {
+ $label = '';
+ $sortable = false;
+
// get column name
switch ($col) {
case 'flag':
- $col_name = '<span class="flagged">&nbsp;</span>';
+ $col_name = html::span('flagged', '&nbsp;');
break;
case 'attachment':
case 'priority':
case 'status':
- $col_name = '<span class="' . $col .'">&nbsp;</span>';
+ $col_name = html::span($col, '&nbsp;');
break;
case 'threads':
$col_name = $list_menu;
break;
case 'fromto':
- $col_name = rcube::Q($RCMAIL->gettext($smart_col));
+ $label = $RCMAIL->gettext($smart_col);
+ $col_name = rcube::Q($label);
break;
default:
- $col_name = rcube::Q($RCMAIL->gettext($col));
+ $label = $RCMAIL->gettext($col);
+ $col_name = rcube::Q($label);
}
// make sort links
if (in_array($col, $a_sort_cols)) {
+ $sortable = true;
$col_name = html::a(array(
- 'href' => "./#sort",
- 'onclick' => 'return '.rcmail_output::JS_OBJECT_NAME.".command('sort','".$col."',this)",
- 'title' => $RCMAIL->gettext('sortby')
+ 'href' => "./#sort",
+ 'class' => 'sortcol',
+ 'rel' => $col,
+ 'title' => $RCMAIL->gettext('sortby')
), $col_name);
}
else if ($col_name[0] != '<') {
@@ -526,8 +596,10 @@ function rcmail_message_list_head($attrib, $a_show_cols)
// put it all together
$cells[] = array('className' => $class_name, 'id' => "rcm$col", 'html' => $col_name);
+ $coltypes[$col] = array('className' => $class_name, 'id' => "rcm$col", 'label' => $label, 'sortable' => $sortable);
}
+ $RCMAIL->output->set_env('coltypes', $coltypes);
return $cells;
}
@@ -583,7 +655,7 @@ function rcmail_get_messagecount_text($count = null, $page = null)
$max = $RCMAIL->storage->count(NULL, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL');
if ($max == 0)
- $out = $RCMAIL->gettext('mailboxempty');
+ $out = $RCMAIL->storage->get_search_set() ? $RCMAIL->gettext('nomessages') : $RCMAIL->gettext('mailboxempty');
else
$out = $RCMAIL->gettext(array('name' => $RCMAIL->storage->get_threading() ? 'threadsfromto' : 'messagesfromto',
'vars' => array('from' => $start_msg,
@@ -806,95 +878,29 @@ function rcmail_print_body($part, $p = array())
// plaintext postprocessing
if ($part->ctype_secondary == 'plain') {
- if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') {
- $body = rcube_mime::unfold_flowed($body);
- }
-
- $body = rcmail_plain_body($body);
+ $body = rcmail_plain_body($body, $part->ctype_parameters['format'] == 'flowed');
}
// allow post-processing of the message body
$data = $RCMAIL->plugins->exec_hook('message_part_after',
array('type' => $part->ctype_secondary, 'body' => $body, 'id' => $part->mime_id) + $data);
- return $data['type'] == 'html' ? $data['body'] : html::tag('pre', array(), $data['body']);
+ return $data['body'];
}
/**
* Handle links and citation marks in plain text message
*
* @param string Plain text string
+ * @param boolean Set to True if the source text is in format=flowed
*
* @return string Formatted HTML string
*/
-function rcmail_plain_body($body)
+function rcmail_plain_body($body, $flowed = false)
{
- global $RCMAIL;
-
- // make links and email-addresses clickable
- $attribs = array('link_attribs' => array('rel' => 'noreferrer', 'target' => '_blank'));
- $replacer = new rcmail_string_replacer($attribs);
-
- // search for patterns like links and e-mail addresses and replace with tokens
- $body = $replacer->replace($body);
-
- // split body into single lines
- $body = preg_split('/\r?\n/', $body);
- $quote_level = 0;
- $last = -1;
-
- // find/mark quoted lines...
- for ($n=0, $cnt=count($body); $n < $cnt; $n++) {
- if ($body[$n][0] == '>' && preg_match('/^(>+ {0,1})+/', $body[$n], $regs)) {
- $q = substr_count($regs[0], '>');
- $body[$n] = substr($body[$n], strlen($regs[0]));
-
- if ($q > $quote_level) {
- $body[$n] = $replacer->get_replacement($replacer->add(
- str_repeat('<blockquote>', $q - $quote_level))) . $body[$n];
- $last = $n;
- }
- else if ($q < $quote_level) {
- $body[$n] = $replacer->get_replacement($replacer->add(
- str_repeat('</blockquote>', $quote_level - $q))) . $body[$n];
- $last = $n;
- }
- }
- else {
- $q = 0;
- if ($quote_level > 0)
- $body[$n] = $replacer->get_replacement($replacer->add(
- str_repeat('</blockquote>', $quote_level))) . $body[$n];
- }
-
- $quote_level = $q;
- }
-
- $body = join("\n", $body);
-
- // quote plain text (don't use rcube::Q() here, to display entities "as is")
- $table = get_html_translation_table(HTML_SPECIALCHARS);
- unset($table['?']);
- $body = strtr($body, $table);
-
- // colorize signature (up to <sig_max_lines> lines)
- $len = strlen($body);
- $sig_max_lines = $RCMAIL->config->get('sig_max_lines', 15);
-
- while (($sp = strrpos($body, "-- \n", $sp ? -$len+$sp-1 : 0)) !== false) {
- if ($sp == 0 || $body[$sp-1] == "\n") {
- // do not touch blocks with more that X lines
- if (substr_count($body, "\n", $sp) < $sig_max_lines) {
- $body = substr($body, 0, max(0, $sp))
- . '<span class="sig">'.substr($body, $sp).'</span>';
- }
-
- break;
- }
- }
-
- // insert url/mailto links and citation tags
- $body = $replacer->resolve($body);
+ $options = array('flowed' => $flowed, 'wrap' => !$flowed);
+ $text2html = new rcube_text2html($body, false, $options);
+ $body = $text2html->get_html();
return $body;
}
@@ -1049,7 +1055,9 @@ function rcmail_message_headers($attrib, $headers=null)
$plugin = $RCMAIL->plugins->exec_hook('message_headers_output', array(
'output' => $output_headers,
'headers' => $headers_obj,
- 'exclude' => $exclude_headers
+ 'exclude' => $exclude_headers, // readonly
+ 'folder' => $MESSAGE->folder, // readonly
+ 'uid' => $MESSAGE->uid, // readonly
));
// single header value is requested
@@ -1224,8 +1232,8 @@ function rcmail_message_body($attrib)
$plugin = $RCMAIL->plugins->exec_hook('message_body_prefix',
array('part' => $MESSAGE, 'prefix' => ''));
- $out .= html::div('message-part', $plugin['prefix'] . html::tag('pre', array(),
- rcmail_plain_body(rcube::Q($MESSAGE->body, 'strict', false))));
+ $out .= html::div('message-part',
+ $plugin['prefix'] . rcmail_plain_body($MESSAGE->body));
}
}
@@ -1295,12 +1303,10 @@ function rcmail_message_body($attrib)
function rcmail_part_image_type($part)
{
- $rcmail = rcmail::get_instance();
-
// Skip TIFF images if browser doesn't support this format...
$tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']);
// until we can convert them to JPEG
- $tiff_support = $tiff_support || $rcmail->config->get('im_convert_path');
+ $tiff_support = $tiff_support || rcube_image::is_convertable('image/tiff');
// Content-type regexp
$mime_regex = $tiff_support ? '/^image\//i' : '/^image\/(?!tif)/i';
@@ -1693,7 +1699,8 @@ function rcmail_draftinfo_encode($p)
{
$parts = array();
foreach ($p as $key => $val) {
- $parts[] = $key . '=' . ($key == 'folder' ? base64_encode($val) : $val);
+ $encode = $key == 'folder' || strpos($val, ';') !== false;
+ $parts[] = $key . '=' . ($encode ? 'B::' . base64_encode($val) : $val);
}
return join('; ', $parts);
@@ -1705,7 +1712,10 @@ function rcmail_draftinfo_decode($str)
foreach (preg_split('/;\s+/', $str) as $part) {
list($key, $val) = explode('=', $part, 2);
- if ($key == 'folder') {
+ if (strpos($val, 'B::') === 0) {
+ $val = base64_decode(substr($val, 3));
+ }
+ else if ($key == 'folder') {
$val = base64_decode($val);
}
@@ -1984,7 +1994,7 @@ function rcmail_search_filter($attrib)
$ctypes = array('application/', 'multipart/m', 'multipart/signed', 'multipart/report');
// Build search string of "with attachment" filter
- $attachment = str_repeat(' OR', count($ctypes)-1);
+ $attachment = trim(str_repeat(' OR', count($ctypes)-1));
foreach ($ctypes as $type) {
$attachment .= ' HEADER Content-Type ' . rcube_imap_generic::escape($type);
}
@@ -2070,6 +2080,58 @@ function rcmail_message_import_form($attrib = array())
$content);
$RCMAIL->output->add_gui_object('importform', $attrib['id'].'Frm');
+ $RCMAIL->output->add_label('selectimportfile','importwait');
return html::div($attrib, $out);
}
+
+/**
+ * Add groups from the given address source to the address book widget
+ */
+function rcmail_compose_contact_groups($abook, $source_id, $search = null, $search_mode = 0)
+{
+ global $RCMAIL, $OUTPUT;
+
+ $jsresult = array();
+ foreach ($abook->list_groups($search, $search_mode) as $group) {
+ $abook->reset();
+ $abook->set_group($group['ID']);
+ $group_prop = $abook->get_group($group['ID']);
+
+ // group (distribution list) with email address(es)
+ if ($group_prop['email']) {
+ foreach ((array)$group_prop['email'] as $email) {
+ $row_id = 'G'.$group['ID'];
+ $jsresult[$row_id] = format_email_recipient($email, $group['name']);
+ $OUTPUT->command('add_contact_row', $row_id, array(
+ 'contactgroup' => html::span(array('title' => $email), rcube::Q($group['name']))), 'group');
+ }
+ }
+ // make virtual groups clickable to list their members
+ else if ($group_prop['virtual']) {
+ $row_id = 'G'.$group['ID'];
+ $OUTPUT->command('add_contact_row', $row_id, array(
+ 'contactgroup' => html::a(array(
+ 'href' => '#list',
+ 'rel' => $group['ID'],
+ 'title' => $RCMAIL->gettext('listgroup'),
+ 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)",
+ rcmail_output::JS_OBJECT_NAME, $source_id, $group['ID']),
+ ), rcube::Q($group['name']) . '&nbsp;' . html::span('action', '&raquo;'))),
+ 'group',
+ array('ID' => $group['ID'], 'name' => $group['name'], 'virtual' => true));
+ }
+ // show group with count
+ else if (($result = $abook->count()) && $result->count) {
+ $row_id = 'E'.$group['ID'];
+ $jsresult[$row_id] = $group['name'];
+ $OUTPUT->command('add_contact_row', $row_id, array(
+ 'contactgroup' => rcube::Q($group['name'] . ' (' . intval($result->count) . ')')), 'group');
+ }
+ }
+
+ $abook->reset();
+ $abook->set_group(0);
+
+ return $jsresult;
+}
diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc
index 8f869c67c..02d57c7dc 100644
--- a/program/steps/mail/get.inc
+++ b/program/steps/mail/get.inc
@@ -221,7 +221,7 @@ else if (strlen($part_id)) {
// TIFF to JPEG conversion, if needed
$tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']);
if (!empty($_REQUEST['_embed']) && !$tiff_support
- && $RCMAIL->config->get('im_convert_path')
+ && rcube_image::is_convertable('image/tiff')
&& rcmail_part_image_type($part) == 'image/tiff'
) {
$tiff2jpeg = true;
@@ -293,9 +293,7 @@ else if (strlen($part_id)) {
$filename = rcmail_attachment_name($part);
- if ($browser->ie && $browser->ver < 7)
- $filename = rawurlencode(abbreviate_string($filename, 55));
- else if ($browser->ie)
+ if ($browser->ie)
$filename = rawurlencode($filename);
else
$filename = addcslashes($filename, '"');
diff --git a/program/steps/mail/import.inc b/program/steps/mail/import.inc
index 4f822e0e4..ef78ad945 100644
--- a/program/steps/mail/import.inc
+++ b/program/steps/mail/import.inc
@@ -5,7 +5,7 @@
| program/steps/mail/import.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, The Roundcube Dev Team |
+ | Copyright (C) 2005-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -16,6 +16,7 @@
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+ | Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
@@ -31,48 +32,62 @@ if (is_array($_FILES['_file'])) {
if (!$err) {
// check file content type first
- list($mtype_primary,) = explode('/', rcube_mime::file_content_type($filepath, $_FILES['_file']['name'][$i], $_FILES['_file']['type'][$i]));
+ $ctype = rcube_mime::file_content_type($filepath, $_FILES['_file']['name'][$i], $_FILES['_file']['type'][$i]);
+ list($mtype_primary, $mtype_secondary) = explode('/', $ctype);
- if (!in_array($mtype_primary, array('text','message'))) {
- $OUTPUT->show_message('importmessageerror', 'error');
+ if (in_array($ctype, array('application/zip', 'application/x-zip'))) {
+ $filepath = rcmail_zip_extract($filepath);
+ if (empty($filepath)) {
+ continue;
+ }
+ }
+ else if (!in_array($mtype_primary, array('text', 'message'))) {
continue;
}
- // read the first few lines to detect header-like structure
- $fp = fopen($filepath, 'r');
- do {
- $line = fgets($fp);
- }
- while ($line !== false && trim($line) == '');
+ foreach ((array) $filepath as $file) {
+ // read the first few lines to detect header-like structure
+ $fp = fopen($file, 'r');
+ do {
+ $line = fgets($fp);
+ }
+ while ($line !== false && trim($line) == '');
- if (!preg_match('/^From\s+-/', $line) && !preg_match('/^[a-z-_]+:\s+.+/i', $line)) {
- $OUTPUT->show_message('importmessageerror', 'error');
- continue;
- }
+ if (!preg_match('/^From .+/', $line) && !preg_match('/^[a-z-_]+:\s+.+/i', $line)) {
+ continue;
+ }
- $message = $lastline = '';
- fseek($fp, 0);
- while (($line = fgets($fp)) !== false) {
- // importing mbox file, split by From - lines
- if (preg_match('/^From\s+-/', $line) && $lastline == '') {
- if (!empty($message)) {
- if ($RCMAIL->storage->save_message(null, rtrim($message))) {
- $imported++;
- }
- else {
- rcube::raise_error("Failed to import message to " . $RCMAIL->storage->get_folder(), false, true);
+ $message = $lastline = '';
+ fseek($fp, 0);
+ while (($line = fgets($fp)) !== false) {
+ // importing mbox file, split by From - lines
+ if ($lastline === '' && strncmp($line, 'From ', 5) === 0 && strlen($line) > 5) {
+ if (!empty($message)) {
+ // unquote ">From " lines in message body
+ $message = preg_replace('/\n>([>]*)From /', "\n\\1From ", $message);
+ if ($RCMAIL->storage->save_message(null, rtrim($message))) {
+ $imported++;
+ }
+ else {
+ rcube::raise_error("Failed to import message to " . $RCMAIL->storage->get_folder(), false, true);
+ }
+ $message = '';
}
- $message = '';
+ continue;
}
- continue;
+
+ $message .= $line;
+ $lastline = rtrim($line);
}
- $message .= $line;
- $lastline = rtrim($line);
- }
+ if (!empty($message) && $RCMAIL->storage->save_message(null, rtrim($message))) {
+ $imported++;
+ }
- if (!empty($message) && $RCMAIL->storage->save_message(null, rtrim($message))) {
- $imported++;
+ // remove temp files extracted from zip
+ if (is_array($filepath)) {
+ unlink($file);
+ }
}
}
@@ -106,3 +121,39 @@ else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// send html page with JS calls as response
$OUTPUT->send('iframe');
+
+
+function rcmail_zip_extract($path)
+{
+ if (!class_exists('ZipArchive', false)) {
+ return;
+ }
+
+ $rcmail = rcmail::get_instance();
+ $temp_dir = $rcmail->config->get('temp_dir');
+ $zip = new ZipArchive;
+ $files = array();
+
+ if ($zip->open($path)) {
+ for ($i = 0; $i < $zip->numFiles; $i++) {
+ $entry = $zip->getNameIndex($i);
+ $tmpfname = tempnam($temp_dir, 'zipimport');
+
+ if (copy("zip://$path#$entry", $tmpfname)) {
+ $ctype = rcube_mime::file_content_type($tmpfname, $entry);
+ list($mtype_primary, $mtype_secondary) = explode('/', $ctype);
+
+ if (in_array($mtype_primary, array('text', 'message'))) {
+ $files[] = $tmpfname;
+ }
+ else {
+ unlink($tmpfname);
+ }
+ }
+ }
+
+ $zip->close();
+ }
+
+ return $files;
+}
diff --git a/program/steps/mail/list.inc b/program/steps/mail/list.inc
index 277564c38..929dda299 100644
--- a/program/steps/mail/list.inc
+++ b/program/steps/mail/list.inc
@@ -5,7 +5,7 @@
| program/steps/mail/list.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2007, The Roundcube Dev Team |
+ | Copyright (C) 2005-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -42,6 +42,7 @@ if ($sort = rcube_utils::get_input_value('_sort', rcube_utils::INPUT_GET)) {
// is there a set of columns for this request?
if ($cols = rcube_utils::get_input_value('_cols', rcube_utils::INPUT_GET)) {
+ $_SESSION['list_attrib']['columns'] = explode(',', $cols);
if (!in_array('list_cols', $dont_override)) {
$save_arr['list_cols'] = explode(',', $cols);
}
@@ -59,11 +60,12 @@ $RCMAIL->storage->folder_sync($mbox_name);
// initialize searching result if search_filter is used
if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') {
- $search_request = md5($mbox_name.$_SESSION['search_filter']);
+ $search_request = md5($mbox_name.$_SESSION['search_scope'].$_SESSION['search_filter']);
$RCMAIL->storage->search($mbox_name, $_SESSION['search_filter'], RCUBE_CHARSET, rcmail_sort_column());
$_SESSION['search'] = $RCMAIL->storage->get_search_set();
$_SESSION['search_request'] = $search_request;
$OUTPUT->set_env('search_request', $search_request);
+ $OUTPUT->set_env('search_filter', $_SESSION['search_filter']);
}
// fetch message headers
@@ -91,7 +93,7 @@ rcmail_send_unread_count($mbox_name, !empty($_REQUEST['_refresh']), $unseen);
// update message count display
$pages = ceil($count/$RCMAIL->storage->get_pagesize());
-$exists = $RCMAIL->storage->count($mbox_name, 'EXISTS');
+$exists = $RCMAIL->storage->count($mbox_name, 'EXISTS', true);
$OUTPUT->set_env('messagecount', $count);
$OUTPUT->set_env('pagecount', $pages);
@@ -100,8 +102,14 @@ $OUTPUT->set_env('current_page', $count ? $RCMAIL->storage->get_page() : 1);
$OUTPUT->set_env('exists', $exists);
$OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($count), $mbox_name);
+// remove old message rows if commanded by the client
+if (!empty($_REQUEST['_clear'])) {
+ $OUTPUT->command('clear_message_list');
+}
+
// add message rows
-rcmail_js_message_list($a_headers, FALSE, $cols);
+rcmail_js_message_list($a_headers, false, $cols);
+
if (isset($a_headers) && count($a_headers)) {
if ($search_request) {
$OUTPUT->show_message('searchsuccessful', 'confirmation', array('nr' => $count));
diff --git a/program/steps/mail/list_contacts.inc b/program/steps/mail/list_contacts.inc
index 46f81353a..0ee81135b 100644
--- a/program/steps/mail/list_contacts.inc
+++ b/program/steps/mail/list_contacts.inc
@@ -5,7 +5,7 @@
| program/steps/mail/list_contacts.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -23,15 +23,22 @@ $afields = $RCMAIL->config->get('contactlist_fields');
$addr_sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
$list_page = max(1, intval($_GET['_page']));
+$jsresult = array();
// Use search result
if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) {
$search = (array)$_SESSION['search'][$_REQUEST['_search']];
+ $sparam = $_SESSION['search_params']['id'] == $_REQUEST['_search'] ? $_SESSION['search_params']['data'] : array();
// get records from all sources
foreach ($search as $s => $set) {
$CONTACTS = $RCMAIL->get_address_book($s);
+ // list matching groups of this source (on page one)
+ if ($sparam[1] && $CONTACTS->groups && $list_page == 1) {
+ $jsresult += rcmail_compose_contact_groups($CONTACTS, $s, $sparam[1], (int)$RCMAIL->config->get('addressbook_search_mode'));
+ }
+
// reset page
$CONTACTS->set_page(1);
$CONTACTS->set_pagesize(9999);
@@ -78,44 +85,7 @@ else {
}
// list groups of this source (on page one)
else if ($CONTACTS->groups && $CONTACTS->list_page == 1) {
- foreach ($CONTACTS->list_groups() as $group) {
- $CONTACTS->reset();
- $CONTACTS->set_group($group['ID']);
- $group_prop = $CONTACTS->get_group($group['ID']);
-
- // group (distribution list) with email address(es)
- if ($group_prop['email']) {
- foreach ((array)$group_prop['email'] as $email) {
- $row_id = 'G'.$group['ID'];
- $jsresult[$row_id] = format_email_recipient($email, $group['name']);
- $OUTPUT->command('add_contact_row', $row_id, array(
- 'contactgroup' => html::span(array('title' => $email), rcube::Q($group['name']))), 'group');
- }
- }
- // make virtual groups clickable to list their members
- else if ($group_prop['virtual']) {
- $row_id = 'G'.$group['ID'];
- $OUTPUT->command('add_contact_row', $row_id, array(
- 'contactgroup' => html::a(array(
- 'href' => '#list',
- 'rel' => $row['ID'],
- 'title' => $RCMAIL->gettext('listgroup'),
- 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", rcmail_output::JS_OBJECT_NAME, $source, $group['ID']),
- ), rcube::Q($group['name']) . '&nbsp;' . html::span('action', '&raquo;'))),
- 'group',
- array('ID' => $group['ID'], 'name' => $group['name'], 'virtual' => true));
- }
- // show group with count
- else if (($result = $CONTACTS->count()) && $result->count) {
- $row_id = 'E'.$group['ID'];
- $jsresult[$row_id] = $group['name'];
- $OUTPUT->command('add_contact_row', $row_id, array(
- 'contactgroup' => rcube::Q($group['name'] . ' (' . intval($result->count) . ')')), 'group');
- }
- }
-
- $CONTACTS->reset();
- $CONTACTS->set_group(0);
+ $jsresult = rcmail_compose_contact_groups($CONTACTS, $source);
}
// get contacts for this user
diff --git a/program/steps/mail/mark.inc b/program/steps/mail/mark.inc
index daa8c7e54..4e83f975c 100644
--- a/program/steps/mail/mark.inc
+++ b/program/steps/mail/mark.inc
@@ -4,7 +4,7 @@
| program/steps/mail/mark.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, The Roundcube Dev Team |
+ | Copyright (C) 2005-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -36,7 +36,7 @@ $a_flags_map = array(
'unflagged' => 'UNFLAGGED',
);
-if (($uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST))
+if (($_uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST))
&& ($flag = rcube_utils::get_input_value('_flag', rcube_utils::INPUT_POST))
) {
$flag = $a_flags_map[$flag] ? $a_flags_map[$flag] : strtoupper($flag);
@@ -45,10 +45,12 @@ if (($uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST))
// count messages before changing anything
$old_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL');
$old_pages = ceil($old_count / $RCMAIL->storage->get_pagesize());
- $count = sizeof(explode(',', $uids));
}
- $marked = $RCMAIL->storage->set_flag($uids, $flag);
+ foreach (rcmail::get_uids() as $mbox => $uids) {
+ $marked += (int)$RCMAIL->storage->set_flag($uids, $flag, $mbox);
+ $count += count($uids);
+ }
if (!$marked) {
// send error message
@@ -66,7 +68,9 @@ if (($uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST))
if ($flag == 'DELETED' && $read_deleted && !empty($_POST['_ruid'])) {
$ruids = rcube_utils::get_input_value('_ruid', rcube_utils::INPUT_POST);
- $read = $RCMAIL->storage->set_flag($ruids, 'SEEN');
+ foreach (rcmail::get_uids($ruids) as $mbox => $uids) {
+ $read += (int)$RCMAIL->storage->set_flag($uids, 'SEEN', $mbox);
+ }
if ($read && !$skip_deleted) {
$OUTPUT->command('flag_deleted_as_read', $ruids);
@@ -74,7 +78,9 @@ if (($uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST))
}
if ($flag == 'SEEN' || $flag == 'UNSEEN' || ($flag == 'DELETED' && !$skip_deleted)) {
- rcmail_send_unread_count($RCMAIL->storage->get_folder());
+ foreach (rcmail::get_uids() as $mbox => $uids) {
+ rcmail_send_unread_count($mbox);
+ }
}
else if ($flag == 'DELETED' && $skip_deleted) {
if ($_POST['_from'] == 'show') {
@@ -128,7 +134,7 @@ if (($uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST))
}
// add new rows from next page (if any)
- if ($count && $uids != '*' && ($jump_back || $nextpage_count > 0)) {
+ if ($old_count && $_uids != '*' && ($jump_back || $nextpage_count > 0)) {
$a_headers = $RCMAIL->storage->list_messages($mbox, NULL,
rcmail_sort_column(), rcmail_sort_order(), $jump_back ? NULL : $count);
diff --git a/program/steps/mail/move_del.inc b/program/steps/mail/move_del.inc
index 7564bb89d..d98d49d1f 100644
--- a/program/steps/mail/move_del.inc
+++ b/program/steps/mail/move_del.inc
@@ -5,7 +5,7 @@
| program/steps/mail/move_del.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2009, The Roundcube Dev Team |
+ | Copyright (C) 2005-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -32,13 +32,23 @@ $trash = $RCMAIL->config->get('trash_mbox');
// move messages
if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
- $count = sizeof(explode(',', ($uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST))));
$target = rcube_utils::get_input_value('_target_mbox', rcube_utils::INPUT_POST, true);
- $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true);
-
- $moved = $RCMAIL->storage->move_message($uids, $target, $mbox);
+ $trash = $RCMAIL->config->get('trash_mbox');
+
+ $success = true;
+ foreach (rcmail::get_uids() as $mbox => $uids) {
+ if ($mbox === $target) {
+ $count += count($uids);
+ }
+ else if ($RCMAIL->storage->move_message($uids, $target, $mbox)) {
+ $count += count($uids);
+ }
+ else {
+ $success = false;
+ }
+ }
- if (!$moved) {
+ if (!$success) {
// send error message
if ($_POST['_from'] != 'show')
$OUTPUT->command('list_mailbox');
@@ -47,17 +57,23 @@ if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_targe
exit;
}
else {
- $OUTPUT->show_message('messagemoved', 'confirmation');
+ $OUTPUT->show_message('messagemoved', 'confirmation');
}
- $addrows = true;
+ if (!empty($_POST['_refresh'])) {
+ // FIXME: send updated message rows instead of releading the entire list
+ $OUTPUT->command('refresh_list');
+ }
+ else {
+ $addrows = true;
+ }
}
// delete messages
else if ($RCMAIL->action=='delete' && !empty($_POST['_uid'])) {
- $count = sizeof(explode(',', ($uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST))));
- $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true);
-
- $del = $RCMAIL->storage->delete_message($uids, $mbox);
+ foreach (rcmail::get_uids() as $mbox => $uids) {
+ $del += (int)$RCMAIL->storage->delete_message($uids, $mbox);
+ $count += count($uids);
+ }
if (!$del) {
// send error message
@@ -68,7 +84,7 @@ else if ($RCMAIL->action=='delete' && !empty($_POST['_uid'])) {
exit;
}
else {
- $OUTPUT->show_message('messagedeleted', 'confirmation');
+ $OUTPUT->show_message('messagedeleted', 'confirmation');
}
$addrows = true;
@@ -150,7 +166,7 @@ else {
$OUTPUT->command('set_trash_count', $exists);
}
else if ($target !== null && $target === $trash) {
- $OUTPUT->command('set_trash_count', $RCMAIL->storage->count($trash, 'EXISTS'));
+ $OUTPUT->command('set_trash_count', $RCMAIL->storage->count($trash, 'EXISTS', true));
}
}
diff --git a/program/steps/mail/search.inc b/program/steps/mail/search.inc
index a80887254..4aa22e14b 100644
--- a/program/steps/mail/search.inc
+++ b/program/steps/mail/search.inc
@@ -21,6 +21,8 @@
$REMOTE_REQUEST = TRUE;
+@set_time_limit(170); // extend default max_execution_time to ~3 minutes
+
// reset list_page and old search results
$RCMAIL->storage->set_page(1);
$RCMAIL->storage->set_search_set(NULL);
@@ -35,9 +37,12 @@ $str = rcube_utils::get_input_value('_q', rcube_utils::INPUT_GET, true);
$mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GET, true);
$filter = rcube_utils::get_input_value('_filter', rcube_utils::INPUT_GET);
$headers = rcube_utils::get_input_value('_headers', rcube_utils::INPUT_GET);
+$scope = rcube_utils::get_input_value('_scope', rcube_utils::INPUT_GET);
+$continue = rcube_utils::get_input_value('_continue', rcube_utils::INPUT_GET);
$subject = array();
-$search_request = md5($mbox.$filter.$str);
+$filter = trim($filter);
+$search_request = md5($mbox.$scope.$filter.$str);
// add list filter string
$search_str = $filter && $filter != 'ALL' ? $filter : '';
@@ -83,8 +88,9 @@ else if (strlen(trim($str))) {
}
// save search modifiers for the current folder to user prefs
+ $mkey = $scope == 'all' ? '*' : $mbox;
$search_mods = rcmail_search_mods();
- $search_mods[$mbox] = array_fill_keys(array_keys($subject), 1);
+ $search_mods[$mkey] = array_fill_keys(array_keys($subject), 1);
$RCMAIL->user->save_prefs(array('search_mods' => $search_mods));
}
@@ -106,9 +112,26 @@ if (!empty($subject)) {
$search_str = trim($search_str);
$sort_column = rcmail_sort_column();
+// set message set for already stored (but incomplete) search request
+if (!empty($continue) && isset($_SESSION['search']) && $_SESSION['search_request'] == $continue) {
+ $RCMAIL->storage->set_search_set($_SESSION['search']);
+ $search_str = $_SESSION['search'][0];
+}
+
// execute IMAP search
if ($search_str) {
- $RCMAIL->storage->search($mbox, $search_str, $imap_charset, $sort_column);
+ // search all, current or subfolders folders
+ if ($scope == 'all') {
+ $mboxes = $RCMAIL->storage->list_folders_subscribed('', '*', 'mail', null, true);
+ natcasesort($mboxes); // we want natural alphabetic sorting of folders in the result set
+ }
+ else if ($scope == 'sub') {
+ $mboxes = $RCMAIL->storage->list_folders_subscribed($mbox, '*', 'mail');
+ if ($mbox != 'INBOX' && $mboxes[0] == 'INBOX')
+ array_shift($mboxes);
+ }
+
+ $result = $RCMAIL->storage->search($mboxes, $search_str, $imap_charset, $sort_column);
}
// save search results in session
@@ -121,38 +144,54 @@ if ($search_str) {
$_SESSION['last_text_search'] = $str;
}
$_SESSION['search_request'] = $search_request;
+$_SESSION['search_scope'] = $scope;
// Get the headers
-$result_h = $RCMAIL->storage->list_messages($mbox, 1, $sort_column, rcmail_sort_order());
-$count = $RCMAIL->storage->count($mbox, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL');
+if (!$result->incomplete) {
+ $result_h = $RCMAIL->storage->list_messages($mbox, 1, $sort_column, rcmail_sort_order());
+ $count = $RCMAIL->storage->count($mbox, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL');
+}
// Make sure we got the headers
if (!empty($result_h)) {
- rcmail_js_message_list($result_h);
+ rcmail_js_message_list($result_h, false);
if ($search_str) {
$OUTPUT->show_message('searchsuccessful', 'confirmation', array('nr' => $RCMAIL->storage->count(NULL, 'ALL')));
}
// remember last HIGHESTMODSEQ value (if supported)
// we need it for flag updates in check-recent
- $data = $RCMAIL->storage->folder_data($mbox_name);
- if (!empty($data['HIGHESTMODSEQ'])) {
- $_SESSION['list_mod_seq'] = $data['HIGHESTMODSEQ'];
+ if ($mbox !== null) {
+ $data = $RCMAIL->storage->folder_data($mbox);
+ if (!empty($data['HIGHESTMODSEQ'])) {
+ $_SESSION['list_mod_seq'] = $data['HIGHESTMODSEQ'];
+ }
}
}
// handle IMAP errors (e.g. #1486905)
-else if ($err_code = $RCMAIL->storage->get_error_code()) {
+else if ($err_code = $RCMAIL->storage->get_error_code()) {
$RCMAIL->display_server_error();
}
+// advice the client to re-send the (cross-folder) search request
+else if ($result->incomplete) {
+ $count = 0; // keep UI locked
+ $OUTPUT->command('continue_search', $search_request);
+}
else {
$OUTPUT->show_message('searchnomatch', 'notice');
+ $OUTPUT->set_env('multifolder_listing', (bool)$result->multi);
+ if ($result->multi && $scope == 'all')
+ $OUTPUT->command('select_folder', '');
}
// update message count display
$OUTPUT->set_env('search_request', $search_str ? $search_request : '');
+$OUTPUT->set_env('search_filter', $_SESSION['search_filter']);
+$OUTPUT->set_env('threading', $RCMAIL->storage->get_threading());
$OUTPUT->set_env('messagecount', $count);
$OUTPUT->set_env('pagecount', ceil($count/$RCMAIL->storage->get_pagesize()));
-$OUTPUT->set_env('exists', $RCMAIL->storage->count($mbox_name, 'EXISTS'));
+$OUTPUT->set_env('exists', $mbox === null ? 0 : $RCMAIL->storage->count($mbox, 'EXISTS'));
$OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($count, 1), $mbox);
+$OUTPUT->set_pagetitle($RCMAIL->gettext(array('name' => 'searchfor', 'vars' => array('q' => $str))));
$OUTPUT->send();
diff --git a/program/steps/mail/search_contacts.inc b/program/steps/mail/search_contacts.inc
index 4d5abf9ef..d56581695 100644
--- a/program/steps/mail/search_contacts.inc
+++ b/program/steps/mail/search_contacts.inc
@@ -5,7 +5,7 @@
| program/steps/mail/search_contacts.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2013, The Roundcube Dev Team |
+ | Copyright (C) 2013-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -27,12 +27,18 @@ $afields = $RCMAIL->config->get('contactlist_fields');
$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
$records = array();
$search_set = array();
+$jsresult = array();
foreach ($sources as $s) {
$source = $RCMAIL->get_address_book($s['id']);
$source->set_page(1);
$source->set_pagesize(9999);
+ // list matching groups of this source
+ if ($source->groups) {
+ $jsresult += rcmail_compose_contact_groups($source, $s['id'], $search, $search_mode);
+ }
+
// get contacts count
$result = $source->search($afields, $search, $search_mode, true, true, 'email');
@@ -53,6 +59,8 @@ foreach ($sources as $s) {
unset($result);
}
+$group_count = count($jsresult);
+
// sort the records
ksort($records, SORT_LOCALE_STRING);
@@ -98,7 +106,7 @@ if (!empty($result) && $result->count > 0) {
$OUTPUT->command('set_env', 'source', '');
$OUTPUT->command('unselect_directory');
}
-else {
+else if (!$group_count) {
$OUTPUT->show_message('nocontactsfound', 'notice');
}
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 2255acc13..7ae03e522 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -201,7 +201,7 @@ if (!empty($headers['Reply-To'])) {
$headers['Mail-Reply-To'] = $headers['Reply-To'];
}
if ($hdr = rcube_utils::get_input_value('_followupto', rcube_utils::INPUT_POST, TRUE, $message_charset)) {
- $headers['Mail-Followup-To'] = rcmail_email_input_format();
+ $headers['Mail-Followup-To'] = rcmail_email_input_format($hdr);
}
// remember reply/forward UIDs in special headers
@@ -209,7 +209,7 @@ if (!empty($COMPOSE['reply_uid']) && $savedraft) {
$headers['X-Draft-Info'] = array('type' => 'reply', 'uid' => $COMPOSE['reply_uid']);
}
else if (!empty($COMPOSE['forward_uid']) && $savedraft) {
- $headers['X-Draft-Info'] = array('type' => 'forward', 'uid' => $COMPOSE['forward_uid']);
+ $headers['X-Draft-Info'] = array('type' => 'forward', 'uid' => rcube_imap_generic::compressMessageSet($COMPOSE['forward_uid']));
}
if (!empty($COMPOSE['reply_msgid'])) {
@@ -281,13 +281,23 @@ if ($isHtml) {
if (!$savedraft) {
if ($isHtml) {
- // remove signature's div ID
- $message_body = preg_replace('/\s*id="_rc_sig"/', '', $message_body);
-
- // add inline css for blockquotes
- $bstyle = 'padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px';
- $message_body = preg_replace('/<blockquote>/',
- '<blockquote type="cite" style="'.$bstyle.'">', $message_body);
+ $b_style = 'padding: 0 0.4em; border-left: #1010ff 2px solid; margin: 0';
+ $pre_style = 'margin: 0; padding: 0; font-family: monospace';
+
+ $message_body = preg_replace(
+ array(
+ // remove signature's div ID
+ '/\s*id="_rc_sig"/',
+ // add inline css for blockquotes and container
+ '/<blockquote>/',
+ '/<div class="pre">/'
+ ),
+ array(
+ '',
+ '<blockquote type="cite" style="'.$b_style.'">',
+ '<div class="pre" style="'.$pre_style.'">'
+ ),
+ $message_body);
}
// Check spelling before send
@@ -541,10 +551,16 @@ if (!$savedraft) {
}
// set replied/forwarded flag
- if ($COMPOSE['reply_uid'])
- $RCMAIL->storage->set_flag($COMPOSE['reply_uid'], 'ANSWERED', $COMPOSE['mailbox']);
- else if ($COMPOSE['forward_uid'])
- $RCMAIL->storage->set_flag($COMPOSE['forward_uid'], 'FORWARDED', $COMPOSE['mailbox']);
+ if ($COMPOSE['reply_uid']) {
+ foreach (rcmail::get_uids($COMPOSE['reply_uid'], $COMPOSE['mailbox']) as $mbox => $uids) {
+ $RCMAIL->storage->set_flag($uids, 'ANSWERED', $mbox);
+ }
+ }
+ else if ($COMPOSE['forward_uid']) {
+ foreach (rcmail::get_uids($COMPOSE['forward_uid'], $COMPOSE['mailbox']) as $mbox => $uids) {
+ $RCMAIL->storage->set_flag($uids, 'FORWARDED', $mbox);
+ }
+ }
}
// Determine which folder to save message
@@ -913,7 +929,8 @@ function rcmail_generic_message_footer($isHtml)
if (!preg_match('/\.(php|ini|conf)$/', $file) && strpos($file, '/etc/') === false) {
$footer = file_get_contents($file);
if ($isHtml && !$html_footer) {
- $footer = '<pre>' . $footer . '</pre>';
+ $t2h = new rcube_text2html($footer, false);
+ $footer = $t2h->get_html();
}
return $footer;
}
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index 9498d1dc5..beb2cc6e9 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -102,7 +102,7 @@ if ($uid) {
}
if (empty($_SESSION['browser_caps']['tif']) && ($key = array_search('image/tiff', $mimetypes)) !== false) {
// we can convert tiff to jpeg
- if (!$RCMAIL->config->get('im_convert_path')) {
+ if (!rcube_image::is_convertable('image/tiff')) {
unset($mimetypes[$key]);
}
}
diff --git a/program/steps/mail/viewsource.inc b/program/steps/mail/viewsource.inc
index 0328d9600..f988f679a 100644
--- a/program/steps/mail/viewsource.inc
+++ b/program/steps/mail/viewsource.inc
@@ -33,9 +33,7 @@ if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET)) {
$filename = ($subject ? $subject : $RCMAIL->config->get('product_name', 'email')) . '.eml';
$browser = $RCMAIL->output->browser;
- if ($browser->ie && $browser->ver < 7)
- $filename = rawurlencode(abbreviate_string($filename, 55));
- else if ($browser->ie)
+ if ($browser->ie)
$filename = rawurlencode($filename);
else
$filename = addcslashes($filename, '"');
diff --git a/program/steps/settings/edit_folder.inc b/program/steps/settings/edit_folder.inc
index fc6b2cd16..6b7bd08d2 100644
--- a/program/steps/settings/edit_folder.inc
+++ b/program/steps/settings/edit_folder.inc
@@ -139,6 +139,7 @@ function rcmail_folder_form($attrib)
'unsubscribed' => true,
'skip_noinferiors' => true,
'exceptions' => $exceptions,
+ 'additional' => strlen($selected) ? array($selected) : null,
));
$form['props']['fieldsets']['location']['content']['path'] = array(
diff --git a/program/steps/settings/edit_identity.inc b/program/steps/settings/edit_identity.inc
index f208c8a05..3f7b6a58a 100644
--- a/program/steps/settings/edit_identity.inc
+++ b/program/steps/settings/edit_identity.inc
@@ -71,7 +71,7 @@ function rcube_identity_form($attrib)
$RCMAIL->html_editor('identity');
// add some labels to client
- $OUTPUT->add_label('noemailwarning', 'nonamewarning', 'converting', 'editorwarning');
+ $OUTPUT->add_label('noemailwarning', 'converting', 'editorwarning');
$i_size = !empty($attrib['size']) ? $attrib['size'] : 40;
$t_rows = !empty($attrib['textarearows']) ? $attrib['textarearows'] : 6;
diff --git a/program/steps/settings/edit_prefs.inc b/program/steps/settings/edit_prefs.inc
index 05f4db6a6..b72c3e73f 100644
--- a/program/steps/settings/edit_prefs.inc
+++ b/program/steps/settings/edit_prefs.inc
@@ -51,6 +51,10 @@ function rcmail_user_prefs_form($attrib)
$out = $form_start;
+ if(!empty($SECTIONS[$CURR_SECTION]['header'])) {
+ $out .= html::div(array('id' => 'preferences-header', 'class' =>'boxcontent'), $SECTIONS[$CURR_SECTION]['header']);
+ }
+
foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $class => $block) {
if (!empty($block['options'])) {
$table = new html_table(array('cols' => 2));
diff --git a/program/steps/settings/edit_response.inc b/program/steps/settings/edit_response.inc
index 760f28290..6d3c3dc41 100644
--- a/program/steps/settings/edit_response.inc
+++ b/program/steps/settings/edit_response.inc
@@ -35,7 +35,7 @@ if (($key = rcube_utils::get_input_value('_key', rcube_utils::INPUT_GPC))) {
// save response
if ($RCMAIL->action == 'save-response' && isset($_POST['_name']) && !$RESPONSE_RECORD['static']) {
$name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST));
- $text = trim(rcube_utils::get_input_value('_text', rcube_utils::INPUT_POST));
+ $text = trim(rcube_utils::get_input_value('_text', rcube_utils::INPUT_POST, true));
if (!empty($name) && !empty($text)) {
$dupes = 0;
diff --git a/program/steps/settings/folders.inc b/program/steps/settings/folders.inc
index b09ea03ce..1bcfb4cfc 100644
--- a/program/steps/settings/folders.inc
+++ b/program/steps/settings/folders.inc
@@ -45,7 +45,7 @@ if ($RCMAIL->action == 'subscribe') {
if ($result) {
// Handle subscription of protected folder (#1487656)
if ($RCMAIL->config->get('protect_default_folders')
- && in_array($mbox, (array)$RCMAIL->config->get('default_folders'))
+ && $STORAGE->is_special_folder($mbox)
) {
$OUTPUT->command('disable_subscription', $mbox);
}
@@ -221,16 +221,15 @@ function rcube_subscription_form($attrib)
// get folders from server
$STORAGE->clear_cache('mailboxes', true);
- $a_unsubscribed = $STORAGE->list_folders();
- $a_subscribed = $STORAGE->list_folders_subscribed('', '*', null, null, true); // unsorted
- $delimiter = $STORAGE->get_hierarchy_delimiter();
- $namespace = $STORAGE->get_namespace();
- $a_js_folders = array();
- $seen = array();
- $list_folders = array();
-
- $default_folders = (array) $RCMAIL->config->get('default_folders');
+ $a_unsubscribed = $STORAGE->list_folders();
+ $a_subscribed = $STORAGE->list_folders_subscribed('', '*', null, null, true); // unsorted
+ $delimiter = $STORAGE->get_hierarchy_delimiter();
+ $namespace = $STORAGE->get_namespace();
+ $special_folders = array_flip(array_merge(array('inbox' => 'INBOX'), $STORAGE->get_special_folders()));
$protect_default = $RCMAIL->config->get('protect_default_folders');
+ $a_js_folders = array();
+ $seen = array();
+ $list_folders = array();
// pre-process folders list
foreach ($a_unsubscribed as $i => $folder) {
@@ -291,7 +290,7 @@ function rcube_subscription_form($attrib)
$idx = $i + 1;
$sub_key = array_search($folder['id'], $a_subscribed);
$subscribed = $sub_key !== false;
- $protected = $protect_default && in_array($folder['id'], $default_folders);
+ $protected = $protect_default && isset($special_folders[$folder['id']]);
$noselect = false;
$classes = array($i%2 ? 'even' : 'odd');
@@ -368,7 +367,7 @@ function rcube_subscription_form($attrib)
$OUTPUT->add_gui_object('subscriptionlist', $attrib['id']);
$OUTPUT->set_env('subscriptionrows', $a_js_folders);
- $OUTPUT->set_env('defaultfolders', $default_folders);
+ $OUTPUT->set_env('defaultfolders', array_keys($special_folders));
$OUTPUT->set_env('delimiter', $delimiter);
return $form_start . $table->show($attrib) . $form_end;
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index 7c36df3b1..4b4575f10 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -346,6 +346,7 @@ function rcmail_user_prefs($current = null)
$license_link = $meta['license-url'] ? html::a(array('href' => $meta['license-url'], 'target' => '_blank'), rcube::Q($meta['license'])) : rcube::Q($meta['license']);
}
+ $skinnames[] = mb_strtolower($skinname);
$blocks['skin']['options'][$skin]['content'] = html::label(array('class' => 'skinselection'),
html::span('skinitem', $input->show($config['skin'], array('value' => $skin, 'id' => $field_id.$skin))) .
html::span('skinitem', html::img(array('src' => $thumbnail, 'class' => 'skinthumbnail', 'alt' => $skin, 'width' => 64, 'height' => 64))) .
@@ -354,6 +355,7 @@ function rcmail_user_prefs($current = null)
html::span('skinlicense', $license_link ? $RCMAIL->gettext('license').':&nbsp;' . $license_link : ''))
);
}
+ array_multisort($blocks['skin']['options'], SORT_ASC, SORT_STRING, $skinnames);
}
}
@@ -376,13 +378,16 @@ function rcmail_user_prefs($current = null)
if ($current) {
$product_name = $RCMAIL->config->get('product_name', 'Roundcube Webmail');
$RCMAIL->output->add_script(sprintf("%s.check_protocol_handler('%s', '#mailtoprotohandler');",
- rcmail_output::JS_OBJECT_NAME, rcube::JQ($product_name)), 'foot');
+ rcmail_output::JS_OBJECT_NAME, rcube::JQ($product_name)), 'docready');
}
$blocks['browser']['options']['mailtoprotohandler'] = array(
'content' => html::a(array(
- 'href' => '#',
- 'id' => 'mailtoprotohandler'), rcube::Q($RCMAIL->gettext('mailtoprotohandler'))),
+ 'href' => '#',
+ 'id' => 'mailtoprotohandler'
+ ),
+ rcube::Q($RCMAIL->gettext('mailtoprotohandler'))) .
+ html::span('mailtoprotohandler-status', ''),
);
break;
@@ -1032,7 +1037,8 @@ function rcmail_user_prefs($current = null)
}
// Configure special folders
- if (!isset($no_override['default_folders']) && $current) {
+ $set = array('drafts_mbox', 'sent_mbox', 'junk_mbox', 'trash_mbox');
+ if ($current && count(array_intersect($no_override, $set)) < 4) {
$select = $RCMAIL->folder_selector(array(
'noselection' => '---',
'realnames' => true,
@@ -1040,10 +1046,10 @@ function rcmail_user_prefs($current = null)
'folder_filter' => 'mail',
'folder_rights' => 'w',
));
- }
- // #1486114, #1488279, #1489219
- $onchange = "if ($(this).val() == 'INBOX') $(this).val('')";
+ // #1486114, #1488279, #1489219
+ $onchange = "if ($(this).val() == 'INBOX') $(this).val('')";
+ }
if (!isset($no_override['drafts_mbox'])) {
if (!$current) {
@@ -1235,6 +1241,13 @@ function rcmail_user_prefs($current = null)
$sections[$idx]['blocks'] = $data['blocks'];
}
+ $data = $RCMAIL->plugins->exec_hook('preferences_section_header',
+ array('section' => $sect['id'], 'header' => '', 'current' => $current));
+
+ if(!empty($data['header'])) {
+ $sections[$idx]['header'] = $data['header'];
+ }
+
return array($sections, $plugin['cols']);
}
@@ -1284,13 +1297,11 @@ function rcmail_update_folder_row($name, $oldname=null, $subscribe=false, $class
{
global $RCMAIL, $OUTPUT;
- $default_folders = (array) $RCMAIL->config->get('default_folders');
$protect_folders = $RCMAIL->config->get('protect_default_folders');
-
- $storage = $RCMAIL->get_storage();
- $delimiter = $storage->get_hierarchy_delimiter();
- $name_utf8 = rcube_charset::convert($name, 'UTF7-IMAP');
- $protected = $protect_folders && in_array($name, $default_folders);
+ $storage = $RCMAIL->get_storage();
+ $delimiter = $storage->get_hierarchy_delimiter();
+ $name_utf8 = rcube_charset::convert($name, 'UTF7-IMAP');
+ $protected = $protect_folders && $storage->is_special_folder($name);
$foldersplit = explode($delimiter, $storage->mod_folder($name));
$level = count($foldersplit) - 1;
diff --git a/program/steps/settings/responses.inc b/program/steps/settings/responses.inc
index 35a2a1b64..06093b3b8 100644
--- a/program/steps/settings/responses.inc
+++ b/program/steps/settings/responses.inc
@@ -22,7 +22,7 @@
if (!empty($_POST['_insert'])) {
$name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST));
- $text = trim(rcube_utils::get_input_value('_text', rcube_utils::INPUT_POST));
+ $text = trim(rcube_utils::get_input_value('_text', rcube_utils::INPUT_POST, true));
if (!empty($name) && !empty($text)) {
$dupes = 0;
diff --git a/program/steps/settings/save_identity.inc b/program/steps/settings/save_identity.inc
index 1584c5f00..77245b988 100644
--- a/program/steps/settings/save_identity.inc
+++ b/program/steps/settings/save_identity.inc
@@ -26,8 +26,8 @@ $a_boolean_cols = array('standard', 'html_signature');
$updated = $default_id = false;
// check input
-if (IDENTITIES_LEVEL != 4 && (empty($_POST['_name']) || (empty($_POST['_email']) && IDENTITIES_LEVEL != 1 && IDENTITIES_LEVEL != 3))) {
- $OUTPUT->show_message('formincomplete', 'warning');
+if (empty($_POST['_email']) && (IDENTITIES_LEVEL == 0 || IDENTITIES_LEVEL == 2)) {
+ $OUTPUT->show_message('noemailwarning', 'warning');
$RCMAIL->overwrite_action('edit-identity');
return;
}
diff --git a/program/steps/settings/save_prefs.inc b/program/steps/settings/save_prefs.inc
index f71eee39a..7a17f21f4 100644
--- a/program/steps/settings/save_prefs.inc
+++ b/program/steps/settings/save_prefs.inc
@@ -121,12 +121,12 @@ case 'server':
case 'folders':
$a_user_prefs = array(
'show_real_foldernames' => isset($_POST['_show_real_foldernames']) ? true : false,
- 'drafts_mbox' => rcube_utils::get_input_value('_drafts_mbox', rcube_utils::INPUT_POST, true),
- 'sent_mbox' => rcube_utils::get_input_value('_sent_mbox', rcube_utils::INPUT_POST, true),
- 'junk_mbox' => rcube_utils::get_input_value('_junk_mbox', rcube_utils::INPUT_POST, true),
- 'trash_mbox' => rcube_utils::get_input_value('_trash_mbox', rcube_utils::INPUT_POST, true),
);
+ foreach (rcube_storage::$folder_types as $type) {
+ $a_user_prefs[$type . '_mbox'] = rcube_utils::get_input_value('_' . $type . '_mbox', rcube_utils::INPUT_POST, true);
+ };
+
break;
}
@@ -191,21 +191,15 @@ case 'addressbook':
break;
case 'folders':
- // special handling for 'default_folders'
- if (in_array('default_folders', (array)$CONFIG['dont_override'])) {
- foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) {
- $a_user_prefs[$p] = $CONFIG[$p];
- }
- }
- else {
- $a_user_prefs['default_folders'] = array('INBOX');
- foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) {
- if ($a_user_prefs[$p]) {
- $a_user_prefs['default_folders'][] = $a_user_prefs[$p];
- }
- }
+ $storage = $RCMAIL->get_storage();
+ $specials = array();
+
+ foreach (rcube_storage::$folder_types as $type) {
+ $specials[$type] = $a_user_prefs[$type . '_mbox'];
}
+ $storage->set_special_folders($specials);
+
break;
}
diff --git a/program/steps/utils/html2text.inc b/program/steps/utils/html2text.inc
index c01443b22..f6e2bec4d 100644
--- a/program/steps/utils/html2text.inc
+++ b/program/steps/utils/html2text.inc
@@ -19,7 +19,12 @@
+-----------------------------------------------------------------------+
*/
-$html = $HTTP_RAW_POST_DATA;
+$html = stream_get_contents(fopen('php://input', 'r'));
+
+// strip slashes if magic_quotes enabled
+if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) {
+ $html = stripslashes($html);
+}
// Replace emoticon images with its text representation
$html = $RCMAIL->replace_emoticons($html);
diff --git a/program/steps/utils/modcss.inc b/program/steps/utils/modcss.inc
index c8a7cb524..f3d8d897a 100644
--- a/program/steps/utils/modcss.inc
+++ b/program/steps/utils/modcss.inc
@@ -5,7 +5,7 @@
| program/steps/utils/modcss.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2007-2012, The Roundcube Dev Team |
+ | Copyright (C) 2007-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -33,27 +33,47 @@ if (!preg_match('~^(https?)://~i', $realurl, $matches)) {
exit("Invalid URL");
}
-if (!ini_get('allow_url_fopen')) {
+if (ini_get('allow_url_fopen')) {
+ $scheme = strtolower($matches[1]);
+ $options = array(
+ $scheme => array(
+ 'method' => 'GET',
+ 'timeout' => 15,
+ )
+ );
+
+ $context = stream_context_create($options);
+ $source = @file_get_contents($realurl, false, $context);
+
+ // php.net/manual/en/reserved.variables.httpresponseheader.php
+ $headers = implode("\n", (array) $http_response_header);
+}
+else if (function_exists('curl_init')) {
+ $curl = curl_init($realurl);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 15);
+ curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 15);
+ curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
+ curl_setopt($curl, CURLOPT_ENCODING, '');
+ curl_setopt($curl, CURLOPT_HEADER, true);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ $data = curl_exec($curl);
+
+ if ($data !== false) {
+ list($headers, $source) = explode("\r\n\r\n", $data, 2);
+ }
+ else {
+ $headers = false;
+ $source = false;
+ }
+}
+else {
header('HTTP/1.1 403 Forbidden');
exit("HTTP connections disabled");
}
-$scheme = strtolower($matches[1]);
-$options = array(
- $scheme => array(
- 'method' => 'GET',
- 'timeout' => 15,
- )
-);
-
-$context = stream_context_create($options);
-$source = @file_get_contents($realurl, false, $context);
-
-// php.net/manual/en/reserved.variables.httpresponseheader.php
-$headers = implode("\n", (array)$http_response_header);
-$ctype = '~Content-Type:\s+text/(css|plain)~i';
+$ctype_regexp = '~Content-Type:\s+text/(css|plain)~i';
-if ($source !== false && preg_match($ctype, $headers)) {
+if ($source !== false && preg_match($ctype_regexp, $headers)) {
header('Content-Type: text/css');
echo rcube_utils::mod_css_styles($source, preg_replace('/[^a-z0-9]/i', '', $_GET['_c']));
exit;
diff --git a/program/steps/utils/spell.inc b/program/steps/utils/spell.inc
index c8807e32f..696fa6005 100644
--- a/program/steps/utils/spell.inc
+++ b/program/steps/utils/spell.inc
@@ -37,6 +37,9 @@ if ($learn_word) {
$spellchecker->add_word($data);
$result = '<?xml version="1.0" encoding="'.RCUBE_CHARSET.'"?><learnwordresult></learnwordresult>';
}
+else if (empty($data)) {
+ $result = '<?xml version="1.0" encoding="'.RCUBE_CHARSET.'"?><spellresult charschecked="0"></spellresult>';
+}
else {
$spellchecker->check($data);
$result = $spellchecker->get_xml();
diff --git a/program/steps/utils/text2html.inc b/program/steps/utils/text2html.inc
new file mode 100644
index 000000000..56d15fa19
--- /dev/null
+++ b/program/steps/utils/text2html.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/utils/text2html.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2014, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Convert plain text to HTML |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+$text = stream_get_contents(fopen('php://input', 'r'));
+
+// strip slashes if magic_quotes enabled
+if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) {
+ $html = stripslashes($html);
+}
+
+$converter = new rcube_text2html($text, false, array('wrap' => true));
+
+header('Content-Type: text/html; charset=' . RCUBE_CHARSET);
+print $converter->get_html();
+exit;