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/move.inc6
-rw-r--r--program/steps/mail/autocomplete.inc4
-rw-r--r--program/steps/mail/check_recent.inc30
-rw-r--r--program/steps/mail/compose.inc47
-rw-r--r--program/steps/mail/copy.inc11
-rw-r--r--program/steps/mail/func.inc112
-rw-r--r--program/steps/mail/get.inc4
-rw-r--r--program/steps/mail/import.inc113
-rw-r--r--program/steps/mail/list.inc14
-rw-r--r--program/steps/mail/mark.inc20
-rw-r--r--program/steps/mail/move_del.inc42
-rw-r--r--program/steps/mail/search.inc50
-rw-r--r--program/steps/mail/sendmail.inc16
-rw-r--r--program/steps/mail/viewsource.inc4
-rw-r--r--program/steps/settings/folders.inc23
-rw-r--r--program/steps/settings/func.inc21
-rw-r--r--program/steps/settings/save_prefs.inc28
-rw-r--r--program/steps/utils/spell.inc3
-rw-r--r--program/steps/utils/spell_html.inc2
20 files changed, 382 insertions, 174 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/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/mail/autocomplete.inc b/program/steps/mail/autocomplete.inc
index 20cf94084..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);
@@ -155,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..cfdcda605 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'));
// "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']) {
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index 46280292e..2b717d673 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -179,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'])
@@ -242,8 +248,9 @@ else {
}
}
-if (!empty($COMPOSE['reply_msgid']))
- $OUTPUT->set_env('reply_msgid', $COMPOSE['reply_msgid']);
+if (!empty($COMPOSE['reply_msgid'])) {
+ $OUTPUT->set_env('reply_msgid', $COMPOSE['reply_msgid']);
+}
$MESSAGE->compose = array();
@@ -456,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());
@@ -475,7 +487,7 @@ function rcmail_process_compose_params(&$COMPOSE)
foreach ($plugin['attachments'] as $attach) {
// we have structured data
if (is_array($attach)) {
- $attachment = $attach;
+ $attachment = $attach + array('group' => $COMPOSE_ID);
}
// only a file path is given
else {
@@ -1241,6 +1253,7 @@ function rcmail_write_forward_attachments()
$storage = $RCMAIL->get_storage();
$names = array();
+ $refs = array();
$loaded_attachments = array();
foreach ((array)$COMPOSE['attachments'] as $attachment) {
@@ -1251,10 +1264,10 @@ function rcmail_write_forward_attachments()
$index = $storage->index(null, rcmail_sort_column(), rcmail_sort_order());
$COMPOSE['forward_uid'] = $index->get();
}
- else if (strpos($COMPOSE['forward_uid'], ':')) {
+ else if (!is_array($COMPOSE['forward_uid']) && strpos($COMPOSE['forward_uid'], ':')) {
$COMPOSE['forward_uid'] = rcube_imap_generic::uncompressMessageSet($COMPOSE['forward_uid']);
}
- else {
+ else if (is_string($COMPOSE['forward_uid'])) {
$COMPOSE['forward_uid'] = explode(',', $COMPOSE['forward_uid']);
}
@@ -1323,6 +1336,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 072ee716c..b9971ce0c 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -24,16 +24,15 @@
$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));
+if (!strlen($mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true))) {
+ $mbox = strlen($_SESSION['mbox']) ? $_SESSION['mbox'] : 'INBOX';
}
-else if ($RCMAIL->storage) {
- $_SESSION['mbox'] = $RCMAIL->storage->get_folder();
+if (!($page = intval($_GET['_page']))) {
+ $page = $_SESSION['page'] ? $_SESSION['page'] : 1;
}
-if (!empty($_GET['_page'])) {
- $RCMAIL->storage->set_page(($_SESSION['page'] = intval($_GET['_page'])));
-}
+$RCMAIL->storage->set_folder($_SESSION['mbox'] = $mbox);
+$RCMAIL->storage->set_page($_SESSION['page'] = $page);
$a_threading = $RCMAIL->config->get('message_threading', array());
$message_sort_col = $RCMAIL->config->get('message_sort_col');
@@ -68,6 +67,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 +107,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 +139,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');
+ '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,7 +184,6 @@ $RCMAIL->register_action_map(array(
));
-
/**
* Returns default search mods
*/
@@ -298,7 +315,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 +332,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 +351,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 +367,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 +387,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 +409,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 +435,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 +460,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 +520,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 +528,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 +572,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;
}
@@ -1693,7 +1741,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 +1754,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 +2036,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);
}
diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc
index 8f869c67c..c6262097f 100644
--- a/program/steps/mail/get.inc
+++ b/program/steps/mail/get.inc
@@ -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 5a74feb9f..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,46 +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'))) {
+ 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)) {
- 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);
+ }
}
}
@@ -104,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..c4a6df57b 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
@@ -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/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..c29985875 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;
diff --git a/program/steps/mail/search.inc b/program/steps/mail/search.inc
index ba8b124a3..e610e9137 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,10 +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();
$filter = trim($filter);
-$search_request = md5($mbox.$filter.$str);
+$search_request = md5($mbox.$scope.$filter.$str);
// add list filter string
$search_str = $filter && $filter != 'ALL' ? $filter : '';
@@ -84,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));
}
@@ -107,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
@@ -122,15 +144,18 @@ 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')));
}
@@ -143,17 +168,28 @@ if (!empty($result_h)) {
}
}
// 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->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/sendmail.inc b/program/steps/mail/sendmail.inc
index 2cd897e46..04ba94f5e 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
@@ -534,10 +534,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
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/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 307be8c8e..bccd9caa8 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);
}
}
@@ -1035,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,
@@ -1043,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) {
@@ -1287,13 +1290,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/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/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/spell_html.inc b/program/steps/utils/spell_html.inc
index 27b14acef..5935dc13f 100644
--- a/program/steps/utils/spell_html.inc
+++ b/program/steps/utils/spell_html.inc
@@ -35,7 +35,7 @@ $result['id'] = $request['id'];
$spellchecker = new rcube_spellchecker($lang);
if ($request['method'] == 'checkWords') {
- $result['result'] = $spellchecker->get_words($data);
+ $result['result'] = empty($data) ? array() : $spellchecker->get_words($data);
}
else if ($request['method'] == 'getSuggestions') {
$result['result'] = $spellchecker->get_suggestions($data);