diff options
Diffstat (limited to 'program/steps')
-rw-r--r-- | program/steps/addressbook/copy.inc | 6 | ||||
-rw-r--r-- | program/steps/addressbook/move.inc | 6 | ||||
-rw-r--r-- | program/steps/mail/autocomplete.inc | 4 | ||||
-rw-r--r-- | program/steps/mail/check_recent.inc | 30 | ||||
-rw-r--r-- | program/steps/mail/compose.inc | 47 | ||||
-rw-r--r-- | program/steps/mail/copy.inc | 11 | ||||
-rw-r--r-- | program/steps/mail/func.inc | 112 | ||||
-rw-r--r-- | program/steps/mail/get.inc | 4 | ||||
-rw-r--r-- | program/steps/mail/import.inc | 113 | ||||
-rw-r--r-- | program/steps/mail/list.inc | 14 | ||||
-rw-r--r-- | program/steps/mail/mark.inc | 20 | ||||
-rw-r--r-- | program/steps/mail/move_del.inc | 42 | ||||
-rw-r--r-- | program/steps/mail/search.inc | 50 | ||||
-rw-r--r-- | program/steps/mail/sendmail.inc | 16 | ||||
-rw-r--r-- | program/steps/mail/viewsource.inc | 4 | ||||
-rw-r--r-- | program/steps/settings/folders.inc | 23 | ||||
-rw-r--r-- | program/steps/settings/func.inc | 21 | ||||
-rw-r--r-- | program/steps/settings/save_prefs.inc | 28 | ||||
-rw-r--r-- | program/steps/utils/spell.inc | 3 | ||||
-rw-r--r-- | program/steps/utils/spell_html.inc | 2 |
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"> </span>'; + $col_name = html::span('flagged', ' '); break; case 'attachment': case 'priority': case 'status': - $col_name = '<span class="' . $col .'"> </span>'; + $col_name = html::span($col, ' '); 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').': ' . $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); |