summaryrefslogtreecommitdiff
path: root/program/steps
diff options
context:
space:
mode:
Diffstat (limited to 'program/steps')
-rw-r--r--program/steps/addressbook/copy.inc12
-rw-r--r--program/steps/addressbook/delete.inc38
-rw-r--r--program/steps/addressbook/export.inc113
-rw-r--r--program/steps/addressbook/func.inc187
-rw-r--r--program/steps/addressbook/import.inc71
-rw-r--r--program/steps/addressbook/list.inc49
-rw-r--r--program/steps/addressbook/save.inc29
-rw-r--r--program/steps/addressbook/show.inc63
-rw-r--r--program/steps/addressbook/undo.inc25
-rw-r--r--program/steps/mail/attachments.inc5
-rw-r--r--program/steps/mail/check_recent.inc9
-rw-r--r--program/steps/mail/compose.inc103
-rw-r--r--program/steps/mail/func.inc336
-rw-r--r--program/steps/mail/func.inc.orig1964
-rw-r--r--program/steps/mail/get.inc86
-rw-r--r--program/steps/mail/list.inc1
-rw-r--r--program/steps/mail/list_contacts.inc29
-rw-r--r--program/steps/mail/move_del.inc11
-rw-r--r--program/steps/mail/sendmail.inc30
-rw-r--r--program/steps/mail/show.inc61
-rw-r--r--program/steps/mail/show.inc.orig315
-rw-r--r--program/steps/settings/about.inc67
-rw-r--r--program/steps/settings/edit_folder.inc5
-rw-r--r--program/steps/settings/edit_prefs.inc2
-rw-r--r--program/steps/settings/edit_response.inc107
-rw-r--r--program/steps/settings/folders.inc16
-rw-r--r--program/steps/settings/func.inc1961
-rw-r--r--program/steps/settings/responses.inc128
-rw-r--r--program/steps/settings/save_prefs.inc4
-rw-r--r--program/steps/utils/save_pref.inc22
-rw-r--r--program/steps/utils/spell.inc7
-rw-r--r--program/steps/utils/spell_html.inc5
32 files changed, 3963 insertions, 1898 deletions
diff --git a/program/steps/addressbook/copy.inc b/program/steps/addressbook/copy.inc
index d4387194a..480a9b52e 100644
--- a/program/steps/addressbook/copy.inc
+++ b/program/steps/addressbook/copy.inc
@@ -57,16 +57,10 @@ foreach ($cids as $source => $cid)
foreach ($cid as $cid) {
$a_record = $CONTACTS->get_record($cid, true);
- // avoid copying groups
- if ($a_record['_type'] == 'group')
- continue;
-
// Check if contact exists, if so, we'll need it's ID
// Note: Some addressbooks allows empty email address field
- // @TODO: should we check all email addresses?
- $email = $CONTACTS->get_col_values('email', $a_record, true);
- if (!empty($email))
- $result = $TARGET->search('email', $email[0], 1, true, true);
+ if (!empty($a_record['email']))
+ $result = $TARGET->search('email', $a_record['email'], 1, true, true);
else if (!empty($a_record['name']))
$result = $TARGET->search('name', $a_record['name'], 1, true, true);
else
@@ -120,7 +114,7 @@ foreach ($cids as $source => $cid)
}
}
-if (!$success)
+if ($success == 0)
$OUTPUT->show_message($errormsg, 'error');
else
$OUTPUT->show_message('copysuccess', 'notice', array('nr' => $success));
diff --git a/program/steps/addressbook/delete.inc b/program/steps/addressbook/delete.inc
index 3bb2ef500..56118583c 100644
--- a/program/steps/addressbook/delete.inc
+++ b/program/steps/addressbook/delete.inc
@@ -68,14 +68,48 @@ foreach ($cids as $source => $cid)
$page = isset($_SESSION['page']) ? $_SESSION['page'] : 1;
// update saved search after data changed
-if (($records = rcmail_search_update(true)) !== false) {
+if (($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) {
+ $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
+ $afields = $RCMAIL->config->get('contactlist_fields');
+ $search = (array)$_SESSION['search'][$search_request];
+ $records = array();
+
+ // Get records from all sources (refresh search)
+ foreach ($search as $s => $set) {
+ $source = $RCMAIL->get_address_book($s);
+
+ // reset page
+ $source->set_page(1);
+ $source->set_pagesize(9999);
+ $source->set_search_set($set);
+
+ // get records
+ $result = $source->list_records($afields);
+
+ if (!$result->count) {
+ unset($search[$s]);
+ continue;
+ }
+
+ while ($row = $result->next()) {
+ $row['sourceid'] = $s;
+ $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $records[$key] = $row;
+ }
+ unset($result);
+
+ $search[$s] = $source->get_search_set();
+ }
+
+ $_SESSION['search'][$search_request] = $search;
+
// create resultset object
$count = count($records);
$first = ($page-1) * $PAGE_SIZE;
$result = new rcube_result_set($count, $first);
- $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE);
// get records from the next page to add to the list
+ $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE);
if ($_GET['_from'] != 'show' && $pages > 1 && $page < $pages) {
// sort the records
ksort($records, SORT_LOCALE_STRING);
diff --git a/program/steps/addressbook/export.inc b/program/steps/addressbook/export.inc
index 1e988feab..11c9ca493 100644
--- a/program/steps/addressbook/export.inc
+++ b/program/steps/addressbook/export.inc
@@ -5,7 +5,7 @@
| program/steps/addressbook/export.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2008-2013, The Roundcube Dev Team |
+ | Copyright (C) 2008-2011, The Roundcube Dev Team |
| Copyright (C) 2011, Kolab Systems AG |
| |
| Licensed under the GNU General Public License version 3 or |
@@ -21,46 +21,6 @@
+-----------------------------------------------------------------------+
*/
-
-/**
- * Copy contact record properties into a vcard object
- */
-function prepare_for_export(&$record, $source = null)
-{
- $groups = $source && $source->groups && $source->export_groups ? $source->get_record_groups($record['ID']) : null;
-
- if (empty($record['vcard'])) {
- $vcard = new rcube_vcard();
- if ($source) {
- $vcard->extend_fieldmap($source->vcard_map);
- }
- $vcard->load($record['vcard']);
- $vcard->reset();
-
- foreach ($record as $key => $values) {
- list($field, $section) = explode(':', $key);
- foreach ((array)$values as $value) {
- if (is_array($value) || @strlen($value)) {
- $vcard->set($field, $value, strtoupper($section));
- }
- }
- }
-
- // append group names
- if ($groups) {
- $vcard->set('groups', join(',', $groups), null);
- }
-
- $record['vcard'] = $vcard->export(true);
- }
- // patch categories to alread existing vcard block
- else if ($record['vcard'] && !empty($groups) && !strpos($record['vcard'], 'CATEGORIES:')) {
- $vgroups = 'CATEGORIES:' . rcube_vcard::vcard_quote(join(',', $groups));
- $record['vcard'] = str_replace('END:VCARD', $vgroups . rcube_vcard::$eol . 'END:VCARD', $record['vcard']);
- }
-}
-
-
// Use search result
if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']]))
{
@@ -80,15 +40,11 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
// get records
$result = $source->list_records();
- while ($record = $result->next()) {
- // because vcard_map is per-source we need to create vcard here
- prepare_for_export($record, $source);
-
- $record['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($record, $sort_col);
- $records[$key] = $record;
+ while ($row = $result->next()) {
+ $row['sourceid'] = $s;
+ $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $records[$key] = $row;
}
-
unset($result);
}
@@ -100,35 +56,6 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
$result = new rcube_result_set($count);
$result->records = array_values($records);
}
-// selected contacts
-else if (!empty($_REQUEST['_cid'])) {
- $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
- $records = array();
-
- // Selected contact IDs (with multi-source support)
- $cids = rcmail_get_cids();
-
- foreach ($cids as $s => $ids) {
- $source = $RCMAIL->get_address_book($s);
- $result = $source->search('ID', $ids, 1, true, true);
-
- while ($record = $result->next()) {
- // because vcard_map is per-source we need to create vcard here
- prepare_for_export($record, $source);
-
- $record['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($record, $sort_col);
- $records[$key] = $record;
- }
- }
-
- ksort($records, SORT_LOCALE_STRING);
-
- // create resultset object
- $count = count($records);
- $result = new rcube_result_set($count);
- $result->records = array_values($records);
-}
// selected directory/group
else {
$CONTACTS = rcmail_contact_source(null, true);
@@ -141,15 +68,33 @@ else {
// send downlaod headers
header('Content-Type: text/x-vcard; charset='.RCMAIL_CHARSET);
-header('Content-Disposition: attachment; filename="contacts.vcf"');
+header('Content-Disposition: attachment; filename="rcube_contacts.vcf"');
while ($result && ($row = $result->next())) {
- prepare_for_export($row, $CONTACTS);
+ // we already have a vcard record
+ if ($row['vcard'] && $row['name']) {
+ // fix folding and end-of-line chars
+ $row['vcard'] = preg_replace('/\r|\n\s+/', '', $row['vcard']);
+ $row['vcard'] = preg_replace('/\n/', rcube_vcard::$eol, $row['vcard']);
+ echo rcube_vcard::rfc2425_fold($row['vcard']) . rcube_vcard::$eol;
+ }
+ // copy values into vcard object
+ else {
+ $vcard = new rcube_vcard();
+ $vcard->extend_fieldmap($CONTACTS->vcard_map);
+ $vcard->load($row['vcard']);
+ $vcard->reset();
+
+ foreach ($row as $key => $values) {
+ list($field, $section) = explode(':', $key);
+ foreach ((array)$values as $value) {
+ if (is_array($value) || @strlen($value))
+ $vcard->set($field, $value, strtoupper($section));
+ }
+ }
- // fix folding and end-of-line chars
- $row['vcard'] = preg_replace('/\r|\n\s+/', '', $row['vcard']);
- $row['vcard'] = preg_replace('/\n/', rcube_vcard::$eol, $row['vcard']);
- echo rcube_vcard::rfc2425_fold($row['vcard']) . rcube_vcard::$eol;
+ echo $vcard->export(true) . rcube_vcard::$eol;
+ }
}
exit;
diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc
index f94d15338..989b7c1c4 100644
--- a/program/steps/addressbook/func.inc
+++ b/program/steps/addressbook/func.inc
@@ -183,10 +183,11 @@ function rcmail_directory_list($attrib)
$attrib['id'] = 'rcmdirectorylist';
$out = '';
+ $local_id = '0';
$jsdata = array();
$line_templ = html::tag('li', array(
- 'id' => 'rcmli%s', 'class' => '%s', 'noclose' => true),
+ 'id' => 'rcmli%s', 'class' => '%s'),
html::a(array('href' => '%s',
'rel' => '%s',
'onclick' => "return ".JS_OBJECT_NAME.".command('list','%s',this)"), '%s'));
@@ -212,7 +213,7 @@ function rcmail_directory_list($attrib)
$name = !empty($source['name']) ? $source['name'] : $id;
$out .= sprintf($line_templ,
- rcube_utils::html_identifier($id, true),
+ html_identifier($id),
$class_name,
Q(rcmail_url(null, array('_source' => $id))),
$source['id'],
@@ -223,11 +224,10 @@ function rcmail_directory_list($attrib)
$groupdata = rcmail_contact_groups($groupdata);
$jsdata = $groupdata['jsdata'];
$out = $groupdata['out'];
- $out .= '</li>';
}
$line_templ = html::tag('li', array(
- 'id' => 'rcmli%s', 'class' => '%s'),
+ 'id' => 'rcmliS%s', 'class' => '%s'),
html::a(array('href' => '#', 'rel' => 'S%s',
'onclick' => "return ".JS_OBJECT_NAME.".command('listsearch', '%s', this)"), '%s'));
@@ -245,17 +245,14 @@ function rcmail_directory_list($attrib)
$class_name .= ' ' . $source['class_name'];
$out .= sprintf($line_templ,
- rcube_utils::html_identifier('S'.$id, true),
+ html_identifier($id),
$class_name,
$id,
$js_id, (!empty($source['name']) ? Q($source['name']) : Q($id)));
}
$OUTPUT->set_env('contactgroups', $jsdata);
- $OUTPUT->set_env('collapsed_abooks', (string)$RCMAIL->config->get('collapsed_abooks',''));
$OUTPUT->add_gui_object('folderlist', $attrib['id']);
- $OUTPUT->include_script('treelist.js');
-
// add some labels to client
$OUTPUT->add_label('deletegroupconfirm', 'groupdeleting', 'addingmember', 'removingmember');
@@ -267,23 +264,19 @@ function rcmail_contact_groups($args)
{
global $RCMAIL;
- $groups_html = '';
$groups = $RCMAIL->get_address_book($args['source'])->list_groups();
if (!empty($groups)) {
$line_templ = html::tag('li', array(
- 'id' => 'rcmli%s', 'class' => 'contactgroup'),
+ 'id' => 'rcmliG%s', 'class' => 'contactgroup'),
html::a(array('href' => '#',
'rel' => '%s:%s',
'onclick' => "return ".JS_OBJECT_NAME.".command('listgroup',{'source':'%s','id':'%s'},this)"), '%s'));
- // append collapse/expand toggle and open a new <ul>
- $is_collapsed = strpos($RCMAIL->config->get('collapsed_abooks',''), '&'.rawurlencode($args['source']).'&') !== false;
- $args['out'] .= html::div('treetoggle ' . ($is_collapsed ? 'collapsed' : 'expanded'), '&nbsp;');
-
+ $jsdata = array();
foreach ($groups as $group) {
- $groups_html .= sprintf($line_templ,
- rcube_utils::html_identifier('G' . $args['source'] . $group['ID'], true),
+ $args['out'] .= sprintf($line_templ,
+ html_identifier($args['source'] . $group['ID']),
$args['source'], $group['ID'],
$args['source'], $group['ID'], Q($group['name'])
);
@@ -293,10 +286,6 @@ function rcmail_contact_groups($args)
}
}
- $args['out'] .= html::tag('ul',
- array('class' => 'groups', 'style' => ($is_collapsed || empty($groups) ? "display:none;" : null)),
- $groups_html);
-
return $args;
}
@@ -307,7 +296,7 @@ function rcmail_contacts_list($attrib)
global $CONTACTS, $OUTPUT;
// define list of cols to be displayed
- $a_show_cols = array('name','action');
+ $a_show_cols = array('name');
// add id to message list table if not specified
if (!strlen($attrib['id']))
@@ -322,7 +311,7 @@ function rcmail_contacts_list($attrib)
$OUTPUT->include_script('list.js');
// add some labels to client
- $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'movingcontact', 'contactdeleting');
+ $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'contactdeleting');
return $out;
}
@@ -336,73 +325,31 @@ function rcmail_js_contacts_list($result, $prefix='')
return;
// define list of cols to be displayed
- $a_show_cols = array('name','action');
+ $a_show_cols = array('name');
while ($row = $result->next()) {
- $row['CID'] = $row['ID'];
- $row['email'] = reset(rcube_addressbook::get_col_values('email', $row, true));
-
- $source_id = $OUTPUT->get_env('source');
$a_row_cols = array();
- $classes = array($row['_type'] ? $row['_type'] : 'person');
+ $classes = array('person'); // org records will follow some day
// build contact ID with source ID
if (isset($row['sourceid'])) {
$row['ID'] = $row['ID'].'-'.$row['sourceid'];
- $source_id = $row['sourceid'];
}
// format each col
foreach ($a_show_cols as $col) {
- $val = '';
- switch ($col) {
- case 'name':
- $val = Q(rcube_addressbook::compose_list_name($row));
- break;
-
- case 'action':
- if ($row['_type'] == 'group') {
- $val = html::a(array(
- 'href' => '#list',
- 'rel' => $row['ID'],
- 'title' => rcube_label('listgroup'),
- 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", JS_OBJECT_NAME, $source_id, $row['CID']),
- ), '&raquo;');
- }
- else
- $val = '&nbsp;';
- break;
-
- default:
- $val = Q($row[$col]);
- break;
- }
-
- $a_row_cols[$col] = $val;
+ $val = $col == 'name' ? rcube_addressbook::compose_list_name($row) : $row[$col];
+ $a_row_cols[$col] = Q($val);
}
if ($row['readonly'])
$classes[] = 'readonly';
- $OUTPUT->command($prefix.'add_contact_row', $row['ID'], $a_row_cols, join(' ', $classes), array_intersect_key($row, array('ID'=>1,'readonly'=>1,'_type'=>1,'email'=>1,'name'=>1)));
+ $OUTPUT->command($prefix.'add_contact_row', $row['ID'], $a_row_cols, join(' ', $classes));
}
}
-function rcmail_contacts_list_title($attrib)
-{
- global $OUTPUT;
-
- $attrib += array('label' => 'contacts', 'id' => 'rcmabooklisttitle', 'tag' => 'span');
- unset($attrib['name']);
-
- $OUTPUT->add_gui_object('addresslist_title', $attrib['id']);
- $OUTPUT->add_label('contacts');
-
- return html::tag($attrib['tag'], $attrib, rcube_label($attrib['label']), html::$common_attrib);
-}
-
-
// similar function as /steps/settings/identities.inc::rcmail_identity_frame()
function rcmail_contact_frame($attrib)
{
@@ -471,7 +418,7 @@ function rcmail_get_type_label($type)
function rcmail_contact_form($form, $record, $attrib = null)
{
- global $RCMAIL;
+ global $RCMAIL, $CONFIG;
// Allow plugins to modify contact form content
$plugin = $RCMAIL->plugins->exec_hook('contact_form', array(
@@ -480,7 +427,7 @@ function rcmail_contact_form($form, $record, $attrib = null)
$form = $plugin['form'];
$record = $plugin['record'];
$edit_mode = $RCMAIL->action != 'show';
- $del_button = $attrib['deleteicon'] ? html::img(array('src' => $RCMAIL->output->get_skin_file($attrib['deleteicon']), 'alt' => rcube_label('delete'))) : rcube_label('delete');
+ $del_button = $attrib['deleteicon'] ? html::img(array('src' => $CONFIG['skin_path'] . $attrib['deleteicon'], 'alt' => rcube_label('delete'))) : rcube_label('delete');
unset($attrib['deleteicon']);
$out = '';
@@ -593,13 +540,22 @@ function rcmail_contact_form($form, $record, $attrib = null)
// iterate over possible subtypes and collect values with their subtype
if (is_array($colprop['subtypes'])) {
$values = $subtypes = array();
- foreach (rcube_addressbook::get_col_values($field, $record) as $st => $vals) {
- foreach((array)$vals as $value) {
- $i = count($values);
- $subtypes[$i] = $st;
- $values[$i] = $value;
+ foreach ($colprop['subtypes'] as $i => $st) {
+ $newval = false;
+ if ($record[$field.':'.$st]) {
+ $subtypes[count($values)] = $st;
+ $newval = $record[$field.':'.$st];
+ }
+ else if ($i == 0 && $record[$field]) {
+ $subtypes[count($values)] = $st;
+ $newval = $record[$field];
+ }
+ if ($newval !== false) {
+ if (is_array($newval) && isset($newval[0]))
+ $values = array_merge($values, $newval);
+ else
+ $values[] = $newval;
}
- // TODO: add $st to $select_subtype if missing ?
}
}
else {
@@ -737,42 +693,23 @@ function rcmail_contact_form($form, $record, $attrib = null)
function rcmail_contact_photo($attrib)
{
- global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL;
+ global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL, $CONFIG;
if ($result = $CONTACTS->get_result())
$record = $result->first();
- $photo_img = $attrib['placeholder'] ? $RCMAIL->output->get_skin_file($attrib['placeholder']) : 'program/resources/blank.gif';
- if ($record['_type'] == 'group' && $attrib['placeholdergroup'])
- $photo_img = $RCMAIL->output->get_skin_file($attrib['placeholdergroup']);
-
+ $photo_img = $attrib['placeholder'] ? $CONFIG['skin_path'] . $attrib['placeholder'] : 'program/resources/blank.gif';
$RCMAIL->output->set_env('photo_placeholder', $photo_img);
unset($attrib['placeholder']);
$plugin = $RCMAIL->plugins->exec_hook('contact_photo', array('record' => $record, 'data' => $record['photo']));
- // check if we have photo data from contact form
- if ($GLOBALS['EDIT_RECORD']) {
- $rec = $GLOBALS['EDIT_RECORD'];
- if ($rec['photo'] == '-del-') {
- $record['photo'] = '';
- }
- else if ($_SESSION['contacts']['files'][$rec['photo']]) {
- $record['photo'] = $file_id = $rec['photo'];
- }
- }
-
if ($plugin['url'])
$photo_img = $plugin['url'];
else if (preg_match('!^https?://!i', $record['photo']))
$photo_img = $record['photo'];
- else if ($record['photo']) {
- $url = array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $SOURCE_ID);
- if ($file_id) {
- $url['_photo'] = $ff_value = $file_id;
- }
- $photo_img = $RCMAIL->url($url);
- }
+ else if ($record['photo'])
+ $photo_img = $RCMAIL->url(array('_action' => 'photo', '_cid' => $record['ID'], '_source' => $SOURCE_ID));
else
$ff_value = '-del-'; // will disable delete-photo action
@@ -795,54 +732,6 @@ function rcmail_format_date_col($val)
return format_date($val, $RCMAIL->config->get('date_format', 'Y-m-d'), false);
}
-/**
- * Updates saved search after data changed
- */
-function rcmail_search_update($return = false)
-{
- global $RCMAIL;
-
- if (($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) {
- $search = (array)$_SESSION['search'][$search_request];
- $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
- $afields = $return ? $RCMAIL->config->get('contactlist_fields') : array('name', 'email');
- $records = array();
-
- foreach ($search as $s => $set) {
- $source = $RCMAIL->get_address_book($s);
-
- // reset page
- $source->set_page(1);
- $source->set_pagesize(9999);
- $source->set_search_set($set);
-
- // get records
- $result = $source->list_records($afields);
-
- if (!$result->count) {
- unset($search[$s]);
- continue;
- }
-
- if ($return) {
- while ($row = $result->next()) {
- $row['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($row, $sort_col);
- $records[$key] = $row;
- }
- unset($result);
- }
-
- $search[$s] = $source->get_search_set();
- }
-
- $_SESSION['search'][$search_request] = $search;
-
- return $records;
- }
-
- return false;
-}
/**
* Returns contact ID(s) and source(s) from GET/POST data
@@ -900,7 +789,6 @@ $OUTPUT->add_handlers(array(
'directorylist' => 'rcmail_directory_list',
// 'groupslist' => 'rcmail_contact_groups',
'addresslist' => 'rcmail_contacts_list',
- 'addresslisttitle' => 'rcmail_contacts_list_title',
'addressframe' => 'rcmail_contact_frame',
'recordscountdisplay' => 'rcmail_rowcount_display',
'searchform' => array($OUTPUT, 'search_form')
@@ -909,6 +797,7 @@ $OUTPUT->add_handlers(array(
// register action aliases
$RCMAIL->register_action_map(array(
'add' => 'edit.inc',
+ 'photo' => 'show.inc',
'group-create' => 'groups.inc',
'group-rename' => 'groups.inc',
'group-delete' => 'groups.inc',
diff --git a/program/steps/addressbook/import.inc b/program/steps/addressbook/import.inc
index 60f5d7b61..915aac884 100644
--- a/program/steps/addressbook/import.inc
+++ b/program/steps/addressbook/import.inc
@@ -40,7 +40,6 @@ function rcmail_import_form($attrib)
'multiple' => 'multiple',
));
$form = html::p(null, html::label('rcmimportfile', rcube_label('importfromfile')) . $upload->show());
- $table = new html_table(array('cols' => 2));
// addressbook selector
if (count($writable_books) > 1) {
@@ -49,31 +48,17 @@ function rcmail_import_form($attrib)
foreach ($writable_books as $book)
$select->add($book['name'], $book['id']);
- $table->add('title', html::label('rcmimporttarget', rcube_label('importtarget')));
- $table->add(null, $select->show($target));
+ $form .= html::p(null, html::label('rcmimporttarget', rcube_label('importtarget'))
+ . $select->show($target));
}
else {
$abook = new html_hiddenfield(array('name' => '_target', 'value' => key($writable_books)));
$form .= $abook->show();
}
- // selector for group import options
- if (count($writable_books) >= 1 || $writable_books[0]->groups) {
- $select = new html_select(array('name' => '_groups', 'id' => 'rcmimportgroups', 'is_escaped' => true));
- $select->add(rcube_label('none'), '0');
- $select->add(rcube_label('importgroupsall'), '1');
- $select->add(rcube_label('importgroupsexisting'), '2');
-
- $table->add('title', html::label('rcmimportgroups', rcube_label('importgroups')));
- $table->add(null, $select->show(get_input_value('_groups', RCUBE_INPUT_GPC)));
- }
-
- // checkbox to replace the entire address book
$check_replace = new html_checkbox(array('name' => '_replace', 'value' => 1, 'id' => 'rcmimportreplace'));
- $table->add('title', html::label('rcmimportreplace', rcube_label('importreplace')));
- $table->add(null, $check_replace->show(get_input_value('_replace', RCUBE_INPUT_GPC)));
-
- $form .= $table->show(array('id' => null) + $attrib);
+ $form .= html::p(null, $check_replace->show(get_input_value('_replace', RCUBE_INPUT_GPC)) .
+ html::label('rcmimportreplace', rcube_label('importreplace')));
$OUTPUT->set_env('writable_source', !empty($writable_books));
$OUTPUT->add_label('selectimportfile','importwait');
@@ -149,50 +134,19 @@ function rcmail_import_buttons($attrib)
}
-/**
- * Returns the matching group id. If group doesn't exist, it'll be created if allowed.
- */
-function rcmail_import_group_id($group_name, $CONTACTS, $create, &$import_groups)
-{
- $group_id = 0;
- foreach ($import_groups as $key => $group) {
- if (strtolower($group['name']) == strtolower($group_name)) {
- $group_id = $group['ID'];
- break;
- }
- }
-
- // create a new group
- if (!$group_id && $create) {
- $new_group = $CONTACTS->create_group($group_name);
- if (!$new_group['ID'])
- $new_group['ID'] = $new_group['id'];
- $import_groups[] = $new_group;
- $group_id = $new_group['ID'];
- }
-
- return $group_id;
-}
-
-
/** The import process **/
$importstep = 'rcmail_import_form';
if (is_array($_FILES['_file'])) {
- $replace = (bool)get_input_value('_replace', RCUBE_INPUT_GPC);
- $target = get_input_value('_target', RCUBE_INPUT_GPC);
- $with_groups = intval(get_input_value('_groups', RCUBE_INPUT_GPC));
+ $replace = (bool)get_input_value('_replace', RCUBE_INPUT_GPC);
+ $target = get_input_value('_target', RCUBE_INPUT_GPC);
$vcards = array();
$upload_error = null;
$CONTACTS = $RCMAIL->get_address_book($target, true);
- if (!$CONTACTS->groups) {
- $with_groups = false;
- }
-
if ($CONTACTS->readonly) {
$OUTPUT->show_message('addresswriterror', 'error');
}
@@ -252,10 +206,6 @@ if (is_array($_FILES['_file'])) {
$CONTACTS->delete_all();
}
- if ($with_groups) {
- $import_groups = $CONTACTS->list_groups();
- }
-
foreach ($vcards as $vcard) {
$a_record = $vcard->get_assoc();
@@ -308,15 +258,6 @@ if (is_array($_FILES['_file'])) {
$success = $plugin['result'];
if ($success) {
- // assign groups for this contact (if enabled)
- if ($with_groups && !empty($a_record['groups'])) {
- foreach (explode(',', $a_record['groups'][0]) as $group_name) {
- if ($group_id = rcmail_import_group_id($group_name, $CONTACTS, $with_groups == 1, $import_groups)) {
- $CONTACTS->add_to_group($group_id, $success);
- }
- }
- }
-
$IMPORT_STATS->inserted++;
$IMPORT_STATS->names[] = $a_record['name'] ? $a_record['name'] : $email;
}
diff --git a/program/steps/addressbook/list.inc b/program/steps/addressbook/list.inc
index aca58d279..1bb28658b 100644
--- a/program/steps/addressbook/list.inc
+++ b/program/steps/addressbook/list.inc
@@ -19,20 +19,47 @@
+-----------------------------------------------------------------------+
*/
-if (!empty($_GET['_page']))
- $page = intval($_GET['_page']);
-else
- $page = !empty($_SESSION['page']) ? $_SESSION['page'] : 1;
-
-$_SESSION['page'] = $page;
+$afields = $RCMAIL->config->get('contactlist_fields');
// Use search result
-if (($records = rcmail_search_update(true)) !== false) {
+if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']]))
+{
+ $search = (array)$_SESSION['search'][$_REQUEST['_search']];
+ $records = array();
+
+ if (!empty($_GET['_page']))
+ $page = intval($_GET['_page']);
+ else
+ $page = isset($_SESSION['page']) ? $_SESSION['page'] : 1;
+
+ $_SESSION['page'] = $page;
+ $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
+
+ // Get records from all sources
+ foreach ($search as $s => $set) {
+ $source = $RCMAIL->get_address_book($s);
+
+ // reset page
+ $source->set_page(1);
+ $source->set_pagesize(9999);
+ $source->set_search_set($set);
+
+ // get records
+ $result = $source->list_records($afields);
+
+ while ($row = $result->next()) {
+ $row['sourceid'] = $s;
+ $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $records[$key] = $row;
+ }
+ unset($result);
+ }
+
// sort the records
ksort($records, SORT_LOCALE_STRING);
// create resultset object
- $count = count($records);
+ $count = count($records);
$first = ($page-1) * $PAGE_SIZE;
$result = new rcube_result_set($count, $first);
@@ -45,7 +72,6 @@ if (($records = rcmail_search_update(true)) !== false) {
}
// List selected directory
else {
- $afields = $RCMAIL->config->get('contactlist_fields');
$CONTACTS = rcmail_contact_source(null, true);
// get contacts for this user
@@ -55,11 +81,6 @@ else {
$OUTPUT->show_message('contactsearchonly', 'notice');
$OUTPUT->command('command', 'advanced-search');
}
-
- if ($CONTACTS->group_id) {
- $OUTPUT->command('set_group_prop', array('ID' => $CONTACTS->group_id)
- + array_intersect_key((array)$CONTACTS->get_group($CONTACTS->group_id), array('name'=>1,'email'=>1)));
- }
}
// update message count display
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 2adc53bcf..25bfbd48b 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -59,34 +59,15 @@ foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) {
}
// assign values and subtypes
else if (is_array($_POST[$fname])) {
- $values = get_input_value($fname, RCUBE_INPUT_POST, true);
+ $values = get_input_value($fname, RCUBE_INPUT_POST, true);
$subtypes = get_input_value('_subtype_' . $col, RCUBE_INPUT_POST);
-
foreach ($values as $i => $val) {
- if ($col == 'email') {
- // extract email from full address specification, e.g. "Name" <addr@domain.tld>
- $addr = rcube_mime::decode_address_list($val, 1, false);
- if (!empty($addr) && ($addr = array_pop($addr)) && $addr['mailto']) {
- $val = $addr['mailto'];
- }
- }
-
$subtype = $subtypes[$i] ? ':'.$subtypes[$i] : '';
$a_record[$col.$subtype][] = $val;
}
}
else if (isset($_POST[$fname])) {
$a_record[$col] = get_input_value($fname, RCUBE_INPUT_POST, true);
-
- // normalize the submitted date strings
- if ($colprop['type'] == 'date') {
- if ($timestamp = rcube_utils::strtotime($a_record[$col])) {
- $a_record[$col] = date('Y-m-d', $timestamp);
- }
- else {
- unset($a_record[$col]);
- }
- }
}
}
@@ -94,10 +75,8 @@ foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) {
if (empty($a_record['name'])) {
$a_record['name'] = rcube_addressbook::compose_display_name($a_record, true);
// Reset it if equals to email address (from compose_display_name())
- $email = rcube_addressbook::get_col_values('email', $a_record, true);
- if ($a_record['name'] == $email[0]) {
+ if ($a_record['name'] == $a_record['email'][0])
$a_record['name'] = '';
- }
}
// do input checks (delegated to $CONTACTS instance)
@@ -155,11 +134,11 @@ if (!empty($cid))
$record['email'] = reset($CONTACTS->get_col_values('email', $record, true));
$record['name'] = rcube_addressbook::compose_list_name($record);
- foreach (array('name') as $col)
+ foreach (array('name', 'email') as $col)
$a_js_cols[] = Q((string)$record[$col]);
// update the changed col in list
- $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source, $record);
+ $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source);
// show confirmation
$OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
diff --git a/program/steps/addressbook/show.inc b/program/steps/addressbook/show.inc
index efab5e9e5..d583a6d36 100644
--- a/program/steps/addressbook/show.inc
+++ b/program/steps/addressbook/show.inc
@@ -38,6 +38,58 @@ if ($cid && ($record = $CONTACTS->get_record($cid, true))) {
// get address book name (for display)
rcmail_set_sourcename($CONTACTS);
+// return raw photo of the given contact
+if ($RCMAIL->action == 'photo') {
+ // search for contact first
+ if (!$record && ($email = get_input_value('_email', RCUBE_INPUT_GPC))) {
+ foreach ($RCMAIL->get_address_sources() as $s) {
+ $abook = $RCMAIL->get_address_book($s['id']);
+ $result = $abook->search(array('email'), $email, 1, true, true, 'photo');
+ while ($result && ($record = $result->iterate())) {
+ if ($record['photo'])
+ break 2;
+ }
+ }
+ }
+
+ // read the referenced file
+ if (($file_id = get_input_value('_photo', RCUBE_INPUT_GPC)) && ($tempfile = $_SESSION['contacts']['files'][$file_id])) {
+ $tempfile = $RCMAIL->plugins->exec_hook('attachment_display', $tempfile);
+ if ($tempfile['status']) {
+ if ($tempfile['data'])
+ $data = $tempfile['data'];
+ else if ($tempfile['path'])
+ $data = file_get_contents($tempfile['path']);
+ }
+ }
+ else if ($record['photo']) {
+ $data = is_array($record['photo']) ? $record['photo'][0] : $record['photo'];
+ if (!preg_match('![^a-z0-9/=+-]!i', $data))
+ $data = base64_decode($data, true);
+ }
+
+ // let plugins do fancy things with contact photos
+ $plugin = $RCMAIL->plugins->exec_hook('contact_photo', array('record' => $record, 'email' => $email, 'data' => $data));
+
+ // redirect to url provided by a plugin
+ if ($plugin['url'])
+ $RCMAIL->output->redirect($plugin['url']);
+ else
+ $data = $plugin['data'];
+
+ // deliver alt image
+ if (!$data && ($alt_img = get_input_value('_alt', RCUBE_INPUT_GPC)) && is_file($alt_img))
+ $data = file_get_contents($alt_img);
+
+ // cache for one day if requested by email
+ if (!$cid && $email)
+ $RCMAIL->output->future_expire_header(86400);
+
+ header('Content-Type: ' . rc_image_content_type($data));
+ echo $data ? $data : file_get_contents('program/resources/blank.gif');
+ exit;
+}
+
function rcmail_contact_head($attrib)
{
@@ -49,6 +101,8 @@ function rcmail_contact_head($attrib)
return false;
}
+ $microformats = array('name' => 'fn', 'email' => 'email');
+
$form = array(
'head' => array( // section 'head' is magic!
'content' => array(
@@ -123,7 +177,7 @@ function rcmail_contact_details($attrib)
}
-function rcmail_render_email_value($email)
+function rcmail_render_email_value($email, $col)
{
return html::a(array(
'href' => 'mailto:' . $email,
@@ -134,7 +188,7 @@ function rcmail_render_email_value($email)
}
-function rcmail_render_url_value($url)
+function rcmail_render_url_value($url, $col)
{
$prefix = preg_match('!^(http|ftp)s?://!', $url) ? '' : 'http://';
return html::a(array(
@@ -155,8 +209,9 @@ function rcmail_contact_record_groups($contact_id)
return '';
}
- $members = $CONTACTS->get_record_groups($contact_id);
- $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0));
+ $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0));
+
+ $members = $CONTACTS->get_record_groups($contact_id);
$checkbox = new html_checkbox(array('name' => '_gid[]',
'class' => 'groupmember', 'disabled' => $CONTACTS->readonly));
diff --git a/program/steps/addressbook/undo.inc b/program/steps/addressbook/undo.inc
index c23bd1cb6..9c171143c 100644
--- a/program/steps/addressbook/undo.inc
+++ b/program/steps/addressbook/undo.inc
@@ -46,7 +46,30 @@ foreach ((array)$undo['data'] as $source => $cid)
}
// update saved search after data changed
-rcmail_search_update();
+if ($delcnt && ($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) {
+ $search = (array)$_SESSION['search'][$search_request];
+
+ foreach ($search as $s => $set) {
+ $source = $RCMAIL->get_address_book($s);
+
+ // reset page
+ $source->set_page(1);
+ $source->set_pagesize(9999);
+ $source->set_search_set($set);
+
+ // get records
+ $result = $source->list_records(array('name', 'email'));
+
+ if (!$result->count) {
+ unset($search[$s]);
+ continue;
+ }
+
+ $search[$s] = $source->get_search_set();
+ }
+
+ $_SESSION['search'][$search_request] = $search;
+}
$RCMAIL->session->remove('contact_undo');
diff --git a/program/steps/mail/attachments.inc b/program/steps/mail/attachments.inc
index f83f6892e..85aa9542b 100644
--- a/program/steps/mail/attachments.inc
+++ b/program/steps/mail/attachments.inc
@@ -118,9 +118,12 @@ if (is_array($_FILES['_attachments']['tmp_name'])) {
'alt' => rcube_label('delete')
));
}
- else {
+ else if ($COMPOSE['textbuttons']) {
$button = Q(rcube_label('delete'));
}
+ else {
+ $button = '';
+ }
$content = html::a(array(
'href' => "#delete",
diff --git a/program/steps/mail/check_recent.inc b/program/steps/mail/check_recent.inc
index 8c0b1ffc0..d3c14a38d 100644
--- a/program/steps/mail/check_recent.inc
+++ b/program/steps/mail/check_recent.inc
@@ -52,12 +52,12 @@ foreach ($a_mailboxes as $mbox_name) {
}
// Get mailbox status
- $status = $RCMAIL->storage->folder_status($mbox_name, $diff);
+ $status = $RCMAIL->storage->folder_status($mbox_name);
if ($status & 1) {
// trigger plugin hook
$RCMAIL->plugins->exec_hook('new_messages',
- array('mailbox' => $mbox_name, 'is_current' => $is_current, 'diff' => $diff));
+ array('mailbox' => $mbox_name, 'is_current' => $is_current));
}
rcmail_send_unread_count($mbox_name, true, null,
@@ -81,10 +81,9 @@ foreach ($a_mailboxes as $mbox_name) {
if (empty($_GET['_list']))
continue;
- // get overall message count; allow caching because rcube_storage::folder_status()
- // did a refresh but only in list mode
+ // get overall message count; allow caching because rcube_storage::folder_status() did a refresh
$list_mode = $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL';
- $all_count = $RCMAIL->storage->count($mbox_name, $list_mode, $list_mode == 'THREADS', false);
+ $all_count = $RCMAIL->storage->count($mbox_name, $list_mode, false, false);
$page = $RCMAIL->storage->get_page();
$page_size = $RCMAIL->storage->get_pagesize();
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index e9f638cb1..0130b1c55 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -165,8 +165,6 @@ else if ($msg_uid = $COMPOSE['param']['forward_uid']) {
else if ($msg_uid = $COMPOSE['param']['uid']) {
$compose_mode = RCUBE_COMPOSE_EDIT;
}
-
-$COMPOSE['mode'] = $compose_mode;
$OUTPUT->set_env('compose_mode', $compose_mode);
$config_show_sig = $RCMAIL->config->get('show_sig', 1);
@@ -188,18 +186,9 @@ $LINE_LENGTH = $RCMAIL->config->get('line_length', 72);
if (!empty($msg_uid) && empty($COMPOSE['as_attachment']))
{
- $mbox_name = $RCMAIL->storage->get_folder();
-
- // set format before rcube_message construction
- // use the same format as for the message view
- if (isset($_SESSION['msg_formats'][$mbox_name.':'.$msg_uid])) {
- $RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$msg_uid]);
- }
- else {
- $prefer_html = $CONFIG['prefer_html'] || $CONFIG['htmleditor'] || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT;
- $RCMAIL->config->set('prefer_html', $prefer_html);
- }
-
+ // similar as in program/steps/mail/show.inc
+ // re-set 'prefer_html' to have possibility to use html part for compose
+ $CONFIG['prefer_html'] = $CONFIG['prefer_html'] || $CONFIG['htmleditor'] || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT;
$MESSAGE = new rcube_message($msg_uid);
// make sure message is marked as read
@@ -324,8 +313,8 @@ foreach ($parts as $header) {
else if (!empty($MESSAGE->headers->from))
$fvalue = $MESSAGE->headers->from;
- // Reply to message sent by yourself (#1487074, #1489230)
- if (!empty($ident) && in_array($ident['ident'], array($fvalue, $MESSAGE->headers->from))) {
+ // Reply to message sent by yourself (#1487074)
+ if (!empty($ident) && $fvalue == $ident['ident']) {
$fvalue = $MESSAGE->headers->to;
}
}
@@ -413,7 +402,7 @@ function rcmail_compose_headers($attrib)
{
global $MESSAGE;
- list($form_start,) = get_form_tags($attrib);
+ list($form_start, $form_end) = get_form_tags($attrib);
$out = '';
$part = strtolower($attrib['part']);
@@ -477,7 +466,7 @@ function rcmail_compose_headers($attrib)
function rcmail_compose_header_from($attrib)
{
- global $MESSAGE, $OUTPUT, $RCMAIL, $COMPOSE, $compose_mode;
+ global $MESSAGE, $OUTPUT, $RCMAIL, $compose_mode;
// pass the following attributes to the form class
$field_attrib = array('name' => '_from');
@@ -488,7 +477,6 @@ function rcmail_compose_header_from($attrib)
if (count($MESSAGE->identities))
{
$a_signatures = array();
- $identities = array();
$separator = intval($RCMAIL->config->get('reply_mode')) > 0
&& ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- ';
@@ -526,21 +514,12 @@ function rcmail_compose_header_from($attrib)
$a_signatures[$identity_id]['text'] = $text;
$a_signatures[$identity_id]['html'] = $html;
}
-
- // add bcc and reply-to
- if (!empty($sql_arr['reply-to'])) {
- $identities[$identity_id]['replyto'] = $sql_arr['reply-to'];
- }
- if (!empty($sql_arr['bcc'])) {
- $identities[$identity_id]['bcc'] = $sql_arr['bcc'];
- }
}
$out = $select_from->show($MESSAGE->compose['from']);
// add signatures to client
$OUTPUT->set_env('signatures', $a_signatures);
- $OUTPUT->set_env('identities', $identities);
}
// no identities, display text input field
else {
@@ -584,13 +563,13 @@ function rcmail_compose_editor_mode()
function rcmail_message_is_html()
{
- global $RCMAIL, $MESSAGE;
- return $RCMAIL->config->get('prefer_html') && ($MESSAGE instanceof rcube_message) && $MESSAGE->has_html_part(true);
+ global $MESSAGE;
+ return ($MESSAGE instanceof rcube_message) && $MESSAGE->has_html_part(false, true);
}
function rcmail_prepare_message_body()
{
- global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $HTML_MODE;
+ global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $LINE_LENGTH, $HTML_MODE;
// use posted message body
if (!empty($_POST['_message'])) {
@@ -717,11 +696,6 @@ function rcmail_compose_part_body($part, $isHtml = false)
$body = rcmail_remove_signature($body);
}
}
-
- if ($part->ctype_parameters['format'] == 'flowed') {
- $body = rcube_mime::unfold_flowed($body);
- }
-
// add HTML formatting
$body = rcmail_plain_body($body);
if ($body) {
@@ -742,6 +716,9 @@ function rcmail_compose_part_body($part, $isHtml = false)
$txt = new rcube_html2text($body, false, true, $len);
$body = $txt->get_text();
}
+ else if ($part->ctype_secondary == 'enriched') {
+ $body = rcube_enriched::to_html($body);
+ }
else {
if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') {
$body = rcube_mime::unfold_flowed($body);
@@ -761,7 +738,7 @@ function rcmail_compose_part_body($part, $isHtml = false)
function rcmail_compose_body($attrib)
{
- global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode, $HTML_MODE, $MESSAGE_BODY;
+ global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode, $LINE_LENGTH, $HTML_MODE, $MESSAGE_BODY;
list($form_start, $form_end) = get_form_tags($attrib);
unset($attrib['form']);
@@ -945,7 +922,8 @@ function rcmail_create_forward_body($body, $bodyIsHtml)
if (!isset($COMPOSE['forward_attachments']) && is_array($MESSAGE->mime_parts))
$cid_map = rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml);
- $date = format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long'));
+ $date = format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long'));
+ $charset = $RCMAIL->output->get_charset();
if (!$bodyIsHtml) {
$prefix = "\n\n\n-------- " . rcube_label('originalmessage') . " --------\n";
@@ -997,7 +975,7 @@ function rcmail_create_forward_body($body, $bodyIsHtml)
function rcmail_create_draft_body($body, $bodyIsHtml)
{
- global $MESSAGE, $COMPOSE;
+ global $MESSAGE, $OUTPUT, $COMPOSE;
/**
* add attachments
@@ -1053,14 +1031,7 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
{
global $RCMAIL, $COMPOSE, $compose_mode;
- $loaded_attachments = array();
- foreach ((array)$COMPOSE['attachments'] as $attachment) {
- $loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment;
- }
-
- $cid_map = array();
- $messages = array();
-
+ $cid_map = $messages = array();
foreach ((array)$message->mime_parts as $pid => $part)
{
if ($part->disposition == 'attachment' || ($part->disposition == 'inline' && $bodyIsHtml) || $part->filename) {
@@ -1096,8 +1067,7 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
}
}
- if (($attachment = $loaded_attachments[rcmail_attachment_name($part) . $part->mimetype])
- || ($attachment = rcmail_save_attachment($message, $pid))) {
+ if ($attachment = rcmail_save_attachment($message, $pid)) {
$COMPOSE['attachments'][$attachment['id']] = $attachment;
if ($bodyIsHtml && ($part->content_id || $part->content_location)) {
$url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s',
@@ -1150,7 +1120,7 @@ function rcmail_write_forward_attachments()
$names = array();
$loaded_attachments = array();
- foreach ((array)$COMPOSE['attachments'] as $attachment) {
+ foreach ((array)$COMPOSE['attachments'] as $id => $attachment) {
$loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment;
}
@@ -1370,8 +1340,9 @@ function rcmail_compose_attachment_list($attrib)
if (!$attrib['id'])
$attrib['id'] = 'rcmAttachmentList';
- $out = "\n";
+ $out = "\n";
$jslist = array();
+ $button = '';
if (is_array($COMPOSE['attachments'])) {
if ($attrib['deleteicon']) {
@@ -1380,27 +1351,38 @@ function rcmail_compose_attachment_list($attrib)
'alt' => rcube_label('delete')
));
}
- else
+ else if (rcube_utils::get_boolean($attrib['textbuttons'])) {
$button = Q(rcube_label('delete'));
+ }
foreach ($COMPOSE['attachments'] as $id => $a_prop) {
if (empty($a_prop))
continue;
- $out .= html::tag('li', array('id' => 'rcmfile'.$id, 'class' => rcmail_filetype2classname($a_prop['mimetype'], $a_prop['name'])),
+ $out .= html::tag('li',
+ array(
+ 'id' => 'rcmfile'.$id,
+ 'class' => rcmail_filetype2classname($a_prop['mimetype'], $a_prop['name']),
+ 'onmouseover' => "rcube_webmail.long_subject_title_ex(this, 0)",
+ ),
html::a(array(
'href' => "#delete",
'title' => rcube_label('delete'),
'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id),
- 'class' => 'delete'),
- $button) . Q($a_prop['name']));
+ 'class' => 'delete'
+ ),
+ $button
+ ) . Q($a_prop['name'])
+ );
- $jslist['rcmfile'.$id] = array('name' => $a_prop['name'], 'complete' => true, 'mimetype' => $a_prop['mimetype']);
+ $jslist['rcmfile'.$id] = array('name' => $a_prop['name'], 'complete' => true, 'mimetype' => $a_prop['mimetype']);
}
}
if ($attrib['deleteicon'])
$COMPOSE['deleteicon'] = $CONFIG['skin_path'] . $attrib['deleteicon'];
+ else if (rcube_utils::get_boolean($attrib['textbuttons']))
+ $COMPOSE['textbuttons'] = true;
if ($attrib['cancelicon'])
$OUTPUT->set_env('cancelicon', $CONFIG['skin_path'] . $attrib['cancelicon']);
if ($attrib['loadingicon'])
@@ -1427,7 +1409,7 @@ function rcmail_compose_attachment_form($attrib)
$out = html::div($attrib,
$OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'name' => 'uploadform', 'method' => 'post', 'enctype' => 'multipart/form-data'),
- html::div(null, rcmail_compose_attachment_field()) .
+ html::div(null, rcmail_compose_attachment_field(array('size' => $attrib['attachmentfieldsize']))) .
html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) .
(get_boolean($attrib['buttons']) ? html::div('buttons',
$button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' .
@@ -1441,7 +1423,7 @@ function rcmail_compose_attachment_form($attrib)
}
-function rcmail_compose_attachment_field($attrib = array())
+function rcmail_compose_attachment_field($attrib)
{
$attrib['type'] = 'file';
$attrib['name'] = '_attachments[]';
@@ -1559,7 +1541,7 @@ function rcmail_editor_selector($attrib)
$select->add(Q(rcube_label('plaintoggle')), 'plain');
return $select->show($useHtml ? 'html' : 'plain');
-/*
+
foreach ($choices as $value => $text) {
$attrib['id'] = '_' . $value;
$attrib['value'] = $value;
@@ -1567,7 +1549,6 @@ function rcmail_editor_selector($attrib)
}
return $selector;
-*/
}
@@ -1661,7 +1642,7 @@ function rcmail_addressbook_list($attrib = array())
$class_name .= ' ' . $source['class_name'];
$out .= sprintf($line_templ,
- html_identifier($id,true),
+ html_identifier($id),
$class_name,
$source['id'],
$js_id, (!empty($source['name']) ? $source['name'] : $id));
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index a7d9ca240..2938e91e1 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -89,12 +89,11 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
}
$threading = (bool) $RCMAIL->storage->get_threading();
- $delimiter = $RCMAIL->storage->get_hierarchy_delimiter();
// set current mailbox and some other vars in client environment
$OUTPUT->set_env('mailbox', $mbox_name);
$OUTPUT->set_env('pagesize', $RCMAIL->storage->get_pagesize());
- $OUTPUT->set_env('delimiter', $delimiter);
+ $OUTPUT->set_env('delimiter', $RCMAIL->storage->get_hierarchy_delimiter());
$OUTPUT->set_env('threading', $threading);
$OUTPUT->set_env('threads', $threading || $RCMAIL->storage->get_capability('THREAD'));
$OUTPUT->set_env('preview_pane_mark_read', $RCMAIL->config->get('preview_pane_mark_read', 0));
@@ -120,48 +119,11 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
if (!$OUTPUT->ajax_call)
$OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage',
- 'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait');
+ 'copy', 'move', 'quota');
- $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true);
- $pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle);
-
- $OUTPUT->set_pagetitle($pagetitle);
+ $OUTPUT->set_pagetitle(rcmail_localize_foldername($RCMAIL->storage->mod_folder($mbox_name)));
}
-// register UI objects
-$OUTPUT->add_handlers(array(
- 'mailboxlist' => 'rcmail_mailbox_list',
- 'messages' => 'rcmail_message_list',
- 'messagecountdisplay' => 'rcmail_messagecount_display',
- 'quotadisplay' => 'rcmail_quota_display',
- 'mailboxname' => 'rcmail_mailbox_name_display',
- 'messageheaders' => 'rcmail_message_headers',
- 'messagefullheaders' => 'rcmail_message_full_headers',
- 'messagebody' => 'rcmail_message_body',
- 'messagecontentframe' => 'rcmail_messagecontent_frame',
- 'messageimportform' => 'rcmail_message_import_form',
- 'searchfilter' => 'rcmail_search_filter',
- 'searchform' => array($OUTPUT, 'search_form'),
-));
-
-// register action aliases
-$RCMAIL->register_action_map(array(
- 'refresh' => 'check_recent.inc',
- 'preview' => 'show.inc',
- 'print' => 'show.inc',
- 'move' => 'move_del.inc',
- 'delete' => 'move_del.inc',
- 'send' => 'sendmail.inc',
- 'expunge' => 'folders.inc',
- 'purge' => 'folders.inc',
- 'remove-attachment' => 'attachments.inc',
- 'display-attachment' => 'attachments.inc',
- 'upload' => 'attachments.inc',
- 'group-expand' => 'autocomplete.inc',
-));
-
-
-
/**
* Returns 'to' if current folder is configured Sent or Drafts
* or their subfolders, otherwise returns 'from'.
@@ -177,9 +139,7 @@ function rcmail_message_list_smart_column_name()
$sent_mbox = $RCMAIL->config->get('sent_mbox');
$drafts_mbox = $RCMAIL->config->get('drafts_mbox');
- if ((strpos($mbox.$delim, $sent_mbox.$delim) === 0 || strpos($mbox.$delim, $drafts_mbox.$delim) === 0)
- && strtoupper($mbox) != 'INBOX'
- ) {
+ if (strpos($mbox.$delim, $sent_mbox.$delim) === 0 || strpos($mbox.$delim, $drafts_mbox.$delim) === 0) {
return 'to';
}
@@ -260,7 +220,7 @@ function rcmail_message_list($attrib)
if (!in_array('threads', $a_show_cols))
array_unshift($a_show_cols, 'threads');
- $_SESSION['skin_path'] = $CONFIG['skin_path'];
+ $skin_path = $_SESSION['skin_path'] = $CONFIG['skin_path'];
// set client env
$OUTPUT->add_gui_object('messagelist', $attrib['id']);
@@ -272,13 +232,15 @@ function rcmail_message_list($attrib)
$OUTPUT->include_script('list.js');
- $table = new html_table($attrib);
- if (!$attrib['noheader']) {
- foreach (rcmail_message_list_head($attrib, $a_show_cols) as $cell)
- $table->add_header(array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']);
- }
+ $thead = '';
+ foreach (rcmail_message_list_head($attrib, $a_show_cols) as $cell)
+ $thead .= html::tag('td', array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']);
- return $table->show();
+ return html::tag('table',
+ $attrib,
+ html::tag('thead', null, html::tag('tr', null, $thead)) .
+ html::tag('tbody', null, ''),
+ array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary'));
}
@@ -325,7 +287,7 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
$thead = $head_replace ? rcmail_message_list_head($_SESSION['list_attrib'], $a_show_cols) : NULL;
// get name of smart From/To column in folder context
- if (array_search('fromto', $a_show_cols) !== false) {
+ if (($f = array_search('fromto', $a_show_cols)) !== false) {
$smart_col = rcmail_message_list_smart_column_name();
}
@@ -341,7 +303,7 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null
}
// loop through message headers
- foreach ($a_headers as $header) {
+ foreach ($a_headers as $n => $header) {
if (empty($header))
continue;
@@ -415,6 +377,7 @@ function rcmail_message_list_head($attrib, $a_show_cols)
global $RCMAIL;
$skin_path = $_SESSION['skin_path'];
+ $image_tag = html::img(array('src' => "%s%s", 'alt' => "%s"));
// check to see if we have some settings for sorting
$sort_col = $_SESSION['sort_col'];
@@ -450,7 +413,7 @@ function rcmail_message_list_head($attrib, $a_show_cols)
$cells = array();
// get name of smart From/To column in folder context
- if (array_search('fromto', $a_show_cols) !== false) {
+ if (($f = array_search('fromto', $a_show_cols)) !== false) {
$smart_col = rcmail_message_list_smart_column_name();
}
@@ -641,8 +604,6 @@ function rcmail_check_safe(&$message)
$message->set_safe(true);
}
}
-
- $RCMAIL->plugins->exec_hook('message_check_safe', array('message' => $message));
break;
case 2: // always
@@ -742,10 +703,7 @@ function rcmail_print_body($part, $p = array())
+ $p + array('safe' => false, 'plain' => false, 'inline_html' => true));
// convert html to text/plain
- if ($data['plain'] && ($data['type'] == 'html' || $data['type'] == 'enriched')) {
- if ($data['type'] == 'enriched') {
- $data['body'] = rcube_enriched::to_html($data['body']);
- }
+ if ($data['type'] == 'html' && $data['plain']) {
$txt = new rcube_html2text($data['body'], false, true);
$body = $txt->get_text();
$part->ctype_secondary = 'plain';
@@ -771,13 +729,8 @@ function rcmail_print_body($part, $p = array())
unset($data['body']);
// plaintext postprocessing
- if ($part->ctype_secondary == 'plain') {
- if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') {
- $body = rcube_mime::unfold_flowed($body);
- }
-
- $body = rcmail_plain_body($body);
- }
+ if ($part->ctype_secondary == 'plain')
+ $body = rcmail_plain_body($body, $part->ctype_parameters['format'] == 'flowed');
// allow post-processing of the message body
$data = $RCMAIL->plugins->exec_hook('message_part_after',
@@ -791,16 +744,16 @@ function rcmail_print_body($part, $p = array())
* Handle links and citation marks in plain text message
*
* @param string Plain text string
+ * @param boolean Text uses format=flowed
*
* @return string Formatted HTML string
*/
-function rcmail_plain_body($body)
+function rcmail_plain_body($body, $flowed=false)
{
global $RCMAIL;
// make links and email-addresses clickable
- $attribs = array('link_attribs' => array('rel' => 'noreferrer', 'target' => '_blank'));
- $replacer = new rcmail_string_replacer($attribs);
+ $replacer = new rcmail_string_replacer;
// search for patterns like links and e-mail addresses and replace with tokens
$body = $replacer->replace($body);
@@ -826,10 +779,48 @@ function rcmail_plain_body($body)
str_repeat('</blockquote>', $quote_level - $q))) . $body[$n];
$last = $n;
}
+ else if ($flowed) {
+ // previous line is flowed
+ if (isset($body[$last]) && $body[$n]
+ && $body[$last][strlen($body[$last])-1] == ' ') {
+ // merge lines
+ $body[$last] .= $body[$n];
+ unset($body[$n]);
+ }
+ else {
+ $last = $n;
+ }
+ }
}
else {
$q = 0;
- if ($quote_level > 0)
+ if ($flowed) {
+ // sig separator - line is fixed
+ if ($body[$n] == '-- ') {
+ $last = $last_sig = $n;
+ }
+ else {
+ // remove space-stuffing
+ if ($body[$n][0] == ' ')
+ $body[$n] = substr($body[$n], 1);
+
+ // previous line is flowed?
+ if (isset($body[$last]) && $body[$n]
+ && $last !== $last_sig
+ && $body[$last][strlen($body[$last])-1] == ' '
+ ) {
+ $body[$last] .= $body[$n];
+ unset($body[$n]);
+ }
+ else {
+ $last = $n;
+ }
+ }
+ if ($quote_level > 0)
+ $body[$last] = $replacer->get_replacement($replacer->add(
+ str_repeat('</blockquote>', $quote_level))) . $body[$last];
+ }
+ else if ($quote_level > 0)
$body[$n] = $replacer->get_replacement($replacer->add(
str_repeat('</blockquote>', $quote_level))) . $body[$n];
}
@@ -900,7 +891,7 @@ function rcmail_washtml_callback($tagname, $attrib, $content, $washtml)
*/
function rcmail_message_headers($attrib, $headers=null)
{
- global $MESSAGE, $PRINT_MODE, $RCMAIL;
+ global $OUTPUT, $MESSAGE, $PRINT_MODE, $RCMAIL;
static $sa_attrib;
// keep header table attrib
@@ -1085,7 +1076,7 @@ function rcmail_message_body($attrib)
$header_attrib[$regs[1]] = $value;
if (!empty($MESSAGE->parts)) {
- foreach ($MESSAGE->parts as $part) {
+ foreach ($MESSAGE->parts as $i => $part) {
if ($part->type == 'headers') {
$out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers));
}
@@ -1189,9 +1180,10 @@ function rcmail_message_body($attrib)
$show_link = array(
'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false),
'onclick' => sprintf(
- 'return %s.command(\'load-attachment\',\'%s\',this)',
+ 'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)',
JS_OBJECT_NAME,
- $attach_prop->mime_id)
+ $attach_prop->mime_id,
+ $mimetype)
);
$out .= html::p('image-attachment',
html::a($show_link + array('class' => 'image-link', 'style' => sprintf('width:%dpx', $thumbnail_size)),
@@ -1377,7 +1369,7 @@ function rcmail_html4inline($body, $container_id, $body_id='', &$attributes=null
/**
- * parse link (a, link, area) attributes and set correct target
+ * parse link attributes and set correct target
*/
function rcmail_alter_html_link($matches)
{
@@ -1386,9 +1378,9 @@ function rcmail_alter_html_link($matches)
// Support unicode/punycode in top-level domain part
$EMAIL_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[^&@"\'.][^@&"\']*\\.([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,}))';
- $tag = strtolower($matches[1]);
+ $tag = $matches[1];
$attrib = parse_attrib_string($matches[2]);
- $end = '>';
+ $end = '>';
// Remove non-printable characters in URL (#1487805)
if ($attrib['href'])
@@ -1415,11 +1407,6 @@ function rcmail_alter_html_link($matches)
$attrib['target'] = '_blank';
}
- // Better security by adding rel="noreferrer" (#1484686)
- if (($tag == 'a' || $tag == 'area') && $attrib['href'] && $attrib['href'][0] != '#') {
- $attrib['rel'] = 'noreferrer';
- }
-
// allowed attributes for a|link|area tags
$allow = array('href','name','target','onclick','id','class','style','title',
'rel','type','media','alt','coords','nohref','hreflang','shape');
@@ -1443,8 +1430,7 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
$c = count($a_parts);
$j = 0;
$out = '';
- $allvalues = array();
- $show_email = $RCMAIL->config->get('message_show_email');
+ $allvalues = array();
if ($addicon && !isset($_SESSION['writeable_abook'])) {
$_SESSION['writeable_abook'] = $RCMAIL->get_address_sources(true) ? true : false;
@@ -1458,7 +1444,7 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
$valid = check_email($mailto, false);
// phishing email prevention (#1488981), e.g. "valid@email.addr <phishing@email.addr>"
- if (!$show_email && $valid && $name && $name != $mailto && strpos($name, '@')) {
+ if ($name && $valid && $name != $mailto && strpos($name, '@')) {
$name = '';
}
@@ -1476,21 +1462,13 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null,
}
else if ($valid) {
if ($linked) {
- $attrs = array(
- 'href' => 'mailto:' . $mailto,
- 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($mailto)),
- 'class' => "rcmContactAddress",
- );
-
- if ($show_email && $name && $mailto) {
- $content = Q($name ? sprintf('%s <%s>', $name, $mailto) : $mailto);
- }
- else {
- $content = Q($name ? $name : $mailto);
- $attrs['title'] = $mailto;
- }
-
- $address = html::a($attrs, $content);
+ $address = html::a(array(
+ 'href' => 'mailto:'.$mailto,
+ 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($mailto)),
+ 'title' => $mailto,
+ 'class' => "rcmContactAddress",
+ ),
+ Q($name ? $name : $mailto));
}
else {
$address = html::span(array('title' => $mailto, 'class' => "rcmContactAddress"),
@@ -1617,6 +1595,45 @@ function rcmail_draftinfo_decode($str)
}
+function rcmail_message_part_controls($attrib)
+{
+ global $MESSAGE, $RCMAIL;
+
+ $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC));
+ if (!is_object($MESSAGE) || !is_array($MESSAGE->parts) || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part])
+ return '';
+
+ $part = $MESSAGE->mime_parts[$part];
+ $table = new html_table(array('cols' => 3));
+
+ $filename = rcmail_attachment_name($part);
+
+ if (!empty($filename)) {
+ $table->add('title', Q(rcube_label('filename')));
+ $table->add('header', Q($filename));
+ $table->add('download-link', html::a(array('href' => './?'.str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING'])), Q(rcube_label('download'))));
+ }
+
+ $table->add('title', Q(rcube_label('filesize')));
+ $table->add('header', Q($RCMAIL->message_part_size($part)));
+
+ return $table->show($attrib);
+}
+
+
+function rcmail_message_part_frame($attrib)
+{
+ global $MESSAGE;
+
+ $part = $MESSAGE->mime_parts[asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))];
+ $ctype_primary = strtolower($part->ctype_primary);
+
+ $attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary=='text' ? '_embed=' : '_preload='), $_SERVER['QUERY_STRING']);
+
+ return html::iframe($attrib);
+}
+
+
/**
* clear message composing settings
*/
@@ -1704,7 +1721,8 @@ function rcmail_send_mdn($message, &$smtp_error)
$sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file, $options);
- if ($sent) {
+ if ($sent)
+ {
$RCMAIL->storage->set_flag($message->uid, 'MDNSENT');
return true;
}
@@ -1784,15 +1802,19 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r
// Try Return-Path
if ($from_idx === null && ($return_path = $MESSAGE->headers->others['return-path'])) {
+ $return_path = array_map('strtolower', (array) $return_path);
+
foreach ($identities as $idx => $ident) {
// Return-Path header contains an email address, but on some mailing list
// it can be e.g. <pear-dev-return-55250-local=domain.tld@lists.php.net>
// where local@domain.tld is the address we're looking for (#1489241)
- $ident1 = $ident['email_ascii'];
+ $ident1 = strtolower($ident['email_ascii']);
$ident2 = str_replace('@', '=', $ident1);
+ $ident1 = '<' . $ident1 . '>';
+ $ident2 = '-' . $ident2 . '@';
- foreach ((array)$return_path as $path) {
- if (stripos($path, $ident1) !== false || stripos($path, $ident2)) {
+ foreach ($return_path as $path) {
+ if ($path == $ident1 || stripos($path, $ident2)) {
$from_idx = $idx;
break 2;
}
@@ -1800,13 +1822,27 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r
}
}
- // See identity_select plugin for example usage of this hook
- $plugin = rcmail::get_instance()->plugins->exec_hook('identity_select',
- array('message' => $MESSAGE, 'identities' => $identities, 'selected' => $from_idx));
+ // Fallback using Delivered-To
+ if ($from_idx === null && ($delivered_to = $MESSAGE->headers->others['delivered-to'])) {
+ foreach ($identities as $idx => $ident) {
+ if (in_array($ident['email_ascii'], (array)$delivered_to)) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
- $selected = $plugin['selected'];
+ // Fallback using Envelope-To
+ if ($from_idx === null && ($envelope_to = $MESSAGE->headers->others['envelope-to'])) {
+ foreach ($identities as $idx => $ident) {
+ if (in_array($ident['email_ascii'], (array)$envelope_to)) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
- return $identities[$selected !== null ? $selected : $default_identity];
+ return $identities[$from_idx !== null ? $from_idx : $default_identity];
}
// Fixes some content-type names
@@ -1863,15 +1899,13 @@ function rcmail_search_filter($attrib)
$attrib['onchange'] = JS_OBJECT_NAME.'.filter_mailbox(this.value)';
- // Content-Type values of messages with attachments
- // the same as in app.js:add_message_row()
- $ctypes = array('application/', 'multipart/m', 'multipart/signed', 'multipart/report');
-
- // Build search string of "with attachment" filter
- $attachment = str_repeat(' OR', count($ctypes)-1);
- foreach ($ctypes as $type) {
- $attachment .= ' HEADER Content-Type ' . rcube_imap_generic::escape($type);
- }
+ /*
+ RFC3501 (6.4.4): 'ALL', 'RECENT',
+ 'ANSWERED', 'DELETED', 'FLAGGED', 'SEEN',
+ 'UNANSWERED', 'UNDELETED', 'UNFLAGGED', 'UNSEEN',
+ 'NEW', // = (RECENT UNSEEN)
+ 'OLD' // = NOT RECENT
+ */
$select_filter = new html_select($attrib);
$select_filter->add(rcube_label('all'), 'ALL');
@@ -1882,7 +1916,6 @@ function rcmail_search_filter($attrib)
$select_filter->add(rcube_label('deleted'), 'DELETED');
$select_filter->add(rcube_label('undeleted'), 'UNDELETED');
}
- $select_filter->add(rcube_label('withattachment'), $attachment);
$select_filter->add(rcube_label('priority').': '.rcube_label('highest'), 'HEADER X-PRIORITY 1');
$select_filter->add(rcube_label('priority').': '.rcube_label('high'), 'HEADER X-PRIORITY 2');
$select_filter->add(rcube_label('priority').': '.rcube_label('normal'), 'NOT HEADER X-PRIORITY 1 NOT HEADER X-PRIORITY 2 NOT HEADER X-PRIORITY 4 NOT HEADER X-PRIORITY 5');
@@ -1912,36 +1945,35 @@ function rcmail_message_error($uid=null)
$RCMAIL->output->send('messageerror');
}
-function rcmail_message_import_form($attrib = array())
-{
- global $OUTPUT;
-
- // set defaults
- $attrib += array('id' => 'rcmImportform', 'buttons' => 'yes');
-
- // Get filesize, enable upload progress bar
- $max_filesize = rcube_upload_init();
-
- $button = new html_inputfield(array('type' => 'button'));
- $fileinput = new html_inputfield(array(
- 'type' => 'file',
- 'name' => '_file[]',
- 'multiple' => 'multiple',
- 'accept' => ".eml, .mbox, message/rfc822, text/*",
- ));
-
- $out = html::div($attrib,
- $OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'method' => 'post', 'enctype' => 'multipart/form-data'),
- html::tag('input', array('type' => 'hidden', 'name' => '_unlock', 'value' => '')) .
- html::div(null, $fileinput->show()) .
- html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) .
- (get_boolean($attrib['buttons']) ? html::div('buttons',
- $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' .
- $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('import-messages', this.form)"))
- ) : '')
- )
- );
+// register UI objects
+$OUTPUT->add_handlers(array(
+ 'mailboxlist' => 'rcmail_mailbox_list',
+ 'messages' => 'rcmail_message_list',
+ 'messagecountdisplay' => 'rcmail_messagecount_display',
+ 'quotadisplay' => 'rcmail_quota_display',
+ 'mailboxname' => 'rcmail_mailbox_name_display',
+ 'messageheaders' => 'rcmail_message_headers',
+ 'messagefullheaders' => 'rcmail_message_full_headers',
+ 'messagebody' => 'rcmail_message_body',
+ 'messagecontentframe' => 'rcmail_messagecontent_frame',
+ 'messagepartframe' => 'rcmail_message_part_frame',
+ 'messagepartcontrols' => 'rcmail_message_part_controls',
+ 'searchfilter' => 'rcmail_search_filter',
+ 'searchform' => array($OUTPUT, 'search_form'),
+));
- $OUTPUT->add_gui_object('importform', $attrib['id'].'Frm');
- return $out;
-}
+// register action aliases
+$RCMAIL->register_action_map(array(
+ 'refresh' => 'check_recent.inc',
+ 'preview' => 'show.inc',
+ 'print' => 'show.inc',
+ 'moveto' => 'move_del.inc',
+ 'delete' => 'move_del.inc',
+ 'send' => 'sendmail.inc',
+ 'expunge' => 'folders.inc',
+ 'purge' => 'folders.inc',
+ 'remove-attachment' => 'attachments.inc',
+ 'display-attachment' => 'attachments.inc',
+ 'upload' => 'attachments.inc',
+ 'group-expand' => 'autocomplete.inc',
+));
diff --git a/program/steps/mail/func.inc.orig b/program/steps/mail/func.inc.orig
new file mode 100644
index 000000000..5bae86c10
--- /dev/null
+++ b/program/steps/mail/func.inc.orig
@@ -0,0 +1,1964 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/mail/func.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2012, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Provide webmail functionality and GUI objects |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+// setup some global vars used by mail steps
+$SENT_MBOX = $RCMAIL->config->get('sent_mbox');
+$DRAFTS_MBOX = $RCMAIL->config->get('drafts_mbox');
+$SEARCH_MODS_DEFAULT = array(
+ '*' => array('subject'=>1, 'from'=>1),
+ $SENT_MBOX => array('subject'=>1, 'to'=>1),
+ $DRAFTS_MBOX => array('subject'=>1, 'to'=>1)
+);
+
+// always instantiate storage object (but not connect to server yet)
+$RCMAIL->storage_init();
+
+// set imap properties and session vars
+if (strlen(trim($mbox = get_input_value('_mbox', RCUBE_INPUT_GPC, true))))
+ $RCMAIL->storage->set_folder(($_SESSION['mbox'] = $mbox));
+else if ($RCMAIL->storage)
+ $_SESSION['mbox'] = $RCMAIL->storage->get_folder();
+
+if (!empty($_GET['_page']))
+ $RCMAIL->storage->set_page(($_SESSION['page'] = intval($_GET['_page'])));
+
+// set default sort col/order to session
+if (!isset($_SESSION['sort_col']))
+ $_SESSION['sort_col'] = !empty($CONFIG['message_sort_col']) ? $CONFIG['message_sort_col'] : '';
+if (!isset($_SESSION['sort_order']))
+ $_SESSION['sort_order'] = strtoupper($CONFIG['message_sort_order']) == 'ASC' ? 'ASC' : 'DESC';
+
+// set threads mode
+$a_threading = $RCMAIL->config->get('message_threading', array());
+if (isset($_GET['_threads'])) {
+ if ($_GET['_threads'])
+ $a_threading[$_SESSION['mbox']] = true;
+ else
+ unset($a_threading[$_SESSION['mbox']]);
+ $RCMAIL->user->save_prefs(array('message_threading' => $a_threading));
+}
+$RCMAIL->storage->set_threading($a_threading[$_SESSION['mbox']]);
+
+// set message set for search result
+if (!empty($_REQUEST['_search']) && isset($_SESSION['search'])
+ && $_SESSION['search_request'] == $_REQUEST['_search']
+) {
+ $RCMAIL->storage->set_search_set($_SESSION['search']);
+ $OUTPUT->set_env('search_request', $_REQUEST['_search']);
+ $OUTPUT->set_env('search_text', $_SESSION['last_text_search']);
+}
+
+// set main env variables, labels and page title
+if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
+ // connect to storage server and trigger error on failure
+ $RCMAIL->storage_connect();
+
+ $mbox_name = $RCMAIL->storage->get_folder();
+
+ if (empty($RCMAIL->action)) {
+ // initialize searching result if search_filter is used
+ if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') {
+ $search_request = md5($mbox_name.$_SESSION['search_filter']);
+
+ $RCMAIL->storage->search($mbox_name, $_SESSION['search_filter'], RCMAIL_CHARSET, rcmail_sort_column());
+ $_SESSION['search'] = $RCMAIL->storage->get_search_set();
+ $_SESSION['search_request'] = $search_request;
+ $OUTPUT->set_env('search_request', $search_request);
+ }
+
+ $search_mods = $RCMAIL->config->get('search_mods', $SEARCH_MODS_DEFAULT);
+ $OUTPUT->set_env('search_mods', $search_mods);
+ }
+
+ $threading = (bool) $RCMAIL->storage->get_threading();
+
+ // set current mailbox and some other vars in client environment
+ $OUTPUT->set_env('mailbox', $mbox_name);
+ $OUTPUT->set_env('pagesize', $RCMAIL->storage->get_pagesize());
+ $OUTPUT->set_env('delimiter', $RCMAIL->storage->get_hierarchy_delimiter());
+ $OUTPUT->set_env('threading', $threading);
+ $OUTPUT->set_env('threads', $threading || $RCMAIL->storage->get_capability('THREAD'));
+ $OUTPUT->set_env('preview_pane_mark_read', $RCMAIL->config->get('preview_pane_mark_read', 0));
+ if ($RCMAIL->storage->get_capability('QUOTA')) {
+ $OUTPUT->set_env('quota', true);
+ }
+
+ foreach (array('delete_junk','flag_for_deletion','read_when_deleted','skip_deleted','display_next','message_extwin','compose_extwin','forward_attachment') as $prop) {
+ if ($CONFIG[$prop])
+ $OUTPUT->set_env($prop, true);
+ }
+
+ if ($CONFIG['trash_mbox'])
+ $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']);
+ if ($CONFIG['drafts_mbox'])
+ $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']);
+ if ($CONFIG['junk_mbox'])
+ $OUTPUT->set_env('junk_mailbox', $CONFIG['junk_mbox']);
+
+ 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');
+
+ $OUTPUT->set_pagetitle(rcmail_localize_foldername($RCMAIL->storage->mod_folder($mbox_name)));
+}
+
+/**
+ * Returns 'to' if current folder is configured Sent or Drafts
+ * or their subfolders, otherwise returns 'from'.
+ *
+ * @return string Column name
+ */
+function rcmail_message_list_smart_column_name()
+{
+ global $RCMAIL;
+
+ $delim = $RCMAIL->storage->get_hierarchy_delimiter();
+ $mbox = $RCMAIL->storage->get_folder();
+ $sent_mbox = $RCMAIL->config->get('sent_mbox');
+ $drafts_mbox = $RCMAIL->config->get('drafts_mbox');
+
+ if (strpos($mbox.$delim, $sent_mbox.$delim) === 0 || strpos($mbox.$delim, $drafts_mbox.$delim) === 0) {
+ return 'to';
+ }
+
+ return 'from';
+}
+
+/**
+ * Returns configured messages list sorting column name
+ * The name is context-sensitive, which means if sorting is set to 'fromto'
+ * it will return 'from' or 'to' according to current folder type.
+ *
+ * @return string Column name
+ */
+function rcmail_sort_column()
+{
+ global $RCMAIL;
+
+ if (isset($_SESSION['sort_col'])) {
+ $column = $_SESSION['sort_col'];
+ }
+ else {
+ $column = $RCMAIL->config->get('message_sort_col');
+ }
+
+ // get name of smart From/To column in folder context
+ if ($column == 'fromto') {
+ $column = rcmail_message_list_smart_column_name();
+ }
+
+ return $column;
+}
+
+/**
+ * Returns configured message list sorting order
+ *
+ * @return string Sorting order (ASC|DESC)
+ */
+function rcmail_sort_order()
+{
+ global $RCMAIL;
+
+ if (isset($_SESSION['sort_order'])) {
+ return $_SESSION['sort_order'];
+ }
+
+ return $RCMAIL->config->get('message_sort_order');
+}
+
+/**
+ * return the message list as HTML table
+ */
+function rcmail_message_list($attrib)
+{
+ global $CONFIG, $OUTPUT;
+
+ // add some labels to client
+ $OUTPUT->add_label('from', 'to');
+
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcubemessagelist';
+
+ // define list of cols to be displayed based on parameter or config
+ if (empty($attrib['columns'])) {
+ $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject');
+ $OUTPUT->set_env('col_movable', !in_array('list_cols', (array)$CONFIG['dont_override']));
+ }
+ else {
+ $a_show_cols = preg_split('/[\s,;]+/', strip_quotes($attrib['columns']));
+ $attrib['columns'] = $a_show_cols;
+ }
+
+ // save some variables for use in ajax list
+ $_SESSION['list_attrib'] = $attrib;
+ // make sure 'threads' and 'subject' columns are present
+ if (!in_array('subject', $a_show_cols))
+ array_unshift($a_show_cols, 'subject');
+ if (!in_array('threads', $a_show_cols))
+ array_unshift($a_show_cols, 'threads');
+
+ $skin_path = $_SESSION['skin_path'] = $CONFIG['skin_path'];
+
+ // set client env
+ $OUTPUT->add_gui_object('messagelist', $attrib['id']);
+ $OUTPUT->set_env('autoexpand_threads', intval($CONFIG['autoexpand_threads']));
+ $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->include_script('list.js');
+
+ $thead = '';
+ foreach (rcmail_message_list_head($attrib, $a_show_cols) as $cell)
+ $thead .= html::tag('td', array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']);
+
+ return html::tag('table',
+ $attrib,
+ html::tag('thead', null, html::tag('tr', null, $thead)) .
+ html::tag('tbody', null, ''),
+ array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary'));
+}
+
+
+/**
+ * return javascript commands to add rows to the message list
+ */
+function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null)
+{
+ global $CONFIG, $RCMAIL, $OUTPUT;
+
+ if (empty($a_show_cols)) {
+ if (!empty($_SESSION['list_attrib']['columns']))
+ $a_show_cols = $_SESSION['list_attrib']['columns'];
+ else
+ $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject');
+ }
+ else {
+ if (!is_array($a_show_cols))
+ $a_show_cols = preg_split('/[\s,;]+/', strip_quotes($a_show_cols));
+ $head_replace = true;
+ }
+
+ $mbox = $RCMAIL->storage->get_folder();
+
+ // make sure 'threads' and 'subject' columns are present
+ if (!in_array('subject', $a_show_cols))
+ array_unshift($a_show_cols, 'subject');
+ 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);
+
+ // Plugins may set header's list_cols/list_flags and other rcube_message_header variables
+ // and list columns
+ $plugin = $RCMAIL->plugins->exec_hook('messages_list',
+ array('messages' => $a_headers, 'cols' => $a_show_cols));
+
+ $a_show_cols = $plugin['cols'];
+ $a_headers = $plugin['messages'];
+
+ $thead = $head_replace ? rcmail_message_list_head($_SESSION['list_attrib'], $a_show_cols) : NULL;
+
+ // get name of smart From/To column in folder context
+ if (($f = array_search('fromto', $a_show_cols)) !== false) {
+ $smart_col = rcmail_message_list_smart_column_name();
+ }
+
+ $OUTPUT->command('set_message_coltypes', $a_show_cols, $thead, $smart_col);
+
+ if (empty($a_headers))
+ return;
+
+ // remove 'threads', 'attachment', 'flag', 'status' columns, we don't need them here
+ foreach (array('threads', 'attachment', 'flag', 'status', 'priority') as $col) {
+ if (($key = array_search($col, $a_show_cols)) !== FALSE)
+ unset($a_show_cols[$key]);
+ }
+
+ // loop through message headers
+ foreach ($a_headers as $n => $header) {
+ if (empty($header))
+ continue;
+
+ $a_msg_cols = array();
+ $a_msg_flags = array();
+
+ // format each col; similar as in rcmail_message_list()
+ foreach ($a_show_cols as $col) {
+ $col_name = $col == 'fromto' ? $smart_col : $col;
+
+ if (in_array($col_name, array('from', 'to', 'cc', 'replyto')))
+ $cont = rcmail_address_string($header->$col_name, 3, false, null, $header->charset);
+ else if ($col == 'subject') {
+ $cont = trim(rcube_mime::decode_header($header->$col, $header->charset));
+ if (!$cont) $cont = rcube_label('nosubject');
+ $cont = Q($cont);
+ }
+ else if ($col == 'size')
+ $cont = show_bytes($header->$col);
+ else if ($col == 'date')
+ $cont = format_date($header->date);
+ else
+ $cont = Q($header->$col);
+
+ $a_msg_cols[$col] = $cont;
+ }
+
+ $a_msg_flags = array_change_key_case(array_map('intval', (array) $header->flags));
+ if ($header->depth)
+ $a_msg_flags['depth'] = $header->depth;
+ else if ($header->has_children)
+ $roots[] = $header->uid;
+ if ($header->parent_uid)
+ $a_msg_flags['parent_uid'] = $header->parent_uid;
+ if ($header->has_children)
+ $a_msg_flags['has_children'] = $header->has_children;
+ if ($header->unread_children)
+ $a_msg_flags['unread_children'] = $header->unread_children;
+ if ($header->others['list-post'])
+ $a_msg_flags['ml'] = 1;
+ if ($header->priority)
+ $a_msg_flags['prio'] = (int) $header->priority;
+
+ $a_msg_flags['ctype'] = Q($header->ctype);
+ $a_msg_flags['mbox'] = $mbox;
+
+ // merge with plugin result (Deprecated, use $header->flags)
+ if (!empty($header->list_flags) && is_array($header->list_flags))
+ $a_msg_flags = array_merge($a_msg_flags, $header->list_flags);
+ if (!empty($header->list_cols) && is_array($header->list_cols))
+ $a_msg_cols = array_merge($a_msg_cols, $header->list_cols);
+
+ $OUTPUT->command('add_message_row',
+ $header->uid,
+ $a_msg_cols,
+ $a_msg_flags,
+ $insert_top);
+ }
+
+ if ($RCMAIL->storage->get_threading()) {
+ $OUTPUT->command('init_threads', (array) $roots, $mbox);
+ }
+}
+
+
+/*
+ * Creates <THEAD> for message list table
+ */
+function rcmail_message_list_head($attrib, $a_show_cols)
+{
+ global $RCMAIL;
+
+ $skin_path = $_SESSION['skin_path'];
+ $image_tag = html::img(array('src' => "%s%s", 'alt' => "%s"));
+
+ // check to see if we have some settings for sorting
+ $sort_col = $_SESSION['sort_col'];
+ $sort_order = $_SESSION['sort_order'];
+
+ $dont_override = (array)$RCMAIL->config->get('dont_override');
+ $disabled_sort = in_array('message_sort_col', $dont_override);
+ $disabled_order = in_array('message_sort_order', $dont_override);
+
+ $RCMAIL->output->set_env('disabled_sort_col', $disabled_sort);
+ $RCMAIL->output->set_env('disabled_sort_order', $disabled_order);
+
+ // define sortable columns
+ if ($disabled_sort)
+ $a_sort_cols = $sort_col && !$disabled_order ? array($sort_col) : array();
+ else
+ $a_sort_cols = array('subject', 'date', 'from', 'to', 'fromto', 'size', 'cc');
+
+ if (!empty($attrib['optionsmenuicon'])) {
+ $onclick = 'return ' . JS_OBJECT_NAME . ".command('menu-open', 'messagelistmenu')";
+ if ($attrib['optionsmenuicon'] === true || $attrib['optionsmenuicon'] == 'true')
+ $list_menu = html::div(array('onclick' => $onclick, 'class' => 'listmenu',
+ 'id' => 'listmenulink', 'title' => rcube_label('listoptions')));
+ else
+ $list_menu = html::a(array('href' => '#', 'onclick' => $onclick),
+ html::img(array('src' => $skin_path . $attrib['optionsmenuicon'],
+ 'id' => 'listmenulink', 'title' => rcube_label('listoptions')))
+ );
+ }
+ else
+ $list_menu = '';
+
+ $cells = array();
+
+ // get name of smart From/To column in folder context
+ if (($f = array_search('fromto', $a_show_cols)) !== false) {
+ $smart_col = rcmail_message_list_smart_column_name();
+ }
+
+ foreach ($a_show_cols as $col) {
+ // get column name
+ switch ($col) {
+ case 'flag':
+ $col_name = '<span class="flagged">&nbsp;</span>';
+ break;
+ case 'attachment':
+ case 'priority':
+ case 'status':
+ $col_name = '<span class="' . $col .'">&nbsp;</span>';
+ break;
+ case 'threads':
+ $col_name = $list_menu;
+ break;
+ case 'fromto':
+ $col_name = Q(rcube_label($smart_col));
+ break;
+ default:
+ $col_name = Q(rcube_label($col));
+ }
+
+ // make sort links
+ if (in_array($col, $a_sort_cols))
+ $col_name = html::a(array('href'=>"./#sort", 'onclick' => 'return '.JS_OBJECT_NAME.".command('sort','".$col."',this)", 'title' => rcube_label('sortby')), $col_name);
+ else if ($col_name[0] != '<')
+ $col_name = '<span class="' . $col .'">' . $col_name . '</span>';
+
+ $sort_class = $col == $sort_col && !$disabled_order ? " sorted$sort_order" : '';
+ $class_name = $col.$sort_class;
+
+ // put it all together
+ $cells[] = array('className' => $class_name, 'id' => "rcm$col", 'html' => $col_name);
+ }
+
+ return $cells;
+}
+
+
+/**
+ * return an HTML iframe for loading mail content
+ */
+function rcmail_messagecontent_frame($attrib)
+{
+ global $OUTPUT, $RCMAIL;
+
+ if (empty($attrib['id']))
+ $attrib['id'] = 'rcmailcontentwindow';
+
+ $attrib['name'] = $attrib['id'];
+
+ if ($RCMAIL->config->get('preview_pane'))
+ $OUTPUT->set_env('contentframe', $attrib['id']);
+ $OUTPUT->set_env('blankpage', $attrib['src'] ? $OUTPUT->abs_url($attrib['src']) : 'program/resources/blank.gif');
+
+ return $OUTPUT->frame($attrib, true);
+}
+
+
+function rcmail_messagecount_display($attrib)
+{
+ global $RCMAIL;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmcountdisplay';
+
+ $RCMAIL->output->add_gui_object('countdisplay', $attrib['id']);
+
+ $content = $RCMAIL->action != 'show' ? rcmail_get_messagecount_text() : rcube_label('loading');
+
+ return html::span($attrib, $content);
+}
+
+
+function rcmail_get_messagecount_text($count=NULL, $page=NULL)
+{
+ global $RCMAIL;
+
+ if ($page === NULL) {
+ $page = $RCMAIL->storage->get_page();
+ }
+
+ $page_size = $RCMAIL->storage->get_pagesize();
+ $start_msg = ($page-1) * $page_size + 1;
+
+ if ($count!==NULL)
+ $max = $count;
+ else if ($RCMAIL->action)
+ $max = $RCMAIL->storage->count(NULL, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL');
+
+ if ($max==0)
+ $out = rcube_label('mailboxempty');
+ else
+ $out = rcube_label(array('name' => $RCMAIL->storage->get_threading() ? 'threadsfromto' : 'messagesfromto',
+ 'vars' => array('from' => $start_msg,
+ 'to' => min($max, $start_msg + $page_size - 1),
+ 'count' => $max)));
+
+ return Q($out);
+}
+
+
+function rcmail_mailbox_name_display($attrib)
+{
+ global $RCMAIL;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmmailboxname';
+
+ $RCMAIL->output->add_gui_object('mailboxname', $attrib['id']);
+
+ return html::span($attrib, rcmail_get_mailbox_name_text());
+}
+
+
+function rcmail_get_mailbox_name_text()
+{
+ global $RCMAIL;
+ return rcmail_localize_foldername($RCMAIL->storage->get_folder());
+}
+
+
+function rcmail_send_unread_count($mbox_name, $force=false, $count=null, $mark='')
+{
+ global $RCMAIL;
+
+ $old_unseen = rcmail_get_unseen_count($mbox_name);
+
+ if ($count === null)
+ $unseen = $RCMAIL->storage->count($mbox_name, 'UNSEEN', $force);
+ else
+ $unseen = $count;
+
+ if ($unseen != $old_unseen || ($mbox_name == 'INBOX'))
+ $RCMAIL->output->command('set_unread_count', $mbox_name, $unseen,
+ ($mbox_name == 'INBOX'), $unseen && $mark ? $mark : '');
+
+ rcmail_set_unseen_count($mbox_name, $unseen);
+
+ return $unseen;
+}
+
+
+function rcmail_set_unseen_count($mbox_name, $count)
+{
+ // @TODO: this data is doubled (session and cache tables) if caching is enabled
+
+ // Make sure we have an array here (#1487066)
+ if (!is_array($_SESSION['unseen_count']))
+ $_SESSION['unseen_count'] = array();
+
+ $_SESSION['unseen_count'][$mbox_name] = $count;
+}
+
+
+function rcmail_get_unseen_count($mbox_name)
+{
+ if (is_array($_SESSION['unseen_count']) && array_key_exists($mbox_name, $_SESSION['unseen_count']))
+ return $_SESSION['unseen_count'][$mbox_name];
+ else
+ return null;
+}
+
+
+/**
+ * Sets message is_safe flag according to 'show_images' option value
+ *
+ * @param object rcube_message Message
+ */
+function rcmail_check_safe(&$message)
+{
+ global $RCMAIL;
+
+ if (!$message->is_safe
+ && ($show_images = $RCMAIL->config->get('show_images'))
+ && $message->has_html_part()
+ ) {
+ switch ($show_images) {
+ case 1: // known senders only
+ // get default addressbook, like in addcontact.inc
+ $CONTACTS = $RCMAIL->get_address_book(-1, true);
+
+ if ($CONTACTS) {
+ $result = $CONTACTS->search('email', $message->sender['mailto'], 1, false);
+ if ($result->count) {
+ $message->set_safe(true);
+ }
+ }
+ break;
+
+ case 2: // always
+ $message->set_safe(true);
+ break;
+ }
+ }
+}
+
+
+/**
+ * Cleans up the given message HTML Body (for displaying)
+ *
+ * @param string HTML
+ * @param array Display parameters
+ * @param array CID map replaces (inline images)
+ * @return string Clean HTML
+ */
+function rcmail_wash_html($html, $p, $cid_replaces)
+{
+ global $REMOTE_OBJECTS;
+
+ $p += array('safe' => false, 'inline_html' => true);
+
+ // charset was converted to UTF-8 in rcube_storage::get_message_part(),
+ // change/add charset specification in HTML accordingly,
+ // washtml cannot work without that
+ $meta = '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />';
+
+ // remove old meta tag and add the new one, making sure
+ // that it is placed in the head (#1488093)
+ $html = preg_replace('/<meta[^>]+charset=[a-z0-9-_]+[^>]*>/Ui', '', $html);
+ $html = preg_replace('/(<head[^>]*>)/Ui', '\\1'.$meta, $html, -1, $rcount);
+ if (!$rcount) {
+ $html = '<head>' . $meta . '</head>' . $html;
+ }
+
+ // clean HTML with washhtml by Frederic Motte
+ $wash_opts = array(
+ 'show_washed' => false,
+ 'allow_remote' => $p['safe'],
+ 'blocked_src' => "./program/resources/blocked.gif",
+ 'charset' => RCMAIL_CHARSET,
+ 'cid_map' => $cid_replaces,
+ 'html_elements' => array('body'),
+ );
+
+ if (!$p['inline_html']) {
+ $wash_opts['html_elements'] = array('html','head','title','body');
+ }
+ if ($p['safe']) {
+ $wash_opts['html_elements'][] = 'link';
+ $wash_opts['html_attribs'] = array('rel','type');
+ }
+
+ // overwrite washer options with options from plugins
+ if (isset($p['html_elements']))
+ $wash_opts['html_elements'] = $p['html_elements'];
+ if (isset($p['html_attribs']))
+ $wash_opts['html_attribs'] = $p['html_attribs'];
+
+ // initialize HTML washer
+ $washer = new rcube_washtml($wash_opts);
+
+ if (!$p['skip_washer_form_callback'])
+ $washer->add_callback('form', 'rcmail_washtml_callback');
+
+ // allow CSS styles, will be sanitized by rcmail_washtml_callback()
+ if (!$p['skip_washer_style_callback'])
+ $washer->add_callback('style', 'rcmail_washtml_callback');
+
+ // Remove non-UTF8 characters (#1487813)
+ $html = rc_utf8_clean($html);
+
+ $html = $washer->wash($html);
+ $REMOTE_OBJECTS = $washer->extlinks;
+
+ return $html;
+}
+
+
+/**
+ * Convert the given message part to proper HTML
+ * which can be displayed the message view
+ *
+ * @param object rcube_message_part Message part
+ * @param array Display parameters array
+ * @return string Formatted HTML string
+ */
+function rcmail_print_body($part, $p = array())
+{
+ global $RCMAIL;
+
+ // trigger plugin hook
+ $data = $RCMAIL->plugins->exec_hook('message_part_before',
+ array('type' => $part->ctype_secondary, 'body' => $part->body, 'id' => $part->mime_id)
+ + $p + array('safe' => false, 'plain' => false, 'inline_html' => true));
+
+ // convert html to text/plain
+ if ($data['type'] == 'html' && $data['plain']) {
+ $txt = new rcube_html2text($data['body'], false, true);
+ $body = $txt->get_text();
+ $part->ctype_secondary = 'plain';
+ }
+ // text/html
+ else if ($data['type'] == 'html') {
+ $body = rcmail_wash_html($data['body'], $data, $part->replaces);
+ $part->ctype_secondary = $data['type'];
+ }
+ // text/enriched
+ else if ($data['type'] == 'enriched') {
+ $body = rcube_enriched::to_html($data['body']);
+ $body = rcmail_wash_html($body, $data, $part->replaces);
+ $part->ctype_secondary = 'html';
+ }
+ else {
+ // assert plaintext
+ $body = $part->body;
+ $part->ctype_secondary = $data['type'] = 'plain';
+ }
+
+ // free some memory (hopefully)
+ unset($data['body']);
+
+ // plaintext postprocessing
+ if ($part->ctype_secondary == 'plain')
+ $body = rcmail_plain_body($body, $part->ctype_parameters['format'] == 'flowed');
+
+ // allow post-processing of the message body
+ $data = $RCMAIL->plugins->exec_hook('message_part_after',
+ array('type' => $part->ctype_secondary, 'body' => $body, 'id' => $part->mime_id) + $data);
+
+ return $data['type'] == 'html' ? $data['body'] : html::tag('pre', array(), $data['body']);
+}
+
+
+/**
+ * Handle links and citation marks in plain text message
+ *
+ * @param string Plain text string
+ * @param boolean Text uses format=flowed
+ *
+ * @return string Formatted HTML string
+ */
+function rcmail_plain_body($body, $flowed=false)
+{
+ global $RCMAIL;
+
+ // make links and email-addresses clickable
+ $replacer = new rcmail_string_replacer;
+
+ // search for patterns like links and e-mail addresses and replace with tokens
+ $body = $replacer->replace($body);
+
+ // split body into single lines
+ $body = preg_split('/\r?\n/', $body);
+ $quote_level = 0;
+ $last = -1;
+
+ // find/mark quoted lines...
+ for ($n=0, $cnt=count($body); $n < $cnt; $n++) {
+ if ($body[$n][0] == '>' && preg_match('/^(>+ {0,1})+/', $body[$n], $regs)) {
+ $q = substr_count($regs[0], '>');
+ $body[$n] = substr($body[$n], strlen($regs[0]));
+
+ if ($q > $quote_level) {
+ $body[$n] = $replacer->get_replacement($replacer->add(
+ str_repeat('<blockquote>', $q - $quote_level))) . $body[$n];
+ }
+ else if ($q < $quote_level) {
+ $body[$n] = $replacer->get_replacement($replacer->add(
+ str_repeat('</blockquote>', $quote_level - $q))) . $body[$n];
+ }
+ else if ($flowed) {
+ // previous line is flowed
+ if (isset($body[$last]) && $body[$n]
+ && $body[$last][strlen($body[$last])-1] == ' ') {
+ // merge lines
+ $body[$last] .= $body[$n];
+ unset($body[$n]);
+ }
+ else {
+ $last = $n;
+ }
+ }
+ }
+ else {
+ $q = 0;
+ if ($flowed) {
+ // sig separator - line is fixed
+ if ($body[$n] == '-- ') {
+ $last = $last_sig = $n;
+ }
+ else {
+ // remove space-stuffing
+ if ($body[$n][0] == ' ')
+ $body[$n] = substr($body[$n], 1);
+
+ // previous line is flowed?
+ if (isset($body[$last]) && $body[$n]
+ && $last !== $last_sig
+ && $body[$last][strlen($body[$last])-1] == ' '
+ ) {
+ $body[$last] .= $body[$n];
+ unset($body[$n]);
+ }
+ else {
+ $last = $n;
+ }
+ }
+ if ($quote_level > 0)
+ $body[$last] = $replacer->get_replacement($replacer->add(
+ str_repeat('</blockquote>', $quote_level))) . $body[$last];
+ }
+ else if ($quote_level > 0)
+ $body[$n] = $replacer->get_replacement($replacer->add(
+ str_repeat('</blockquote>', $quote_level))) . $body[$n];
+ }
+
+ $quote_level = $q;
+ }
+
+ $body = join("\n", $body);
+
+ // quote plain text (don't use Q() here, to display entities "as is")
+ $table = get_html_translation_table(HTML_SPECIALCHARS);
+ unset($table['?']);
+ $body = strtr($body, $table);
+
+ // colorize signature (up to <sig_max_lines> lines)
+ $len = strlen($body);
+ $sig_max_lines = $RCMAIL->config->get('sig_max_lines', 15);
+ while (($sp = strrpos($body, "-- \n", $sp ? -$len+$sp-1 : 0)) !== false) {
+ if ($sp == 0 || $body[$sp-1] == "\n") {
+ // do not touch blocks with more that X lines
+ if (substr_count($body, "\n", $sp) < $sig_max_lines)
+ $body = substr($body, 0, max(0, $sp))
+ .'<span class="sig">'.substr($body, $sp).'</span>';
+ break;
+ }
+ }
+
+ // insert url/mailto links and citation tags
+ $body = $replacer->resolve($body);
+
+ return $body;
+}
+
+
+/**
+ * Callback function for washtml cleaning class
+ */
+function rcmail_washtml_callback($tagname, $attrib, $content, $washtml)
+{
+ switch ($tagname) {
+ case 'form':
+ $out = html::div('form', $content);
+ break;
+
+ case 'style':
+ // decode all escaped entities and reduce to ascii strings
+ $stripped = preg_replace('/[^a-zA-Z\(:;]/', '', rcmail_xss_entity_decode($content));
+
+ // now check for evil strings like expression, behavior or url()
+ if (!preg_match('/expression|behavior|javascript:|import[^a]/i', $stripped)) {
+ if (!$washtml->get_config('allow_remote') && stripos($stripped, 'url('))
+ $washtml->extlinks = true;
+ else
+ $out = html::tag('style', array('type' => 'text/css'), $content);
+ break;
+ }
+
+ default:
+ $out = '';
+ }
+
+ return $out;
+}
+
+
+/**
+ * return table with message headers
+ */
+function rcmail_message_headers($attrib, $headers=null)
+ {
+ global $OUTPUT, $MESSAGE, $PRINT_MODE, $RCMAIL;
+ static $sa_attrib;
+
+ // keep header table attrib
+ if (is_array($attrib) && !$sa_attrib && !$attrib['valueof'])
+ $sa_attrib = $attrib;
+ else if (!is_array($attrib) && is_array($sa_attrib))
+ $attrib = $sa_attrib;
+
+ if (!isset($MESSAGE))
+ return FALSE;
+
+ // get associative array of headers object
+ if (!$headers) {
+ $headers_obj = $MESSAGE->headers;
+ $headers = get_object_vars($MESSAGE->headers);
+ }
+ else if (is_object($headers)) {
+ $headers_obj = $headers;
+ $headers = get_object_vars($headers_obj);
+ }
+ else {
+ $headers_obj = rcube_message_header::from_array($headers);
+ }
+
+ // show these headers
+ $standard_headers = array('subject', 'from', 'sender', 'to', 'cc', 'bcc', 'replyto',
+ 'mail-reply-to', 'mail-followup-to', 'date', 'priority');
+ $exclude_headers = $attrib['exclude'] ? explode(',', $attrib['exclude']) : array();
+ $output_headers = array();
+
+ foreach ($standard_headers as $hkey) {
+ $ishtml = false;
+
+ if ($headers[$hkey])
+ $value = $headers[$hkey];
+ else if ($headers['others'][$hkey])
+ $value = $headers['others'][$hkey];
+ else
+ continue;
+
+ if (in_array($hkey, $exclude_headers))
+ continue;
+
+ $header_title = rcube_label(preg_replace('/(^mail-|-)/', '', $hkey));
+
+ if ($hkey == 'date') {
+ if ($PRINT_MODE)
+ $header_value = format_date($value, $RCMAIL->config->get('date_long', 'x'));
+ else
+ $header_value = format_date($value);
+ }
+ else if ($hkey == 'priority') {
+ if ($value) {
+ $header_value = html::span('prio' . $value, rcmail_localized_priority($value));
+ }
+ else
+ continue;
+ }
+ else if ($hkey == 'replyto') {
+ if ($headers['replyto'] != $headers['from']) {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else
+ continue;
+ }
+ else if ($hkey == 'mail-reply-to') {
+ if ($headers['mail-replyto'] != $headers['reply-to']
+ && $headers['reply-to'] != $headers['from']
+ ) {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else
+ continue;
+ }
+ else if ($hkey == 'sender') {
+ if ($headers['sender'] != $headers['from']) {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else
+ continue;
+ }
+ else if ($hkey == 'mail-followup-to') {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else if (in_array($hkey, array('from', 'to', 'cc', 'bcc'))) {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else if ($hkey == 'subject' && empty($value))
+ $header_value = rcube_label('nosubject');
+ else
+ $header_value = trim(rcube_mime::decode_header($value, $headers['charset']));
+
+ $output_headers[$hkey] = array(
+ 'title' => $header_title,
+ 'value' => $header_value,
+ 'raw' => $value,
+ 'html' => $ishtml,
+ );
+ }
+
+ $plugin = $RCMAIL->plugins->exec_hook('message_headers_output',
+ array('output' => $output_headers, 'headers' => $headers_obj, 'exclude' => $exclude_headers));
+
+ // single header value is requested
+ if (!empty($attrib['valueof']))
+ return Q($plugin['output'][$attrib['valueof']]['value'], ($attrib['valueof'] == 'subject' ? 'strict' : 'show'));
+
+ // compose html table
+ $table = new html_table(array('cols' => 2));
+
+ foreach ($plugin['output'] as $hkey => $row) {
+ $table->add(array('class' => 'header-title'), Q($row['title']));
+ $table->add(array('class' => 'header '.$hkey), $row['html'] ? $row['value'] : Q($row['value'], ($hkey == 'subject' ? 'strict' : 'show')));
+ }
+
+ return $table->show($attrib);
+}
+
+/**
+ * Convert Priority header value into a localized string
+ */
+function rcmail_localized_priority($value)
+{
+ $labels_map = array(
+ '1' => 'highest',
+ '2' => 'high',
+ '3' => 'normal',
+ '4' => 'low',
+ '5' => 'lowest',
+ );
+
+ if ($value && $labels_map[$value])
+ return rcube_label($labels_map[$value]);
+
+ return '';
+}
+
+/**
+ * return block to show full message headers
+ */
+function rcmail_message_full_headers($attrib, $headers=NULL)
+{
+ global $OUTPUT;
+
+ $html = html::div(array('id' => "all-headers", 'class' => "all", 'style' => 'display:none'), html::div(array('id' => 'headers-source'), ''));
+ $html .= html::div(array('class' => "more-headers show-headers", 'onclick' => "return ".JS_OBJECT_NAME.".command('show-headers','',this)", 'title' => rcube_label('togglefullheaders')), '');
+
+ $OUTPUT->add_gui_object('all_headers_row', 'all-headers');
+ $OUTPUT->add_gui_object('all_headers_box', 'headers-source');
+
+ return html::div($attrib, $html);
+}
+
+
+/**
+ * Handler for the 'messagebody' GUI object
+ *
+ * @param array Named parameters
+ * @return string HTML content showing the message body
+ */
+function rcmail_message_body($attrib)
+{
+ global $CONFIG, $OUTPUT, $MESSAGE, $RCMAIL, $REMOTE_OBJECTS;
+
+ if (!is_array($MESSAGE->parts) && empty($MESSAGE->body))
+ return '';
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmailMsgBody';
+
+ $safe_mode = $MESSAGE->is_safe || intval($_GET['_safe']);
+ $out = '';
+
+ $header_attrib = array();
+ foreach ($attrib as $attr => $value)
+ if (preg_match('/^headertable([a-z]+)$/i', $attr, $regs))
+ $header_attrib[$regs[1]] = $value;
+
+ if (!empty($MESSAGE->parts)) {
+ foreach ($MESSAGE->parts as $i => $part) {
+ if ($part->type == 'headers') {
+ $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers));
+ }
+ else if ($part->type == 'content') {
+ // unsapported
+ if ($part->realtype) {
+ if ($part->realtype == 'multipart/encrypted') {
+ $out .= html::span('part-notice', rcube_label('encryptedmessage'));
+ }
+ continue;
+ }
+ else if (!$part->size) {
+ continue;
+ }
+ // Check if we have enough memory to handle the message in it
+ // #1487424: we need up to 10x more memory than the body
+ else if (!rcmail_mem_check($part->size * 10)) {
+ $out .= html::span('part-notice', rcube_label('messagetoobig'). ' '
+ . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id
+ .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), rcube_label('download')));
+ continue;
+ }
+
+ if (empty($part->ctype_parameters) || empty($part->ctype_parameters['charset']))
+ $part->ctype_parameters['charset'] = $MESSAGE->headers->charset;
+
+ // fetch part if not available
+ if (!isset($part->body))
+ $part->body = $MESSAGE->get_part_content($part->mime_id);
+
+ // extract headers from message/rfc822 parts
+ if ($part->mimetype == 'message/rfc822') {
+ $msgpart = rcube_mime::parse_message($part->body);
+ if (!empty($msgpart->headers)) {
+ $part = $msgpart;
+ $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers));
+ }
+ }
+
+ // message is cached but not exists (#1485443), or other error
+ if ($part->body === false) {
+ rcmail_message_error($MESSAGE->uid);
+ }
+
+ $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', array(
+ 'part' => $part, 'prefix' => ''));
+
+ $body = rcmail_print_body($part, array('safe' => $safe_mode, 'plain' => !$CONFIG['prefer_html']));
+
+ if ($part->ctype_secondary == 'html') {
+ $body = rcmail_html4inline($body, $attrib['id'], 'rcmBody', $attrs, $safe_mode);
+ $div_attr = array('class' => 'message-htmlpart');
+ $style = array();
+
+ if (!empty($attrs)) {
+ foreach ($attrs as $a_idx => $a_val)
+ $style[] = $a_idx . ': ' . $a_val;
+ if (!empty($style))
+ $div_attr['style'] = implode('; ', $style);
+ }
+
+ $out .= html::div($div_attr, $plugin['prefix'] . $body);
+ }
+ else
+ $out .= html::div('message-part', $plugin['prefix'] . $body);
+ }
+ }
+ }
+ else {
+ // Check if we have enough memory to handle the message in it
+ // #1487424: we need up to 10x more memory than the body
+ if (!rcmail_mem_check(strlen($MESSAGE->body) * 10)) {
+ $out .= html::span('part-notice', rcube_label('messagetoobig'). ' '
+ . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part=0'
+ .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), rcube_label('download')));
+ }
+ else {
+ $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', array(
+ 'part' => $MESSAGE, 'prefix' => ''));
+
+ $out .= html::div('message-part', $plugin['prefix'] . html::tag('pre', array(),
+ rcmail_plain_body(Q($MESSAGE->body, 'strict', false))));
+ }
+ }
+
+ // list images after mail body
+ if ($RCMAIL->config->get('inline_images', true) && !empty($MESSAGE->attachments)) {
+ $thumbnail_size = $RCMAIL->config->get('image_thumbnail_size', 240);
+ $client_mimetypes = (array)$RCMAIL->config->get('client_mimetypes');
+
+ foreach ($MESSAGE->attachments as $attach_prop) {
+ // skip inline images
+ if ($attach_prop->content_id && $attach_prop->disposition == 'inline') {
+ continue;
+ }
+
+ // Content-Type: image/*...
+ if ($mimetype = rcmail_part_image_type($attach_prop)) {
+ // display thumbnails
+ if ($thumbnail_size) {
+ $show_link = array(
+ 'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false),
+ 'onclick' => sprintf(
+ 'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)',
+ JS_OBJECT_NAME,
+ $attach_prop->mime_id,
+ $mimetype)
+ );
+ $out .= html::p('image-attachment',
+ html::a($show_link + array('class' => 'image-link', 'style' => sprintf('width:%dpx', $thumbnail_size)),
+ html::img(array(
+ 'class' => 'image-thumbnail',
+ 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, true) . '&_thumb=1',
+ 'title' => $attach_prop->filename,
+ 'alt' => $attach_prop->filename,
+ 'style' => sprintf('max-width:%dpx; max-height:%dpx', $thumbnail_size, $thumbnail_size),
+ ))
+ ) .
+ html::span('image-filename', Q($attach_prop->filename)) .
+ html::span('image-filesize', Q($RCMAIL->message_part_size($attach_prop))) .
+ html::span('attachment-links',
+ (in_array($mimetype, $client_mimetypes) ? html::a($show_link, rcube_label('showattachment')) . '&nbsp;' : '') .
+ html::a($show_link['href'] . '&_download=1', rcube_label('download'))
+ ) .
+ html::br(array('style' => 'clear:both'))
+ );
+ }
+ else {
+ $out .= html::tag('fieldset', 'image-attachment',
+ html::tag('legend', 'image-filename', Q($attach_prop->filename)) .
+ html::p(array('align' => "center"),
+ html::img(array(
+ 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, true),
+ 'title' => $attach_prop->filename,
+ 'alt' => $attach_prop->filename,
+ )))
+ );
+ }
+ }
+ }
+ }
+
+ // tell client that there are blocked remote objects
+ if ($REMOTE_OBJECTS && !$safe_mode)
+ $OUTPUT->set_env('blockedobjects', true);
+
+ return html::div($attrib, $out);
+}
+
+function rcmail_part_image_type($part)
+{
+ $rcmail = rcmail::get_instance();
+
+ // Skip TIFF images if browser doesn't support this format...
+ $tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']);
+ // until we can convert them to JPEG
+ $tiff_support = $tiff_support || $rcmail->config->get('im_convert_path');
+
+ // Content-type regexp
+ $mime_regex = $tiff_support ? '/^image\//i' : '/^image\/(?!tif)/i';
+
+ // Content-Type: image/*...
+ if (preg_match($mime_regex, $part->mimetype)) {
+ return rcmail_fix_mimetype($part->mimetype);
+ }
+
+ // Many clients use application/octet-stream, we'll detect mimetype
+ // by checking filename extension
+
+ // Supported image filename extensions to image type map
+ $types = array(
+ 'jpg' => 'image/jpeg',
+ 'jpeg' => 'image/jpeg',
+ 'png' => 'image/png',
+ 'gif' => 'image/gif',
+ 'bmp' => 'image/bmp',
+ );
+ if ($tiff_support) {
+ $types['tif'] = 'image/tiff';
+ $types['tiff'] = 'image/tiff';
+ }
+
+ if ($part->filename
+ && preg_match('/^application\/octet-stream$/i', $part->mimetype)
+ && preg_match('/\.([^.]+)$/i', $part->filename, $m)
+ && ($extension = strtolower($m[1]))
+ && isset($types[$extension])
+ ) {
+ return $types[$extension];
+ }
+}
+
+
+/**
+ * modify a HTML message that it can be displayed inside a HTML page
+ */
+function rcmail_html4inline($body, $container_id, $body_id='', &$attributes=null, $allow_remote=false)
+{
+ $last_style_pos = 0;
+ $cont_id = $container_id.($body_id ? ' div.'.$body_id : '');
+
+ // find STYLE tags
+ while (($pos = stripos($body, '<style', $last_style_pos)) && ($pos2 = stripos($body, '</style>', $pos)))
+ {
+ $pos = strpos($body, '>', $pos) + 1;
+ $len = $pos2 - $pos;
+
+ // replace all css definitions with #container [def]
+ $styles = substr($body, $pos, $len);
+ $styles = rcmail_mod_css_styles($styles, $cont_id, $allow_remote);
+
+ $body = substr_replace($body, $styles, $pos, $len);
+ $last_style_pos = $pos2 + strlen($styles) - $len;
+ }
+
+ // modify HTML links to open a new window if clicked
+ $GLOBALS['rcmail_html_container_id'] = $container_id;
+ $body = preg_replace_callback('/<(a|link|area)\s+([^>]+)>/Ui', 'rcmail_alter_html_link', $body);
+ unset($GLOBALS['rcmail_html_container_id']);
+
+ $body = preg_replace(array(
+ // add comments arround html and other tags
+ '/(<!DOCTYPE[^>]*>)/i',
+ '/(<\?xml[^>]*>)/i',
+ '/(<\/?html[^>]*>)/i',
+ '/(<\/?head[^>]*>)/i',
+ '/(<title[^>]*>.*<\/title>)/Ui',
+ '/(<\/?meta[^>]*>)/i',
+ // quote <? of php and xml files that are specified as text/html
+ '/<\?/',
+ '/\?>/',
+ // replace <body> with <div>
+ '/<body([^>]*)>/i',
+ '/<\/body>/i',
+ ),
+ array(
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '&lt;?',
+ '?&gt;',
+ '<div class="'.$body_id.'"\\1>',
+ '</div>',
+ ),
+ $body);
+
+ $attributes = array();
+
+ // Handle body attributes that doesn't play nicely with div elements
+ $regexp = '/<div class="' . preg_quote($body_id, '/') . '"([^>]*)/';
+ if (preg_match($regexp, $body, $m)) {
+ $attrs = $m[0];
+ // Get bgcolor, we'll set it as background-color of the message container
+ if ($m[1] && preg_match('/bgcolor=["\']*([a-z0-9#]+)["\']*/', $attrs, $mb)) {
+ $attributes['background-color'] = $mb[1];
+ $attrs = preg_replace('/bgcolor=["\']*([a-z0-9#]+)["\']*/', '', $attrs);
+ }
+ // Get background, we'll set it as background-image of the message container
+ if ($m[1] && preg_match('/background=["\']*([^"\'>\s]+)["\']*/', $attrs, $mb)) {
+ $attributes['background-image'] = 'url('.$mb[1].')';
+ $attrs = preg_replace('/background=["\']*([^"\'>\s]+)["\']*/', '', $attrs);
+ }
+ if (!empty($attributes)) {
+ $body = preg_replace($regexp, rtrim($attrs), $body, 1);
+ }
+
+ // handle body styles related to background image
+ if ($attributes['background-image']) {
+ // get body style
+ if (preg_match('/#'.preg_quote($cont_id, '/').'\s+\{([^}]+)}/i', $body, $m)) {
+ // get background related style
+ if (preg_match_all('/(background-position|background-repeat)\s*:\s*([^;]+);/i', $m[1], $ma, PREG_SET_ORDER)) {
+ foreach ($ma as $style)
+ $attributes[$style[1]] = $style[2];
+ }
+ }
+ }
+ }
+ // make sure there's 'rcmBody' div, we need it for proper css modification
+ // its name is hardcoded in rcmail_message_body() also
+ else {
+ $body = '<div class="' . $body_id . '">' . $body . '</div>';
+ }
+
+ return $body;
+}
+
+
+/**
+ * parse link attributes and set correct target
+ */
+function rcmail_alter_html_link($matches)
+{
+ global $RCMAIL;
+
+ // Support unicode/punycode in top-level domain part
+ $EMAIL_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[^&@"\'.][^@&"\']*\\.([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,}))';
+
+ $tag = $matches[1];
+ $attrib = parse_attrib_string($matches[2]);
+ $end = '>';
+
+ // Remove non-printable characters in URL (#1487805)
+ if ($attrib['href'])
+ $attrib['href'] = preg_replace('/[\x00-\x1F]/', '', $attrib['href']);
+
+ if ($tag == 'link' && preg_match('/^https?:\/\//i', $attrib['href'])) {
+ $tempurl = 'tmp-' . md5($attrib['href']) . '.css';
+ $_SESSION['modcssurls'][$tempurl] = $attrib['href'];
+ $attrib['href'] = $RCMAIL->url(array('task' => 'utils', 'action' => 'modcss', 'u' => $tempurl, 'c' => $GLOBALS['rcmail_html_container_id']));
+ $end = ' />';
+ }
+ else if (preg_match('/^mailto:'.$EMAIL_PATTERN.'(\?[^"\'>]+)?/i', $attrib['href'], $mailto)) {
+ $attrib['href'] = $mailto[0];
+ $attrib['onclick'] = sprintf(
+ "return %s.command('compose','%s',this)",
+ JS_OBJECT_NAME,
+ JQ($mailto[1].$mailto[3]));
+ }
+ else if (empty($attrib['href']) && !$attrib['name']) {
+ $attrib['href'] = './#NOP';
+ $attrib['onclick'] = 'return false';
+ }
+ else if (!empty($attrib['href']) && $attrib['href'][0] != '#') {
+ $attrib['target'] = '_blank';
+ }
+
+ // allowed attributes for a|link|area tags
+ $allow = array('href','name','target','onclick','id','class','style','title',
+ 'rel','type','media','alt','coords','nohref','hreflang','shape');
+
+ return "<$tag" . html::attrib_string($attrib, $allow) . $end;
+}
+
+
+/**
+ * decode address string and re-format it as HTML links
+ */
+function rcmail_address_string($input, $max=null, $linked=false, $addicon=null, $default_charset=null, $title=null)
+{
+ global $RCMAIL, $PRINT_MODE, $CONFIG;
+
+ $a_parts = rcube_mime::decode_address_list($input, null, true, $default_charset);
+
+ if (!sizeof($a_parts))
+ return $input;
+
+ $c = count($a_parts);
+ $j = 0;
+ $out = '';
+ $allvalues = array();
+
+ if ($addicon && !isset($_SESSION['writeable_abook'])) {
+ $_SESSION['writeable_abook'] = $RCMAIL->get_address_sources(true) ? true : false;
+ }
+
+ foreach ($a_parts as $part) {
+ $j++;
+ $name = $part['name'];
+ $mailto = $part['mailto'];
+ $string = $part['string'];
+
+ // IDNA ASCII to Unicode
+ if ($name == $mailto)
+ $name = rcube_idn_to_utf8($name);
+ if ($string == $mailto)
+ $string = rcube_idn_to_utf8($string);
+ $mailto = rcube_idn_to_utf8($mailto);
+
+ if ($PRINT_MODE) {
+ $out .= ($out ? ', ' : '') . sprintf('%s &lt;%s&gt;', Q($name), $mailto);
+ // for printing we display all addresses
+ continue;
+ }
+ else if (check_email($part['mailto'], false)) {
+ if ($linked) {
+ $address = html::a(array(
+ 'href' => 'mailto:'.$mailto,
+ 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($mailto)),
+ 'title' => $mailto,
+ 'class' => "rcmContactAddress",
+ ),
+ Q($name ? $name : $mailto));
+ }
+ else {
+ $address = html::span(array('title' => $mailto, 'class' => "rcmContactAddress"),
+ Q($name ? $name : $mailto));
+ }
+
+ if ($addicon && $_SESSION['writeable_abook']) {
+ $address .= html::a(array(
+ 'href' => "#add",
+ 'onclick' => sprintf("return %s.command('add-contact','%s',this)", JS_OBJECT_NAME, JQ($string)),
+ 'title' => rcube_label('addtoaddressbook'),
+ 'class' => 'rcmaddcontact',
+ ),
+ html::img(array(
+ 'src' => $CONFIG['skin_path'] . $addicon,
+ 'alt' => "Add contact",
+ )));
+ }
+ }
+ else {
+ $address = '';
+ if ($name)
+ $address .= Q($name);
+ if ($mailto)
+ $address .= (strlen($address) ? ' ' : '') . sprintf('&lt;%s&gt;', Q($mailto));
+ }
+
+ $address = html::span('adr', $address);
+ $allvalues[] = $address;
+
+ if (!$moreadrs)
+ $out .= ($out ? ', ' : '') . $address;
+
+ if ($max && $j == $max && $c > $j) {
+ if ($linked) {
+ $moreadrs = $c - $j;
+ }
+ else {
+ $out .= '...';
+ break;
+ }
+ }
+ }
+
+ if ($moreadrs) {
+ $out .= ' ' . html::a(array(
+ 'href' => '#more',
+ 'class' => 'morelink',
+ 'onclick' => sprintf("return %s.show_popup_dialog('%s','%s')",
+ JS_OBJECT_NAME,
+ JQ(join(', ', $allvalues)),
+ JQ($title))
+ ),
+ Q(rcube_label(array('name' => 'andnmore', 'vars' => array('nr' => $moreadrs)))));
+ }
+
+ return $out;
+}
+
+
+/**
+ * Wrap text to a given number of characters per line
+ * but respect the mail quotation of replies messages (>).
+ * Finally add another quotation level by prpending the lines
+ * with >
+ *
+ * @param string Text to wrap
+ * @param int The line width
+ * @return string The wrapped text
+ */
+function rcmail_wrap_and_quote($text, $length = 72)
+{
+ // Rebuild the message body with a maximum of $max chars, while keeping quoted message.
+ $max = max(75, $length + 8);
+ $lines = preg_split('/\r?\n/', trim($text));
+ $out = '';
+
+ foreach ($lines as $line) {
+ // don't wrap already quoted lines
+ if ($line[0] == '>')
+ $line = '>' . rtrim($line);
+ else if (mb_strlen($line) > $max) {
+ $newline = '';
+ foreach(explode("\n", rc_wordwrap($line, $length - 2)) as $l) {
+ if (strlen($l))
+ $newline .= '> ' . $l . "\n";
+ else
+ $newline .= ">\n";
+ }
+ $line = rtrim($newline);
+ }
+ else
+ $line = '> ' . $line;
+
+ // Append the line
+ $out .= $line . "\n";
+ }
+
+ return rtrim($out, "\n");
+}
+
+
+function rcmail_draftinfo_encode($p)
+{
+ $parts = array();
+ foreach ($p as $key => $val)
+ $parts[] = $key . '=' . ($key == 'folder' ? base64_encode($val) : $val);
+
+ return join('; ', $parts);
+}
+
+
+function rcmail_draftinfo_decode($str)
+{
+ $info = array();
+ foreach (preg_split('/;\s+/', $str) as $part) {
+ list($key, $val) = explode('=', $part, 2);
+ if ($key == 'folder')
+ $val = base64_decode($val);
+ $info[$key] = $val;
+ }
+
+ return $info;
+}
+
+
+function rcmail_message_part_controls($attrib)
+{
+ global $MESSAGE, $RCMAIL;
+
+ $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC));
+ if (!is_object($MESSAGE) || !is_array($MESSAGE->parts) || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part])
+ return '';
+
+ $part = $MESSAGE->mime_parts[$part];
+ $table = new html_table(array('cols' => 3));
+
+ $filename = $part->filename;
+ if (empty($filename) && $attach_prop->mimetype == 'text/html') {
+ $filename = rcube_label('htmlmessage');
+ }
+
+ if (!empty($filename)) {
+ $table->add('title', Q(rcube_label('filename')));
+ $table->add('header', Q($filename));
+ $table->add('download-link', html::a(array('href' => './?'.str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING'])), Q(rcube_label('download'))));
+ }
+
+ $table->add('title', Q(rcube_label('filesize')));
+ $table->add('header', Q($RCMAIL->message_part_size($part)));
+
+ return $table->show($attrib);
+}
+
+
+
+function rcmail_message_part_frame($attrib)
+{
+ global $MESSAGE;
+
+ $part = $MESSAGE->mime_parts[asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))];
+ $ctype_primary = strtolower($part->ctype_primary);
+
+ $attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary=='text' ? '_embed=' : '_preload='), $_SERVER['QUERY_STRING']);
+
+ return html::iframe($attrib);
+}
+
+
+/**
+ * clear message composing settings
+ */
+function rcmail_compose_cleanup($id)
+{
+ if (!isset($_SESSION['compose_data_'.$id]))
+ return;
+
+ $rcmail = rcmail::get_instance();
+ $rcmail->plugins->exec_hook('attachments_cleanup', array('group' => $id));
+ $rcmail->session->remove('compose_data_'.$id);
+}
+
+
+/**
+ * Send the MDN response
+ *
+ * @param mixed $message Original message object (rcube_message) or UID
+ * @param array $smtp_error SMTP error array (reference)
+ *
+ * @return boolean Send status
+ */
+function rcmail_send_mdn($message, &$smtp_error)
+{
+ global $RCMAIL;
+
+ if (!is_object($message) || !is_a($message, 'rcube_message'))
+ $message = new rcube_message($message);
+
+ if ($message->headers->mdn_to && empty($message->headers->flags['MDNSENT']) &&
+ ($RCMAIL->storage->check_permflag('MDNSENT') || $RCMAIL->storage->check_permflag('*')))
+ {
+ $identity = rcmail_identity_select($message);
+ $sender = format_email_recipient($identity['email'], $identity['name']);
+ $recipient = array_shift(rcube_mime::decode_address_list(
+ $message->headers->mdn_to, 1, true, $message->headers->charset));
+ $mailto = $recipient['mailto'];
+
+ $compose = new Mail_mime("\r\n");
+
+ $compose->setParam('text_encoding', 'quoted-printable');
+ $compose->setParam('html_encoding', 'quoted-printable');
+ $compose->setParam('head_encoding', 'quoted-printable');
+ $compose->setParam('head_charset', RCMAIL_CHARSET);
+ $compose->setParam('html_charset', RCMAIL_CHARSET);
+ $compose->setParam('text_charset', RCMAIL_CHARSET);
+
+ // compose headers array
+ $headers = array(
+ 'Date' => rcmail_user_date(),
+ 'From' => $sender,
+ 'To' => $message->headers->mdn_to,
+ 'Subject' => rcube_label('receiptread') . ': ' . $message->subject,
+ 'Message-ID' => rcmail_gen_message_id(),
+ 'X-Sender' => $identity['email'],
+ 'References' => trim($message->headers->references . ' ' . $message->headers->messageID),
+ );
+
+ if ($agent = $RCMAIL->config->get('useragent'))
+ $headers['User-Agent'] = $agent;
+
+ $body = rcube_label("yourmessage") . "\r\n\r\n" .
+ "\t" . rcube_label("to") . ': ' . rcube_mime::decode_mime_string($message->headers->to, $message->headers->charset) . "\r\n" .
+ "\t" . rcube_label("subject") . ': ' . $message->subject . "\r\n" .
+ "\t" . rcube_label("sent") . ': ' . format_date($message->headers->date, $RCMAIL->config->get('date_long')) . "\r\n" .
+ "\r\n" . rcube_label("receiptnote") . "\r\n";
+
+ $ua = $RCMAIL->config->get('useragent', "Roundcube Webmail (Version ".RCMAIL_VERSION.")");
+ $report = "Reporting-UA: $ua\r\n";
+
+ if ($message->headers->to)
+ $report .= "Original-Recipient: {$message->headers->to}\r\n";
+
+ $report .= "Final-Recipient: rfc822; {$identity['email']}\r\n" .
+ "Original-Message-ID: {$message->headers->messageID}\r\n" .
+ "Disposition: manual-action/MDN-sent-manually; displayed\r\n";
+
+ $compose->headers($headers);
+ $compose->setContentType('multipart/report', array('report-type'=> 'disposition-notification'));
+ $compose->setTXTBody(rc_wordwrap($body, 75, "\r\n"));
+ $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline');
+
+ $sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file);
+
+ if ($sent)
+ {
+ $RCMAIL->storage->set_flag($message->uid, 'MDNSENT');
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Detect recipient identity from specified message
+ */
+function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'reply')
+{
+ $a_recipients = array();
+ $a_names = array();
+
+ if ($identities === null) {
+ $identities = rcmail::get_instance()->user->list_identities(null, true);
+ }
+
+ // extract all recipients of the reply-message
+ if (is_object($MESSAGE->headers) && in_array($compose_mode, array('reply', 'forward'))) {
+ $a_to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, true, $MESSAGE->headers->charset);
+ foreach ($a_to as $addr) {
+ if (!empty($addr['mailto'])) {
+ $a_recipients[] = format_email($addr['mailto']);
+ $a_names[] = $addr['name'];
+ }
+ }
+
+ if (!empty($MESSAGE->headers->cc)) {
+ $a_cc = rcube_mime::decode_address_list($MESSAGE->headers->cc, null, true, $MESSAGE->headers->charset);
+ foreach ($a_cc as $addr) {
+ if (!empty($addr['mailto'])) {
+ $a_recipients[] = format_email($addr['mailto']);
+ $a_names[] = $addr['name'];
+ }
+ }
+ }
+ }
+
+ $from_idx = null;
+ $found_idx = null;
+ $default_identity = 0; // default identity is always first on the list
+
+ // Select identity
+ foreach ($identities as $idx => $ident) {
+ // use From header
+ if (in_array($compose_mode, array('draft', 'edit'))) {
+ if ($MESSAGE->headers->from == $ident['ident']) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ // reply to yourself
+ else if ($compose_mode == 'reply' && $MESSAGE->headers->from == $ident['ident']) {
+ $from_idx = $idx;
+ break;
+ }
+ // use replied message recipients
+ else if (($found = array_search($ident['email_ascii'], $a_recipients)) !== false) {
+ if ($found_idx === null) {
+ $found_idx = $idx;
+ }
+ // match identity name
+ if ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name']) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
+
+ // If matching by name+address doesn't found any matches, get first found address (identity)
+ if ($from_idx === null) {
+ $from_idx = $found_idx;
+ }
+
+ // Try Return-Path
+ if ($from_idx === null && ($return_path = $MESSAGE->headers->others['return-path'])) {
+ foreach ($identities as $idx => $ident) {
+ if (strpos($return_path, str_replace('@', '=', $ident['email_ascii']).'@') !== false) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
+
+ // Fallback using Delivered-To
+ if ($from_idx === null && ($delivered_to = $MESSAGE->headers->others['delivered-to'])) {
+ foreach ($identities as $idx => $ident) {
+ if (in_array($ident['email_ascii'], (array)$delivered_to)) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
+
+ // Fallback using Envelope-To
+ if ($from_idx === null && ($envelope_to = $MESSAGE->headers->others['envelope-to'])) {
+ foreach ($identities as $idx => $ident) {
+ if (in_array($ident['email_ascii'], (array)$envelope_to)) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
+
+ return $identities[$from_idx !== null ? $from_idx : $default_identity];
+}
+
+// Fixes some content-type names
+function rcmail_fix_mimetype($name)
+{
+ // Some versions of Outlook create garbage Content-Type:
+ // application/pdf.A520491B_3BF7_494D_8855_7FAC2C6C0608
+ if (preg_match('/^application\/pdf.+/', $name))
+ $name = 'application/pdf';
+
+ // treat image/pjpeg as image/jpeg
+ else if (preg_match('/^image\/p?jpe?g$/', $name))
+ $name = 'image/jpeg';
+
+ return $name;
+}
+
+<<<<<<< HEAD
+// return attachment filename, handle empty filename case
+function rcmail_attachment_name($attachment, $display = false)
+{
+ $filename = $attachment->filename;
+
+ if ($filename === null || $filename === '') {
+ if ($attachment->mimetype == 'text/html') {
+ $filename = rcube_label('htmlmessage');
+ }
+ else {
+ $ext = rcube_mime::get_mime_extensions($attachment->mimetype);
+ $ext = array_shift($ext);
+ $filename = rcube_label('messagepart') . ' ' . $attachment->mime_id;
+ if ($ext) {
+ $filename .= '.' . $ext;
+ }
+ }
+ }
+
+ $filename = preg_replace('[\r\n]', '', $filename);
+
+ // Display smart names for some known mimetypes
+ if ($display) {
+ if (preg_match('/application\/(pgp|pkcs7)-signature/i', $attachment->mimetype)) {
+ $filename = rcube_label('digitalsig');
+ }
+ }
+
+ return $filename;
+}
+
+=======
+>>>>>>> parent of be72fb3... Unified attachments filenames handling for message parts without a filename
+function rcmail_search_filter($attrib)
+{
+ global $OUTPUT, $CONFIG;
+
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmlistfilter';
+
+ $attrib['onchange'] = JS_OBJECT_NAME.'.filter_mailbox(this.value)';
+
+ /*
+ RFC3501 (6.4.4): 'ALL', 'RECENT',
+ 'ANSWERED', 'DELETED', 'FLAGGED', 'SEEN',
+ 'UNANSWERED', 'UNDELETED', 'UNFLAGGED', 'UNSEEN',
+ 'NEW', // = (RECENT UNSEEN)
+ 'OLD' // = NOT RECENT
+ */
+
+ $select_filter = new html_select($attrib);
+ $select_filter->add(rcube_label('all'), 'ALL');
+ $select_filter->add(rcube_label('unread'), 'UNSEEN');
+ $select_filter->add(rcube_label('flagged'), 'FLAGGED');
+ $select_filter->add(rcube_label('unanswered'), 'UNANSWERED');
+ if (!$CONFIG['skip_deleted']) {
+ $select_filter->add(rcube_label('deleted'), 'DELETED');
+ $select_filter->add(rcube_label('undeleted'), 'UNDELETED');
+ }
+ $select_filter->add(rcube_label('priority').': '.rcube_label('highest'), 'HEADER X-PRIORITY 1');
+ $select_filter->add(rcube_label('priority').': '.rcube_label('high'), 'HEADER X-PRIORITY 2');
+ $select_filter->add(rcube_label('priority').': '.rcube_label('normal'), 'NOT HEADER X-PRIORITY 1 NOT HEADER X-PRIORITY 2 NOT HEADER X-PRIORITY 4 NOT HEADER X-PRIORITY 5');
+ $select_filter->add(rcube_label('priority').': '.rcube_label('low'), 'HEADER X-PRIORITY 4');
+ $select_filter->add(rcube_label('priority').': '.rcube_label('lowest'), 'HEADER X-PRIORITY 5');
+
+ $out = $select_filter->show($_SESSION['search_filter']);
+
+ $OUTPUT->add_gui_object('search_filter', $attrib['id']);
+
+ return $out;
+}
+
+function rcmail_message_error($uid=null)
+{
+ global $RCMAIL;
+
+ // Set env variables for messageerror.html template
+ if ($RCMAIL->action == 'show') {
+ $mbox_name = $RCMAIL->storage->get_folder();
+ $RCMAIL->output->set_env('mailbox', $mbox_name);
+ $RCMAIL->output->set_env('uid', null);
+ }
+ // display error message
+ $RCMAIL->output->show_message('messageopenerror', 'error');
+ // ... display message error page
+ $RCMAIL->output->send('messageerror');
+}
+
+// register UI objects
+$OUTPUT->add_handlers(array(
+ 'mailboxlist' => 'rcmail_mailbox_list',
+ 'messages' => 'rcmail_message_list',
+ 'messagecountdisplay' => 'rcmail_messagecount_display',
+ 'quotadisplay' => 'rcmail_quota_display',
+ 'mailboxname' => 'rcmail_mailbox_name_display',
+ 'messageheaders' => 'rcmail_message_headers',
+ 'messagefullheaders' => 'rcmail_message_full_headers',
+ 'messagebody' => 'rcmail_message_body',
+ 'messagecontentframe' => 'rcmail_messagecontent_frame',
+ 'messagepartframe' => 'rcmail_message_part_frame',
+ 'messagepartcontrols' => 'rcmail_message_part_controls',
+ 'searchfilter' => 'rcmail_search_filter',
+ 'searchform' => array($OUTPUT, 'search_form'),
+));
+
+// register action aliases
+$RCMAIL->register_action_map(array(
+ 'refresh' => 'check_recent.inc',
+ 'preview' => 'show.inc',
+ 'print' => 'show.inc',
+ 'moveto' => 'move_del.inc',
+ 'delete' => 'move_del.inc',
+ 'send' => 'sendmail.inc',
+ 'expunge' => 'folders.inc',
+ 'purge' => 'folders.inc',
+ 'remove-attachment' => 'attachments.inc',
+ 'display-attachment' => 'attachments.inc',
+ 'upload' => 'attachments.inc',
+ 'group-expand' => 'autocomplete.inc',
+));
diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc
index e0c4e2911..372757720 100644
--- a/program/steps/mail/get.inc
+++ b/program/steps/mail/get.inc
@@ -38,34 +38,19 @@ ob_end_clean();
// similar code as in program/steps/mail/show.inc
if (!empty($_GET['_uid'])) {
- $uid = get_input_value('_uid', RCUBE_INPUT_GET);
$RCMAIL->config->set('prefer_html', true);
- $MESSAGE = new rcube_message($uid);
+ $MESSAGE = new rcube_message(get_input_value('_uid', RCUBE_INPUT_GET));
}
// check connection status
check_storage_status();
-$part_id = get_input_value('_part', RCUBE_INPUT_GPC);
-
// show part page
if (!empty($_GET['_frame'])) {
- if ($part_id && ($part = $MESSAGE->mime_parts[$part_id])) {
- $filename = rcmail_attachment_name($part);
- $OUTPUT->set_pagetitle($filename);
+ if (($part_id = get_input_value('_part', RCUBE_INPUT_GPC)) && ($part = $MESSAGE->mime_parts[$part_id])) {
+ $OUTPUT->set_pagetitle(rcmail_attachment_name($part));
}
- // register UI objects
- $OUTPUT->add_handlers(array(
- 'messagepartframe' => 'rcmail_message_part_frame',
- 'messagepartcontrols' => 'rcmail_message_part_controls',
- ));
-
- $OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder());
- $OUTPUT->set_env('uid', $uid);
- $OUTPUT->set_env('part', $part_id);
- $OUTPUT->set_env('filename', $filename);
-
$OUTPUT->send('messagepart');
exit;
}
@@ -107,8 +92,9 @@ else if ($_GET['_thumb']) {
exit;
}
-else if (strlen($part_id)) {
- if ($part = $MESSAGE->mime_parts[$part_id]) {
+else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
+
+ if ($part = $MESSAGE->mime_parts[$pid]) {
$mimetype = rcmail_fix_mimetype($part->mimetype);
// allow post-processing of the message body
@@ -134,7 +120,7 @@ else if (strlen($part_id)) {
$valid = $file_extension && in_array($file_extension, (array)$extensions) || !empty($_REQUEST['_mimeclass']);
// 2. detect the real mimetype of the attachment part and compare it with the stated mimetype and filename extension
- if ($valid || !$file_extension || $mimetype == 'application/octet-stream' || stripos($mimetype, 'text/') === 0) {
+ if ($valid || !$file_extension || $mimetype == 'application/octet-stream' || $mimetype == 'text/plain') {
if ($part->body) // part body is already loaded
$body = $part->body;
else if ($part->size && $part->size < 1024*1024) // load the entire part if it's small enough
@@ -189,8 +175,8 @@ else if (strlen($part_id)) {
rcube_label(array(
'name' => 'attachmentvalidationerror',
'vars' => array(
- 'expected' => $mimetype . ($file_extension ? " (.$file_extension)" : ''),
- 'detected' => $real_mimetype . ($extensions[0] ? " (.$extensions[0])" : ''),
+ 'expected' => $mimetype . ($file_extension ? "(.$file_extension)" : ''),
+ 'detected' => $real_mimetype . ($extensions[0] ? "(.$extensions[0])" : ''),
)
)) .
html::p(array('class' => 'rcmail-inline-buttons'),
@@ -233,6 +219,7 @@ else if (strlen($part_id)) {
header("Content-Transfer-Encoding: binary");
}
+
// deliver part content
if ($ctype_primary == 'text' && $ctype_secondary == 'html' && empty($plugin['download'])) {
// Check if we have enough memory to handle the message in it
@@ -357,8 +344,7 @@ else if (strlen($part_id)) {
header("Content-Length: $size");
}
- // 8th argument disables re-formatting of text/* parts (#1489267)
- $sent = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, true, null, false, 0, false);
+ $sent = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, true);
}
}
@@ -392,9 +378,7 @@ else {
header('HTTP/1.1 404 Not Found');
exit;
-/**
- * Handles nicely storage connection errors
- */
+
function check_storage_status()
{
$error = rcmail::get_instance()->storage->get_error_code();
@@ -426,49 +410,3 @@ function check_storage_status()
exit;
}
}
-
-/**
- * Attachment properties table
- */
-function rcmail_message_part_controls($attrib)
-{
- global $MESSAGE, $RCMAIL;
-
- $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC));
- if (!is_object($MESSAGE) || !is_array($MESSAGE->parts)
- || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part]
- ) {
- return '';
- }
-
- $part = $MESSAGE->mime_parts[$part];
- $table = new html_table(array('cols' => 2));
-
- $table->add('title', Q(rcube_label('namex')).':');
- $table->add('header', Q(rcmail_attachment_name($part)));
-
- $table->add('title', Q(rcube_label('type')).':');
- $table->add('header', Q($part->mimetype));
-
- $table->add('title', Q(rcube_label('size')).':');
- $table->add('header', Q($RCMAIL->message_part_size($part)));
-
- return $table->show($attrib);
-}
-
-/**
- * Attachment preview frame
- */
-function rcmail_message_part_frame($attrib)
-{
- global $MESSAGE, $RCMAIL;
-
- $part = $MESSAGE->mime_parts[asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))];
- $ctype_primary = strtolower($part->ctype_primary);
-
- $attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary=='text' ? '_embed=' : '_preload='), $_SERVER['QUERY_STRING']);
-
- $RCMAIL->output->add_gui_object('messagepartframe', $attrib['id']);
-
- return html::iframe($attrib);
-}
diff --git a/program/steps/mail/list.inc b/program/steps/mail/list.inc
index a2380131a..b8c3ee021 100644
--- a/program/steps/mail/list.inc
+++ b/program/steps/mail/list.inc
@@ -97,6 +97,7 @@ $OUTPUT->set_env('threading', $threading);
$OUTPUT->set_env('current_page', $count ? $RCMAIL->storage->get_page() : 1);
$OUTPUT->set_env('exists', $RCMAIL->storage->count($mbox_name, 'EXISTS'));
$OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($count), $mbox_name);
+$OUTPUT->command('set_mailboxname', rcmail_get_mailbox_name_text());
// add message rows
rcmail_js_message_list($a_headers, FALSE, $cols);
diff --git a/program/steps/mail/list_contacts.inc b/program/steps/mail/list_contacts.inc
index dab146431..479c21422 100644
--- a/program/steps/mail/list_contacts.inc
+++ b/program/steps/mail/list_contacts.inc
@@ -73,11 +73,8 @@ else {
$CONTACTS->set_pagesize($page_size);
$CONTACTS->set_page($list_page);
- if ($group_id = get_input_value('_gid', RCUBE_INPUT_GPC)) {
- $CONTACTS->set_group($group_id);
- }
// list groups of this source (on page one)
- else if ($CONTACTS->groups && $CONTACTS->list_page == 1) {
+ if ($CONTACTS->groups && $CONTACTS->list_page == 1) {
foreach ($CONTACTS->list_groups() as $group) {
$CONTACTS->reset();
$CONTACTS->set_group($group['ID']);
@@ -92,19 +89,6 @@ else {
'contactgroup' => html::span(array('title' => $email), Q($group['name']))), 'group');
}
}
- // make virtual groups clickable to list their members
- else if ($group_prop['virtual']) {
- $row_id = 'G'.$group['ID'];
- $OUTPUT->command('add_contact_row', $row_id, array(
- 'contactgroup' => html::a(array(
- 'href' => '#list',
- 'rel' => $row['ID'],
- 'title' => rcube_label('listgroup'),
- 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", JS_OBJECT_NAME, $source, $group['ID']),
- ), Q($group['name']) . '&nbsp;' . html::span('action', '&raquo;'))),
- 'group',
- array('ID' => $group['ID'], 'name' => $group['name'], 'virtual' => true));
- }
// show group with count
else if (($result = $CONTACTS->count()) && $result->count) {
$row_id = 'E'.$group['ID'];
@@ -113,12 +97,10 @@ else {
'contactgroup' => Q($group['name'] . ' (' . intval($result->count) . ')')), 'group');
}
}
-
- $CONTACTS->reset();
- $CONTACTS->set_group(0);
}
// get contacts for this user
+ $CONTACTS->set_group(0);
$result = $CONTACTS->list_records($afields);
}
}
@@ -136,13 +118,10 @@ else if (!empty($result) && $result->count > 0) {
foreach ($emails as $i => $email) {
$row_id = $row['ID'].$i;
$jsresult[$row_id] = format_email_recipient($email, $name);
- $classname = $row['_type'] == 'group' ? 'group' : 'person';
- $keyname = $row['_type'] == 'group' ? 'contactgroup' : 'contact';
-
$OUTPUT->command('add_contact_row', $row_id, array(
- $keyname => html::span(array('title' => $email), Q($name ? $name : $email) .
+ 'contact' => html::span(array('title' => $email), Q($name ? $name : $email) .
($name && count($emails) > 1 ? '&nbsp;' . html::span('email', Q($email)) : '')
- )), $classname);
+ )), 'person');
}
}
}
diff --git a/program/steps/mail/move_del.inc b/program/steps/mail/move_del.inc
index f15cd2460..37157b71f 100644
--- a/program/steps/mail/move_del.inc
+++ b/program/steps/mail/move_del.inc
@@ -29,11 +29,10 @@ $old_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL');
$old_pages = ceil($old_count / $RCMAIL->storage->get_pagesize());
// move messages
-if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
- $count = sizeof(explode(',', ($uids = get_input_value('_uid', RCUBE_INPUT_POST))));
+if ($RCMAIL->action=='moveto' && !empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
+ $count = sizeof(explode(',', ($uids = get_input_value('_uid', RCUBE_INPUT_POST))));
$target = get_input_value('_target_mbox', RCUBE_INPUT_POST, true);
- $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true);
- $trash = $RCMAIL->config->get('trash_mbox');
+ $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true);
$moved = $RCMAIL->storage->move_message($uids, $target, $mbox);
@@ -41,7 +40,7 @@ if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_targe
// send error message
if ($_POST['_from'] != 'show')
$OUTPUT->command('list_mailbox');
- rcmail_display_server_error('errormoving', null, $target == $trash ? 'delete' : '');
+ rcmail_display_server_error('errormoving');
$OUTPUT->send();
exit;
}
@@ -126,7 +125,7 @@ else
rcmail_set_unseen_count($mbox, $unseen_count);
}
- if ($RCMAIL->action == 'move' && strlen($target)) {
+ if ($RCMAIL->action == 'moveto' && strlen($target)) {
rcmail_send_unread_count($target, true);
}
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 779fb87cd..c1c257127 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -123,7 +123,7 @@ function rcmail_fix_emoticon_paths($mime_message)
// sanitize image name so resulting attachment doesn't leave images dir
$image_name = preg_replace('/[^a-zA-Z0-9_\.\-]/i', '', $image_name);
- $img_file = INSTALL_PATH . '/' . $searchstr . $image_name;
+ $img_file = '/usr/share/tinymce/www/plugins/emotions/img/' . $image_name;
if (! in_array($image_name, $included_images)) {
// add the image to the MIME message
@@ -391,6 +391,10 @@ if (!empty($mailcc)) {
if (!empty($mailbcc)) {
$headers['Bcc'] = $mailbcc;
}
+if (!empty($identity_arr['bcc']) && stripos($headers['Bcc'], $identity_arr['bcc']) === false) {
+ $headers['Bcc'] = ($headers['Bcc'] ? $headers['Bcc'].', ' : '') . $identity_arr['bcc'];
+ $RECIPIENT_COUNT ++;
+}
if (($max_recipients = (int) $RCMAIL->config->get('max_recipients')) > 0) {
if ($RECIPIENT_COUNT > $max_recipients) {
@@ -408,6 +412,9 @@ if (!empty($identity_arr['organization'])) {
if (!empty($_POST['_replyto'])) {
$headers['Reply-To'] = rcmail_email_input_format(get_input_value('_replyto', RCUBE_INPUT_POST, TRUE, $message_charset));
}
+else if (!empty($identity_arr['reply-to'])) {
+ $headers['Reply-To'] = rcmail_email_input_format($identity_arr['reply-to'], false, true);
+}
if (!empty($headers['Reply-To'])) {
$headers['Mail-Reply-To'] = $headers['Reply-To'];
}
@@ -823,24 +830,15 @@ if ($savedraft) {
// start the auto-save timer again
$OUTPUT->command('auto_save_start');
+
+ $OUTPUT->send('iframe');
}
else {
- $folders = array();
-
- if ($COMPOSE['mode'] == 'reply' || $COMPOSE['mode'] == 'forward')
- $folders[] = $COMPOSE['mailbox'];
-
rcmail_compose_cleanup($COMPOSE_ID);
if ($store_folder && !$saved)
- $OUTPUT->command('sent_successfully', 'error', rcube_label('errorsavingsent'), $folders);
- else {
- if ($store_folder) {
- $folders[] = $store_target;
- }
-
- $OUTPUT->command('sent_successfully', 'confirmation', rcube_label('messagesent'), $folders);
- }
+ $OUTPUT->command('sent_successfully', 'error', rcube_label('errorsavingsent'));
+ else
+ $OUTPUT->command('sent_successfully', 'confirmation', rcube_label('messagesent'), $store_target);
+ $OUTPUT->send('iframe');
}
-
-$OUTPUT->send('iframe');
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index 59f4d55e1..c1726bbdf 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -19,7 +19,7 @@
+-----------------------------------------------------------------------+
*/
-$PRINT_MODE = $RCMAIL->action == 'print' ? TRUE : FALSE;
+$PRINT_MODE = $RCMAIL->action=='print' ? TRUE : FALSE;
// Read browser capabilities and store them in session
if ($caps = get_input_value('_caps', RCUBE_INPUT_GET)) {
@@ -31,21 +31,8 @@ if ($caps = get_input_value('_caps', RCUBE_INPUT_GET)) {
$_SESSION['browser_caps'] = $browser_caps;
}
-$uid = get_input_value('_uid', RCUBE_INPUT_GET);
-$mbox_name = $RCMAIL->storage->get_folder();
-
// similar code as in program/steps/mail/get.inc
-if ($uid) {
- // set message format (need to be done before rcube_message construction)
- if (!empty($_GET['_format'])) {
- $prefer_html = $_GET['_format'] == 'html';
- $RCMAIL->config->set('prefer_html', $prefer_html);
- $_SESSION['msg_formats'][$mbox_name.':'.$uid] = $prefer_html;
- }
- else if (isset($_SESSION['msg_formats'][$mbox_name.':'.$uid])) {
- $RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$uid]);
- }
-
+if ($uid = get_input_value('_uid', RCUBE_INPUT_GET)) {
$MESSAGE = new rcube_message($uid);
// if message not found (wrong UID)...
@@ -53,6 +40,7 @@ if ($uid) {
rcmail_message_error($uid);
}
+ $mbox_name = $RCMAIL->storage->get_folder();
// show images?
rcmail_check_safe($MESSAGE);
@@ -116,12 +104,7 @@ if ($uid) {
if (!$OUTPUT->ajax_call)
$OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
- 'movingmessage', 'deletingmessage', 'markingmessage', 'replyall', 'replylist');
-
- $prefer_html = $RCMAIL->config->get('prefer_html');
- if ($MESSAGE->has_html_part()) {
- $OUTPUT->set_env('optional_format', $prefer_html ? 'text' : 'html');
- }
+ 'movingmessage', 'deletingmessage', 'markingmessage');
// check for unset disposition notification
if ($MESSAGE->headers->mdn_to
@@ -164,7 +147,6 @@ function rcmail_message_attachments($attrib)
global $PRINT_MODE, $MESSAGE, $RCMAIL;
$out = $ol = '';
- $attachments = array();
if (sizeof($MESSAGE->attachments)) {
foreach ($MESSAGE->attachments as $attach_prop) {
@@ -175,31 +157,30 @@ function rcmail_message_attachments($attrib)
$ol .= html::tag('li', null, Q(sprintf("%s (%s)", $filename, $size)));
}
else {
- if (mb_strlen($filename) > 50) {
+ if ($attrib['maxlength'] && mb_strlen($filename) > $attrib['maxlength']) {
$title = $filename;
- $filename = abbreviate_string($filename, 50);
+ $filename = abbreviate_string($filename, $attrib['maxlength']);
}
else {
$title = '';
}
- $mimetype = rcmail_fix_mimetype($attach_prop->mimetype);
- $class = rcmail_filetype2classname($mimetype, $filename);
- $id = 'attach' . $attach_prop->mime_id;
- $link = html::a(array(
+ $ol .= html::tag('li', rcmail_filetype2classname($attach_prop->mimetype, $filename),
+ html::a(array(
'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false),
- 'onclick' => sprintf('return %s.command(\'load-attachment\',\'%s\',this)',
- JS_OBJECT_NAME, $attach_prop->mime_id),
- 'title' => Q($title),
- ), Q($filename));
- $ol .= html::tag('li', array('class' => $class, 'id' => $id), $link);
-
- $attachments[$attach_prop->mime_id] = $mimetype;
+ 'onclick' => sprintf(
+ 'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)',
+ JS_OBJECT_NAME,
+ $attach_prop->mime_id,
+ rcmail_fix_mimetype($attach_prop->mimetype)),
+ 'onmouseover' => $title ? '' : 'rcube_webmail.long_subject_title_ex(this, 0)',
+ 'title' => Q($title),
+ ),
+ Q($filename)));
}
}
$out = html::tag('ul', $attrib, $ol, html::$common_attrib);
- $RCMAIL->output->set_env('attachments', $attachments);
}
return $out;
@@ -228,11 +209,11 @@ function rcmail_remote_objects_msg()
function rcmail_message_buttons()
{
- global $RCMAIL;
+ global $MESSAGE, $RCMAIL, $CONFIG;
$mbox = $RCMAIL->storage->get_folder();
$delim = $RCMAIL->storage->get_hierarchy_delimiter();
- $dbox = $RCMAIL->config->get('drafts_mbox');
+ $dbox = $CONFIG['drafts_mbox'];
// the message is not a draft
if ($mbox != $dbox && strpos($mbox, $dbox.$delim) !== 0) {
@@ -309,9 +290,9 @@ $OUTPUT->add_handlers(array(
));
-if ($RCMAIL->action == 'print' && $OUTPUT->template_exists('messageprint'))
+if ($RCMAIL->action=='print' && $OUTPUT->template_exists('messageprint'))
$OUTPUT->send('messageprint', false);
-else if ($RCMAIL->action == 'preview' && $OUTPUT->template_exists('messagepreview'))
+else if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messagepreview'))
$OUTPUT->send('messagepreview', false);
else
$OUTPUT->send('message', false);
diff --git a/program/steps/mail/show.inc.orig b/program/steps/mail/show.inc.orig
new file mode 100644
index 000000000..5ca8f66d4
--- /dev/null
+++ b/program/steps/mail/show.inc.orig
@@ -0,0 +1,315 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/mail/show.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2009, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Display a mail message similar as a usual mail application does |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+$PRINT_MODE = $RCMAIL->action=='print' ? TRUE : FALSE;
+
+// Read browser capabilities and store them in session
+if ($caps = get_input_value('_caps', RCUBE_INPUT_GET)) {
+ $browser_caps = array();
+ foreach (explode(',', $caps) as $cap) {
+ $cap = explode('=', $cap);
+ $browser_caps[$cap[0]] = $cap[1];
+ }
+ $_SESSION['browser_caps'] = $browser_caps;
+}
+
+// similar code as in program/steps/mail/get.inc
+if ($uid = get_input_value('_uid', RCUBE_INPUT_GET)) {
+ $MESSAGE = new rcube_message($uid);
+
+ // if message not found (wrong UID)...
+ if (empty($MESSAGE->headers)) {
+ rcmail_message_error($uid);
+ }
+
+ $mbox_name = $RCMAIL->storage->get_folder();
+
+ // show images?
+ rcmail_check_safe($MESSAGE);
+
+ // set message charset as default
+ if (!empty($MESSAGE->headers->charset))
+ $RCMAIL->storage->set_charset($MESSAGE->headers->charset);
+
+ $OUTPUT->set_pagetitle(abbreviate_string($MESSAGE->subject, 128, '...', true));
+
+ // give message uid to the client
+ $OUTPUT->set_env('uid', $MESSAGE->uid);
+ // set environement
+ $OUTPUT->set_env('safemode', $MESSAGE->is_safe);
+ $OUTPUT->set_env('sender', $MESSAGE->sender['string']);
+ $OUTPUT->set_env('permaurl', rcmail_url('show', array('_uid' => $MESSAGE->uid, '_mbox' => $mbox_name)));
+ $OUTPUT->set_env('delimiter', $RCMAIL->storage->get_hierarchy_delimiter());
+ $OUTPUT->set_env('mailbox', $mbox_name);
+ $OUTPUT->set_env('compose_extwin', $RCMAIL->config->get('compose_extwin',false));
+
+ // mimetypes supported by the browser (default settings)
+ $mimetypes = (array)$RCMAIL->config->get('client_mimetypes');
+
+ // Remove unsupported types, which makes that attachment which cannot be
+ // displayed in a browser will be downloaded directly without displaying an overlay page
+ if (empty($_SESSION['browser_caps']['pdf']) && ($key = array_search('application/pdf', $mimetypes)) !== false) {
+ unset($mimetypes[$key]);
+ }
+ if (empty($_SESSION['browser_caps']['flash']) && ($key = array_search('application/x-shockwave-flash', $mimetypes)) !== false) {
+ unset($mimetypes[$key]);
+ }
+ if (empty($_SESSION['browser_caps']['tif']) && ($key = array_search('image/tiff', $mimetypes)) !== false) {
+ // we can convert tiff to jpeg
+ if (!$RCMAIL->config->get('im_convert_path')) {
+ unset($mimetypes[$key]);
+ }
+ }
+
+ $OUTPUT->set_env('mimetypes', $mimetypes);
+
+ if ($CONFIG['drafts_mbox'])
+ $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']);
+ if ($CONFIG['trash_mbox'])
+ $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']);
+ if ($CONFIG['junk_mbox'])
+ $OUTPUT->set_env('junk_mailbox', $CONFIG['junk_mbox']);
+ if ($CONFIG['delete_junk'])
+ $OUTPUT->set_env('delete_junk', true);
+ if ($CONFIG['flag_for_deletion'])
+ $OUTPUT->set_env('flag_for_deletion', true);
+ if ($CONFIG['read_when_deleted'])
+ $OUTPUT->set_env('read_when_deleted', true);
+ if ($CONFIG['skip_deleted'])
+ $OUTPUT->set_env('skip_deleted', true);
+ if ($CONFIG['display_next'])
+ $OUTPUT->set_env('display_next', true);
+ if ($MESSAGE->headers->others['list-post'])
+ $OUTPUT->set_env('list_post', true);
+ if ($CONFIG['forward_attachment'])
+ $OUTPUT->set_env('forward_attachment', true);
+
+ if (!$OUTPUT->ajax_call)
+ $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
+ 'movingmessage', 'deletingmessage', 'markingmessage');
+
+ // check for unset disposition notification
+ if ($MESSAGE->headers->mdn_to
+ && empty($MESSAGE->headers->flags['MDNSENT'])
+ && empty($MESSAGE->headers->flags['SEEN'])
+ && ($RCMAIL->storage->check_permflag('MDNSENT') || $RCMAIL->storage->check_permflag('*'))
+ && $mbox_name != $CONFIG['drafts_mbox']
+ && $mbox_name != $CONFIG['sent_mbox']
+ ) {
+ $mdn_cfg = intval($CONFIG['mdn_requests']);
+
+ if ($mdn_cfg == 1 || (($mdn_cfg == 3 || $mdn_cfg == 4) && rcmail_contact_exists($MESSAGE->sender['mailto']))) {
+ // Send MDN
+ if (rcmail_send_mdn($MESSAGE, $smtp_error))
+ $OUTPUT->show_message('receiptsent', 'confirmation');
+ else if ($smtp_error)
+ $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']);
+ else
+ $OUTPUT->show_message('errorsendingreceipt', 'error');
+ }
+ else if ($mdn_cfg != 2 && $mdn_cfg != 4) {
+ // Ask user
+ $OUTPUT->add_label('mdnrequest');
+ $OUTPUT->set_env('mdn_request', true);
+ }
+ }
+
+ if (empty($MESSAGE->headers->flags['SEEN'])
+ && ($RCMAIL->action == 'show' || ($RCMAIL->action == 'preview' && intval($CONFIG['preview_pane_mark_read']) == 0))
+ ) {
+ $RCMAIL->plugins->exec_hook('message_read', array('uid' => $MESSAGE->uid,
+ 'mailbox' => $mbox_name, 'message' => $MESSAGE));
+ }
+}
+
+
+
+function rcmail_message_attachments($attrib)
+{
+ global $PRINT_MODE, $MESSAGE, $RCMAIL;
+
+ $out = $ol = '';
+
+ if (sizeof($MESSAGE->attachments)) {
+ foreach ($MESSAGE->attachments as $attach_prop) {
+<<<<<<< HEAD
+ $filename = rcmail_attachment_name($attach_prop, true);
+=======
+ $filename = $attach_prop->filename;
+ if (empty($filename) && $attach_prop->mimetype == 'text/html') {
+ $filename = rcube_label('htmlmessage');
+ }
+>>>>>>> parent of be72fb3... Unified attachments filenames handling for message parts without a filename
+
+ if ($PRINT_MODE) {
+ $size = $RCMAIL->message_part_size($attach_prop);
+ $ol .= html::tag('li', null, Q(sprintf("%s (%s)", $filename, $size)));
+ }
+ else {
+ if (mb_strlen($filename) > 50) {
+ $filename = abbreviate_string($filename, 50);
+ $title = $filename;
+ }
+ else {
+ $title = '';
+ }
+
+ $ol .= html::tag('li', rcmail_filetype2classname($attach_prop->mimetype, $filename),
+ html::a(array(
+ 'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false),
+ 'onclick' => sprintf(
+ 'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)',
+ JS_OBJECT_NAME,
+ $attach_prop->mime_id,
+ rcmail_fix_mimetype($attach_prop->mimetype)),
+ 'title' => Q($title),
+ ),
+ Q($filename)));
+ }
+ }
+
+ $out = html::tag('ul', $attrib, $ol, html::$common_attrib);
+ }
+
+ return $out;
+}
+
+function rcmail_remote_objects_msg()
+{
+ global $MESSAGE, $RCMAIL;
+
+ $attrib['id'] = 'remote-objects-message';
+ $attrib['class'] = 'notice';
+ $attrib['style'] = 'display: none';
+
+ $msg = Q(rcube_label('blockedimages')) . '&nbsp;';
+ $msg .= html::a(array('href' => "#loadimages", 'onclick' => JS_OBJECT_NAME.".command('load-images')"), Q(rcube_label('showimages')));
+
+ // add link to save sender in addressbook and reload message
+ if ($MESSAGE->sender['mailto'] && $RCMAIL->config->get('show_images') == 1) {
+ $msg .= ' ' . html::a(array('href' => "#alwaysload", 'onclick' => JS_OBJECT_NAME.".command('always-load')", 'style' => "white-space:nowrap"),
+ Q(rcube_label(array('name' => 'alwaysshow', 'vars' => array('sender' => $MESSAGE->sender['mailto'])))));
+ }
+
+ $RCMAIL->output->add_gui_object('remoteobjectsmsg', $attrib['id']);
+ return html::div($attrib, $msg);
+}
+
+function rcmail_message_buttons()
+{
+ global $MESSAGE, $RCMAIL, $CONFIG;
+
+ $mbox = $RCMAIL->storage->get_folder();
+ $delim = $RCMAIL->storage->get_hierarchy_delimiter();
+ $dbox = $CONFIG['drafts_mbox'];
+
+ // the message is not a draft
+ if ($mbox != $dbox && strpos($mbox, $dbox.$delim) !== 0) {
+ return '';
+ }
+
+ $attrib['id'] = 'message-buttons';
+ $attrib['class'] = 'notice';
+
+ $msg = Q(rcube_label('isdraft')) . '&nbsp;';
+ $msg .= html::a(array('href' => "#edit", 'onclick' => JS_OBJECT_NAME.".command('edit')"), Q(rcube_label('edit')));
+
+ return html::div($attrib, $msg);
+}
+
+function rcmail_message_objects($attrib)
+{
+ global $RCMAIL, $MESSAGE;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'message-objects';
+
+ $content = array(
+ rcmail_message_buttons(),
+ rcmail_remote_objects_msg(),
+ );
+
+ $plugin = $RCMAIL->plugins->exec_hook('message_objects',
+ array('content' => $content, 'message' => $MESSAGE));
+
+ $content = implode("\n", $plugin['content']);
+
+ return html::div($attrib, $content);
+}
+
+function rcmail_contact_exists($email)
+{
+ global $RCMAIL;
+
+ if ($email) {
+ // @TODO: search in all address books?
+ $CONTACTS = $RCMAIL->get_address_book(-1, true);
+ $existing = $CONTACTS->search('email', $email, true, false);
+ if ($existing->count)
+ return true;
+ }
+
+ return false;
+}
+
+function rcmail_message_contactphoto($attrib)
+{
+ global $RCMAIL, $MESSAGE;
+
+ $placeholder = $attrib['placeholder'] ? $RCMAIL->config->get('skin_path') . $attrib['placeholder'] : null;
+ if ($MESSAGE->sender)
+ $photo_img = $RCMAIL->url(array('_task' => 'addressbook', '_action' => 'photo', '_email' => $MESSAGE->sender['mailto'], '_alt' => $placeholder));
+ else
+ $photo_img = $placeholder ? $placeholder : 'program/resources/blank.gif';
+
+ return html::img(array('src' => $photo_img) + $attrib);
+}
+
+
+$OUTPUT->add_handlers(array(
+ 'messageattachments' => 'rcmail_message_attachments',
+ 'mailboxname' => 'rcmail_mailbox_name_display',
+ 'messageobjects' => 'rcmail_message_objects',
+ 'contactphoto' => 'rcmail_message_contactphoto',
+));
+
+
+if ($RCMAIL->action=='print' && $OUTPUT->template_exists('messageprint'))
+ $OUTPUT->send('messageprint', false);
+else if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messagepreview'))
+ $OUTPUT->send('messagepreview', false);
+else
+ $OUTPUT->send('message', false);
+
+
+// mark message as read
+if ($MESSAGE && $MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN']) &&
+ ($RCMAIL->action == 'show' || ($RCMAIL->action == 'preview' && intval($CONFIG['preview_pane_mark_read']) == 0)))
+{
+ if ($RCMAIL->storage->set_flag($MESSAGE->uid, 'SEEN')) {
+ if ($count = rcmail_get_unseen_count($mbox_name)) {
+ rcmail_set_unseen_count($mbox_name, $count - 1);
+ }
+ }
+}
+
+exit;
+
diff --git a/program/steps/settings/about.inc b/program/steps/settings/about.inc
index 0fdefddda..9b13402f1 100644
--- a/program/steps/settings/about.inc
+++ b/program/steps/settings/about.inc
@@ -40,28 +40,17 @@ function rcmail_plugins_list($attrib)
$attrib['id'] = 'rcmpluginlist';
$plugins = array_filter((array) $RCMAIL->config->get('plugins'));
- $plugin_info = array();
+ $plugins = array_flip($plugins);
- foreach ($plugins as $name) {
- if ($info = $RCMAIL->plugins->get_info($name))
- $plugin_info[$name] = $info;
+ foreach ($plugins as $name => $plugin) {
+ rcube_plugin_data($name, $plugins);
}
- // load info from required plugins, too
- foreach ($plugin_info as $name => $info) {
- if (is_array($info['required']) && !empty($info['required'])) {
- foreach ($info['required'] as $req_name) {
- if (!isset($plugin_info[$req_name]) && ($req_info = $RCMAIL->plugins->get_info($req_name)))
- $plugin_info[$req_name] = $req_info;
- }
- }
- }
-
- if (empty($plugin_info)) {
+ if (empty($plugins)) {
return '';
}
- ksort($plugin_info, SORT_LOCALE_STRING);
+ ksort($plugins, SORT_LOCALE_STRING);
$table = new html_table($attrib);
@@ -71,8 +60,8 @@ function rcmail_plugins_list($attrib)
$table->add_header('license', rcube_label('license'));
$table->add_header('source', rcube_label('source'));
- foreach ($plugin_info as $name => $data) {
- $uri = $data['src_uri'] ? $data['src_uri'] : $data['uri'];
+ foreach ($plugins as $name => $data) {
+ $uri = $data['srcuri'] ? $data['srcuri'] : $data['uri'];
if ($uri && stripos($uri, 'http') !== 0) {
$uri = 'http://' . $uri;
}
@@ -89,6 +78,48 @@ function rcmail_plugins_list($attrib)
return $table->show();
}
+function rcube_plugin_data($name, &$plugins = array())
+{
+ // XPaths of plugin metadata elements
+ $metadata = array(
+ 'name' => 'string(//rc:package/rc:name)',
+ 'version' => 'string(//rc:package/rc:version/rc:release)',
+ 'license' => 'string(//rc:package/rc:license)',
+ 'license_uri' => 'string(//rc:package/rc:license/@uri)',
+ 'srcuri' => 'string(//rc:package/rc:srcuri)',
+ 'uri' => 'string(//rc:package/rc:uri)',
+ );
+
+ $package = INSTALL_PATH . "/plugins/$name/package.xml";
+ if (file_exists($package) && ($file = file_get_contents($package))) {
+ $doc = new DOMDocument();
+ $doc->loadXML($file);
+ $xpath = new DOMXPath($doc);
+ $xpath->registerNamespace('rc', "http://pear.php.net/dtd/package-2.0");
+ $data = array();
+
+ foreach ($metadata as $key => $path) {
+ $data[$key] = $xpath->evaluate($path);
+ }
+
+ $plugins[$name] = $data;
+
+ // dependent required plugins (can be used, but not included in config)
+ $deps = $xpath->evaluate('//rc:package/rc:dependencies/rc:required/rc:package/rc:name');
+ $cnt = $deps->length;
+
+ for ($i=0; $i<$cnt; $i++) {
+ $dn = $deps->item($i)->nodeValue;
+ if (!array_key_exists($dn, $plugins)) {
+ rcube_plugin_data($dn, $plugins);
+ }
+ }
+ }
+ else {
+ unset($plugins[$name]);
+ }
+}
+
$OUTPUT->set_pagetitle(rcube_label('about'));
diff --git a/program/steps/settings/edit_folder.inc b/program/steps/settings/edit_folder.inc
index f19e2177b..fdb38e602 100644
--- a/program/steps/settings/edit_folder.inc
+++ b/program/steps/settings/edit_folder.inc
@@ -264,12 +264,9 @@ function rcmail_folder_form($attrib)
$content = rcmail_get_form_part($tab, $attrib);
}
- if ($content && sizeof($form) > 1) {
+ if ($content) {
$out .= html::tag('fieldset', null, html::tag('legend', null, Q($tab['name'])) . $content) ."\n";
}
- else {
- $out .= $content ."\n";
- }
}
$out .= "\n$form_end";
diff --git a/program/steps/settings/edit_prefs.inc b/program/steps/settings/edit_prefs.inc
index 468e4994d..971ed60b6 100644
--- a/program/steps/settings/edit_prefs.inc
+++ b/program/steps/settings/edit_prefs.inc
@@ -40,7 +40,7 @@ function rcmail_user_prefs_form($attrib)
$out = $form_start;
- foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $block) {
+ foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $idx => $block) {
if (!empty($block['options'])) {
$table = new html_table(array('cols' => 2));
diff --git a/program/steps/settings/edit_response.inc b/program/steps/settings/edit_response.inc
new file mode 100644
index 000000000..49856775a
--- /dev/null
+++ b/program/steps/settings/edit_response.inc
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/edit_response.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Show edit form for a canned response record or to add a new one |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+$responses = $RCMAIL->get_compose_responses();
+
+// edit-response
+if (($key = get_input_value('_key', RCUBE_INPUT_GPC))) {
+ foreach ($responses as $i => $response) {
+ if ($response['key'] == $key) {
+ $RESPONSE_RECORD = $response;
+ $RESPONSE_RECORD['index'] = $i;
+ break;
+ }
+ }
+}
+
+// save response
+if ($RCMAIL->action == 'save-response' && isset($_POST['_name']) && !$RESPONSE_RECORD['static']) {
+ $name = trim(get_input_value('_name', RCUBE_INPUT_POST));
+ $text = trim(get_input_value('_text', RCUBE_INPUT_POST));
+
+ if (!empty($name) && !empty($text)) {
+ $dupes = 0;
+ foreach ($responses as $i => $resp) {
+ if ($RESPONSE_RECORD && $RESPONSE_RECORD['index'] === $i)
+ continue;
+ if (strcasecmp($name, preg_replace('/\s\(\d+\)$/', '', $resp['name'])) == 0)
+ $dupes++;
+ }
+ if ($dupes) { // require a unique name
+ $name .= ' (' . ++$dupes . ')';
+ }
+
+ $response = array('name' => $name, 'text' => $text, 'format' => 'text', 'key' => substr(md5($name), 0, 16));
+ if ($RESPONSE_RECORD && $responses[$RESPONSE_RECORD['index']]) {
+ $responses[$RESPONSE_RECORD['index']] = $response;
+ }
+ else {
+ $responses[] = $response;
+ }
+
+ $responses = array_filter($responses, function($item){ return empty($item['static']); });
+ if ($RCMAIL->user->save_prefs(array('compose_responses' => array_values($responses)))) {
+ $RCMAIL->output->show_message('successfullysaved', 'confirmation');
+ $RCMAIL->output->command('parent.update_response_row', $response, $key);
+ $RCMAIL->overwrite_action('edit-response');
+ $RESPONSE_RECORD = $response;
+ }
+ }
+ else {
+ $RCMAIL->output->show_message('formincomplete', 'error');
+ }
+}
+
+
+function rcube_response_form($attrib)
+{
+ global $RCMAIL, $OUTPUT, $RESPONSE_RECORD;
+
+ // Set form tags and hidden fields
+ $disabled = !empty($RESPONSE_RECORD['static']);
+ $key = $RESPONSE_RECORD['key'];
+ list($form_start, $form_end) = get_form_tags($attrib, 'save-response', $key, array('name' => '_key', 'value' => $key));
+ unset($attrib['form'], $attrib['id']);
+
+ // return the complete edit form as table
+ $out = "$form_start\n";
+
+ $table = new html_table(array('cols' => 2));
+ $label = rcube_label('responsename');
+
+ $table->add('title', html::label('ffname', Q(rcube_label('responsename'))));
+ $table->add(null, rcube_output::get_edit_field('name', $RESPONSE_RECORD['name'], array('id' => 'ffname', 'size' => $attrib['size'], 'disabled' => $disabled), 'text'));
+
+ $table->add('title', html::label('fftext', Q(rcube_label('responsetext'))));
+ $table->add(null, rcube_output::get_edit_field('text', $RESPONSE_RECORD['text'], array('id' => 'fftext', 'size' => $attrib['textareacols'], 'rows' => $attrib['textarearows'], 'disabled' => $disabled), 'textarea'));
+
+ $out .= $table->show($attrib);
+ $out .= $form_end;
+
+ return $out;
+}
+
+$OUTPUT->set_env('readonly', !empty($RESPONSE_RECORD['static']));
+$OUTPUT->add_handler('responseform', 'rcube_response_form');
+$OUTPUT->set_pagetitle(rcube_label(($RCMAIL->action=='add-response' ? 'savenewresponse' : 'editresponse')));
+
+$OUTPUT->send('responseedit');
+
diff --git a/program/steps/settings/folders.inc b/program/steps/settings/folders.inc
index 64af18d62..778d93c03 100644
--- a/program/steps/settings/folders.inc
+++ b/program/steps/settings/folders.inc
@@ -232,16 +232,16 @@ function rcube_subscription_form($attrib)
// add any necessary "virtual" parent folders
if ($parent_folder && !isset($seen[$parent_folder])) {
for ($i=1; $i<=$level; $i++) {
- $ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i));
- if ($ancestor_folder && !$seen[$ancestor_folder]++) {
- $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF7-IMAP');
- $list_folders[] = array(
+ $ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i));
+ if ($ancestor_folder && !$seen[$ancestor_folder]++) {
+ $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF7-IMAP');
+ $list_folders[] = array(
'id' => $ancestor_folder,
'name' => $ancestor_name,
'level' => $i-1,
'virtual' => true,
);
- }
+ }
}
}
@@ -283,6 +283,7 @@ function rcube_subscription_form($attrib)
$noselect = false;
$classes = array($i%2 ? 'even' : 'odd');
+ $folder_js = Q($folder['id']);
$folder_utf8 = rcube_charset_convert($folder['id'], 'UTF7-IMAP');
$display_folder = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $folder['level'])
. Q($protected ? rcmail_localize_foldername($folder['id']) : $folder['name']);
@@ -291,8 +292,7 @@ function rcube_subscription_form($attrib)
$classes[] = 'virtual';
}
- // Check \Noselect flag (of existing folder)
- if (!$protected && in_array($folder['id'], $a_unsubscribed)) {
+ if (!$protected) {
$attrs = $STORAGE->folder_attributes($folder['id']);
$noselect = in_array('\\Noselect', $attrs);
}
@@ -394,7 +394,7 @@ function rcmail_rename_folder($oldname, $newname)
$a_threaded = (array) $RCMAIL->config->get('message_threading', array());
$oldprefix = '/^' . preg_quote($oldname . $delimiter, '/') . '/';
- foreach (array_keys($a_threaded) as $key) {
+ foreach ($a_threaded as $key => $val) {
if ($key == $oldname) {
unset($a_threaded[$key]);
$a_threaded[$newname] = true;
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index fdc07be9e..981d4e406 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -19,1176 +19,915 @@
+-----------------------------------------------------------------------+
*/
-if (!$OUTPUT->ajax_call) {
- $OUTPUT->set_pagetitle(rcube_label('preferences'));
-}
+if (!$OUTPUT->ajax_call)
+ $OUTPUT->set_pagetitle(rcube_label('preferences'));
+
// similar function as /steps/settings/identities.inc::rcmail_identity_frame()
function rcmail_preferences_frame($attrib)
{
- global $OUTPUT;
+ global $OUTPUT;
- if (!$attrib['id']) {
- $attrib['id'] = 'rcmprefsframe';
- }
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmprefsframe';
- return $OUTPUT->frame($attrib, true);
+ return $OUTPUT->frame($attrib, true);
}
function rcmail_sections_list($attrib)
{
- global $RCMAIL;
+ global $RCMAIL;
- // add id to message list table if not specified
- if (!strlen($attrib['id'])) {
- $attrib['id'] = 'rcmsectionslist';
- }
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmsectionslist';
- list($list, $cols) = rcmail_user_prefs();
+ list($list, $cols) = rcmail_user_prefs();
- // create XHTML table
- $out = rcube_table_output($attrib, $list, $cols, 'id');
+ // create XHTML table
+ $out = rcube_table_output($attrib, $list, $cols, 'id');
- // set client env
- $RCMAIL->output->add_gui_object('sectionslist', $attrib['id']);
- $RCMAIL->output->include_script('list.js');
+ // set client env
+ $RCMAIL->output->add_gui_object('sectionslist', $attrib['id']);
+ $RCMAIL->output->include_script('list.js');
- return $out;
+ return $out;
}
function rcmail_identities_list($attrib)
{
- global $OUTPUT, $RCMAIL;
+ global $OUTPUT, $RCMAIL;
- // add id to message list table if not specified
- if (!strlen($attrib['id'])) {
- $attrib['id'] = 'rcmIdentitiesList';
- }
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmIdentitiesList';
- // get identities list and define 'mail' column
- $list = $RCMAIL->user->list_identities();
- foreach ($list as $idx => $row) {
- $list[$idx]['mail'] = trim($row['name'] . ' <' . rcube_idn_to_utf8($row['email']) .'>');
- }
+ // get identities list and define 'mail' column
+ $list = $RCMAIL->user->list_identities();
+ foreach ($list as $idx => $row)
+ $list[$idx]['mail'] = trim($row['name'] . ' <' . rcube_idn_to_utf8($row['email']) .'>');
- // get all identites from DB and define list of cols to be displayed
- $plugin = $RCMAIL->plugins->exec_hook('identities_list', array(
- 'list' => $list,
- 'cols' => array('mail')
- ));
+ // get all identites from DB and define list of cols to be displayed
+ $plugin = $RCMAIL->plugins->exec_hook('identities_list', array(
+ 'list' => $list,
+ 'cols' => array('mail')));
- // @TODO: use <UL> instead of <TABLE> for identities list
- // create XHTML table
- $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'identity_id');
+ // @TODO: use <UL> instead of <TABLE> for identities list
+ // create XHTML table
+ $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'identity_id');
- // set client env
- $OUTPUT->add_gui_object('identitieslist', $attrib['id']);
+ // set client env
+ $OUTPUT->add_gui_object('identitieslist', $attrib['id']);
- return $out;
+ return $out;
}
// similar function as in /steps/addressbook/edit.inc
function get_form_tags($attrib, $action, $id = null, $hidden = null)
{
- global $EDIT_FORM, $RCMAIL;
-
- $form_start = $form_end = '';
-
- if (empty($EDIT_FORM)) {
- $request_key = $action . (isset($id) ? '.'.$id : '');
- $form_start = $RCMAIL->output->request_form(array(
- 'name' => 'form',
- 'method' => 'post',
- 'task' => $RCMAIL->task,
- 'action' => $action,
- 'request' => $request_key,
- 'noclose' => true
- ) + $attrib);
-
- if (is_array($hidden)) {
- $hiddenfields = new html_hiddenfield($hidden);
- $form_start .= $hiddenfields->show();
- }
+ global $EDIT_FORM, $RCMAIL;
+
+ $form_start = $form_end = '';
+
+ if (empty($EDIT_FORM)) {
+ $request_key = $action . (isset($id) ? '.'.$id : '');
+ $form_start = $RCMAIL->output->request_form(array(
+ 'name' => 'form',
+ 'method' => 'post',
+ 'task' => $RCMAIL->task,
+ 'action' => $action,
+ 'request' => $request_key,
+ 'noclose' => true
+ ) + $attrib);
+
+ if (is_array($hidden)) {
+ $hiddenfields = new html_hiddenfield($hidden);
+ $form_start .= $hiddenfields->show();
+ }
- $form_end = !strlen($attrib['form']) ? '</form>' : '';
+ $form_end = !strlen($attrib['form']) ? '</form>' : '';
- $EDIT_FORM = !empty($attrib['form']) ? $attrib['form'] : 'form';
- $RCMAIL->output->add_gui_object('editform', $EDIT_FORM);
- }
+ $EDIT_FORM = !empty($attrib['form']) ? $attrib['form'] : 'form';
+ $RCMAIL->output->add_gui_object('editform', $EDIT_FORM);
+ }
- return array($form_start, $form_end);
+ return array($form_start, $form_end);
}
-function rcmail_user_prefs($current = null)
+function rcmail_user_prefs($current=null)
{
- global $RCMAIL;
+ global $RCMAIL;
+
+ $sections['general'] = array('id' => 'general', 'section' => rcube_label('uisettings'));
+ $sections['mailbox'] = array('id' => 'mailbox', 'section' => rcube_label('mailboxview'));
+ $sections['mailview'] = array('id' => 'mailview','section' => rcube_label('messagesdisplaying'));
+ $sections['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition'));
+ $sections['addressbook'] = array('id' => 'addressbook','section' => rcube_label('addressbook'));
+ $sections['folders'] = array('id' => 'folders', 'section' => rcube_label('specialfolders'));
+ $sections['server'] = array('id' => 'server', 'section' => rcube_label('serversettings'));
+
+ // hook + define list cols
+ $plugin = $RCMAIL->plugins->exec_hook('preferences_sections_list',
+ array('list' => $sections, 'cols' => array('section')));
- $sections['general'] = array('id' => 'general', 'section' => rcube_label('uisettings'));
- $sections['mailbox'] = array('id' => 'mailbox', 'section' => rcube_label('mailboxview'));
- $sections['mailview'] = array('id' => 'mailview','section' => rcube_label('messagesdisplaying'));
- $sections['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition'));
- $sections['addressbook'] = array('id' => 'addressbook','section' => rcube_label('addressbook'));
- $sections['folders'] = array('id' => 'folders', 'section' => rcube_label('specialfolders'));
- $sections['server'] = array('id' => 'server', 'section' => rcube_label('serversettings'));
+ $sections = $plugin['list'];
- // hook + define list cols
- $plugin = $RCMAIL->plugins->exec_hook('preferences_sections_list',
- array('list' => $sections, 'cols' => array('section')));
+ $config = $RCMAIL->config->all();
+ $no_override = array_flip($RCMAIL->config->get('dont_override', array()));
+
+ foreach ($sections as $idx => $sect) {
+
+ if ($current && $sect['id'] != $current)
+ continue;
+
+ $blocks = array();
- $sections = $plugin['list'];
- $config = $RCMAIL->config->all();
- $no_override = array_flip((array)$RCMAIL->config->get('dont_override'));
+ switch ($sect['id']) {
+ // general
+ case 'general':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ );
+
+ // language selection
+ if (!isset($no_override['language'])) {
+ $a_lang = $RCMAIL->list_languages();
+ asort($a_lang);
+
+ $field_id = 'rcmfd_lang';
+ $select_lang = new html_select(array('name' => '_language', 'id' => $field_id));
+ $select_lang->add(array_values($a_lang), array_keys($a_lang));
+
+ $blocks['main']['options']['language'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('language'))),
+ 'content' => $select_lang->show($RCMAIL->user->language),
+ );
+ }
- foreach ($sections as $idx => $sect) {
- if ($current && $sect['id'] != $current) {
- continue;
+ // timezone selection
+ if (!isset($no_override['timezone'])) {
+ $field_id = 'rcmfd_timezone';
+ $select_timezone = new html_select(array('name' => '_timezone', 'id' => $field_id));
+ $select_timezone->add(rcube_label('autodetect'), 'auto');
+
+ $zones = array();
+ foreach (DateTimeZone::listIdentifiers() as $i => $tzs) {
+ try {
+ $tz = new DateTimeZone($tzs);
+ $date = new DateTime('2012-12-21', $tz);
+ $offset = $date->format('Z') + 45000;
+ $sortkey = sprintf('%06d.%s', $offset, $tzs);
+ $zones[$sortkey] = array($tzs, $date->format('P'));
}
+ catch (Exception $e) {}
+ }
+
+ ksort($zones);
+ foreach ($zones as $zone) {
+ list($tzs, $offset) = $zone;
+ $select_timezone->add('(GMT ' . $offset . ') ' . strtr($tzs, '_', ' '), $tzs);
+ }
+
+ $blocks['main']['options']['timezone'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('timezone'))),
+ 'content' => $select_timezone->show((string)$config['timezone']),
+ );
+ }
+
+ // date/time formatting
+ if (!isset($no_override['time_format'])) {
+ $reftime = mktime(7,30,0);
+ $field_id = 'rcmfd_time_format';
+ $select_time = new html_select(array('name' => '_time_format', 'id' => $field_id));
+ foreach ((array)$RCMAIL->config->get('time_formats', array('G:i', 'H:i', 'g:i a', 'h:i A')) as $choice)
+ $select_time->add(date($choice, $reftime), $choice);
+
+ $blocks['main']['options']['time_format'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('timeformat'))),
+ 'content' => $select_time->show($RCMAIL->config->get('time_format')),
+ );
+ }
+
+ if (!isset($no_override['date_format'])) {
+ $refdate = mktime(12,30,0,7,24);
+ $field_id = 'rcmfd_date_format';
+ $select_date = new html_select(array('name' => '_date_format', 'id' => $field_id));
+ foreach ((array)$RCMAIL->config->get('date_formats', array('Y-m-d','d-m-Y','Y/m/d','m/d/Y','d/m/Y','d.m.Y','j.n.Y')) as $choice)
+ $select_date->add(date($choice, $refdate), $choice);
+
+ $blocks['main']['options']['date_format'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('dateformat'))),
+ 'content' => $select_date->show($config['date_format']),
+ );
+ }
+
+ // MM: Show checkbox for toggling 'pretty dates'
+ if (!isset($no_override['prettydate'])) {
+ $field_id = 'rcmfd_prettydate';
+ $input_prettydate = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1));
- $blocks = array();
-
- switch ($sect['id']) {
-
- // general
- case 'general':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- 'skin' => array('name' => Q(rcube_label('skin'))),
- 'browser' => array('name' => Q(rcube_label('browseroptions'))),
- );
-
- // language selection
- if (!isset($no_override['language'])) {
- if (!$current) {
- continue 2;
- }
-
- $a_lang = $RCMAIL->list_languages();
- asort($a_lang);
-
- $field_id = 'rcmfd_lang';
- $select = new html_select(array('name' => '_language', 'id' => $field_id));
- $select->add(array_values($a_lang), array_keys($a_lang));
-
- $blocks['main']['options']['language'] = array(
- 'title' => html::label($field_id, Q(rcube_label('language'))),
- 'content' => $select->show($RCMAIL->user->language),
- );
- }
-
- // timezone selection
- if (!isset($no_override['timezone'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_timezone';
- $select = new html_select(array('name' => '_timezone', 'id' => $field_id));
- $select->add(rcube_label('autodetect'), 'auto');
-
- $zones = array();
- foreach (DateTimeZone::listIdentifiers() as $i => $tzs) {
- try {
- $tz = new DateTimeZone($tzs);
- $date = new DateTime('2012-12-21', $tz);
- $offset = $date->format('Z') + 45000;
- $sortkey = sprintf('%06d.%s', $offset, $tzs);
- $zones[$sortkey] = array($tzs, $date->format('P'));
- }
- catch (Exception $e) {}
- }
-
- ksort($zones);
-
- foreach ($zones as $zone) {
- list($tzs, $offset) = $zone;
- $select->add('(GMT ' . $offset . ') ' . strtr($tzs, '_', ' '), $tzs);
- }
-
- $blocks['main']['options']['timezone'] = array(
- 'title' => html::label($field_id, Q(rcube_label('timezone'))),
- 'content' => $select->show((string)$config['timezone']),
- );
- }
-
- // date/time formatting
- if (!isset($no_override['time_format'])) {
- if (!$current) {
- continue 2;
- }
-
- $reftime = mktime(7,30,0);
- $defaults = array('G:i', 'H:i', 'g:i a', 'h:i A');
- $formats = (array)$RCMAIL->config->get('time_formats', $defaults);
- $field_id = 'rcmfd_time_format';
- $select = new html_select(array('name' => '_time_format', 'id' => $field_id));
-
- foreach ($formats as $choice) {
- $select->add(date($choice, $reftime), $choice);
- }
-
- $blocks['main']['options']['time_format'] = array(
- 'title' => html::label($field_id, Q(rcube_label('timeformat'))),
- 'content' => $select->show($RCMAIL->config->get('time_format')),
- );
- }
-
- if (!isset($no_override['date_format'])) {
- if (!$current) {
- continue 2;
- }
-
- $refdate = mktime(12,30,0,7,24);
- $defaults = array('Y-m-d','d-m-Y','Y/m/d','m/d/Y','d/m/Y','d.m.Y','j.n.Y');
- $formats = (array)$RCMAIL->config->get('date_formats', $defaults);
- $field_id = 'rcmfd_date_format';
- $select = new html_select(array('name' => '_date_format', 'id' => $field_id));
-
- foreach ($formats as $choice) {
- $select->add(date($choice, $refdate), $choice);
- }
-
- $blocks['main']['options']['date_format'] = array(
- 'title' => html::label($field_id, Q(rcube_label('dateformat'))),
- 'content' => $select->show($config['date_format']),
- );
- }
-
- // Show checkbox for toggling 'pretty dates'
- if (!isset($no_override['prettydate'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_prettydate';
- $input = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['prettydate'] = array(
- 'title' => html::label($field_id, Q(rcube_label('prettydate'))),
- 'content' => $input->show($config['prettydate']?1:0),
- );
- }
-
- if (!isset($no_override['refresh_interval'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_refresh_interval';
- $select = new html_select(array('name' => '_refresh_interval', 'id' => $field_id));
-
- $select->add(rcube_label('never'), 0);
- foreach (array(1, 3, 5, 10, 15, 30, 60) as $min) {
- if (!$config['min_refresh_interval'] || $config['min_refresh_interval'] <= $min * 60) {
- $label = rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min)));
- $select->add($label, $min);
- }
- }
-
- $blocks['main']['options']['refresh_interval'] = array(
- 'title' => html::label($field_id, Q(rcube_label('refreshinterval'))),
- 'content' => $select->show($config['refresh_interval']/60),
- );
- }
-
- // show drop-down for available skins
- if (!isset($no_override['skin'])) {
- if (!$current) {
- continue 2;
- }
-
- $skins = rcmail_get_skins();
-
- if (count($skins) > 1) {
- $field_id = 'rcmfd_skin';
- $input = new html_radiobutton(array('name'=>'_skin'));
-
- foreach ($skins as $skin) {
- $thumbnail = "./skins/$skin/thumbnail.png";
- if (!is_file($thumbnail))
- $thumbnail = './program/resources/blank.gif';
-
- $skinname = ucfirst($skin);
- $author_link = $license_link = '';
- $meta = @json_decode(@file_get_contents("./skins/$skin/meta.json"), true);
-
- if (is_array($meta) && $meta['name']) {
- $skinname = $meta['name'];
- $author_link = $meta['url'] ? html::a(array('href' => $meta['url'], 'target' => '_blank'), Q($meta['author'])) : Q($meta['author']);
- $license_link = $meta['license-url'] ? html::a(array('href' => $meta['license-url'], 'target' => '_blank'), Q($meta['license'])) : Q($meta['license']);
- }
-
- $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))) .
- html::span('skinitem', html::span('skinname', Q($skinname)) . html::br() .
- html::span('skinauthor', $author_link ? 'by ' . $author_link : '') . html::br() .
- html::span('skinlicense', $license_link ? rcube_label('license').':&nbsp;' . $license_link : ''))
- );
- }
- }
- }
-
- // standard_windows option decides if new windows should be
- // opened as popups or standard windows (which can be handled by browsers as tabs)
- if (!isset($no_override['standard_windows'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_standard_windows';
- $checkbox = new html_checkbox(array('name' => '_standard_windows', 'id' => $field_id, 'value' => 1));
-
- $blocks['browser']['options']['standard_windows'] = array(
- 'title' => html::label($field_id, Q(rcube_label('standardwindows'))),
- 'content' => $checkbox->show($config['standard_windows']?1:0),
- );
- }
-
- if ($current) {
- $product_name = $RCMAIL->config->get('product_name', 'Roundcube Webmail');
- $RCMAIL->output->add_script(sprintf("%s.check_protocol_handler('%s', '#mailtoprotohandler');",
- JS_OBJECT_NAME, JQ($product_name)), 'foot');
- }
-
- $blocks['browser']['options']['mailtoprotohandler'] = array(
- 'content' => html::a(array(
- 'href' => '#',
- 'id' => 'mailtoprotohandler'), Q(rcube_label('mailtoprotohandler'))),
- );
-
- break;
-
- // Mailbox view (mail screen)
- case 'mailbox':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- 'new_message' => array('name' => Q(rcube_label('newmessage'))),
- );
-
- // show config parameter for preview pane
- if (!isset($no_override['preview_pane'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_preview';
- $input = new html_checkbox(array('name' => '_preview_pane', 'id' => $field_id, 'value' => 1,
- 'onchange' => "$('#rcmfd_preview_pane_mark_read').prop('disabled', !this.checked)"));
-
- $blocks['main']['options']['preview_pane'] = array(
- 'title' => html::label($field_id, Q(rcube_label('previewpane'))),
- 'content' => $input->show($config['preview_pane']?1:0),
- );
- }
-
- // show config parameter for preview pane auto mark as read delay
- if (!isset($no_override['preview_pane_mark_read'])) {
- if (!$current) {
- continue 2;
- }
-
- // apply default if config option is not set at all
- $config['preview_pane_mark_read'] = $RCMAIL->config->get('preview_pane_mark_read', 0);
-
- $field_id = 'rcmfd_preview_pane_mark_read';
- $select = new html_select(array('name' => '_preview_pane_mark_read', 'id' => $field_id,
- 'disabled' => $config['preview_pane']?0:1));
-
- $select->add(rcube_label('never'), '-1');
- $select->add(rcube_label('immediately'), 0);
-
- foreach (array(5, 10, 20, 30) as $sec) {
- $label = rcube_label(array('name' => 'afternseconds', 'vars' => array('n' => $sec)));
- $select->add($label, $sec);
- }
-
- $blocks['main']['options']['preview_pane_mark_read'] = array(
- 'title' => html::label($field_id, Q(rcube_label('previewpanemarkread'))),
- 'content' => $select->show(intval($config['preview_pane_mark_read'])),
- );
- }
-
- if (!isset($no_override['mdn_requests'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_mdn_requests';
- $select = new html_select(array('name' => '_mdn_requests', 'id' => $field_id));
- $select->add(rcube_label('askuser'), 0);
- $select->add(rcube_label('autosend'), 1);
- $select->add(rcube_label('autosendknown'), 3);
- $select->add(rcube_label('autosendknownignore'), 4);
- $select->add(rcube_label('ignore'), 2);
-
- $blocks['main']['options']['mdn_requests'] = array(
- 'title' => html::label($field_id, Q(rcube_label('mdnrequests'))),
- 'content' => $select->show($config['mdn_requests']),
- );
- }
-
- if (!isset($no_override['autoexpand_threads'])) {
- if (!$current) {
- continue 2;
- }
-
- $storage = $RCMAIL->get_storage();
- $supported = $storage->get_capability('THREAD');
-
- if ($supported) {
- $field_id = 'rcmfd_autoexpand_threads';
- $select = new html_select(array('name' => '_autoexpand_threads', 'id' => $field_id));
- $select->add(rcube_label('never'), 0);
- $select->add(rcube_label('do_expand'), 1);
- $select->add(rcube_label('expand_only_unread'), 2);
-
- $blocks['main']['options']['autoexpand_threads'] = array(
- 'title' => html::label($field_id, Q(rcube_label('autoexpand_threads'))),
- 'content' => $select->show($config['autoexpand_threads']),
- );
- }
- }
-
- // show page size selection
- if (!isset($no_override['mail_pagesize'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_mail_pagesize';
- $input = new html_inputfield(array('name' => '_mail_pagesize', 'id' => $field_id, 'size' => 5));
- $size = intval($config['mail_pagesize'] ? $config['mail_pagesize'] : $config['pagesize']);
-
- $blocks['main']['options']['pagesize'] = array(
- 'title' => html::label($field_id, Q(rcube_label('pagesize'))),
- 'content' => $input->show($size ? $size : 50),
- );
- }
-
- if (!isset($no_override['check_all_folders'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_check_all_folders';
- $input = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1));
-
- $blocks['new_message']['options']['check_all_folders'] = array(
- 'title' => html::label($field_id, Q(rcube_label('checkallfolders'))),
- 'content' => $input->show($config['check_all_folders']?1:0),
- );
- }
- break;
-
- // Message viewing
- case 'mailview':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- );
-
- // show checkbox to open message view in new window
- if (!isset($no_override['message_extwin'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_message_extwin';
- $input = new html_checkbox(array('name' => '_message_extwin', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['message_extwin'] = array(
- 'title' => html::label($field_id, Q(rcube_label('showinextwin'))),
- 'content' => $input->show($config['message_extwin']?1:0),
- );
- }
-
- // show checkbox to show email instead of name
- if (!isset($no_override['message_show_email'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_message_show_email';
- $input = new html_checkbox(array('name' => '_message_show_email', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['message_show_email'] = array(
- 'title' => html::label($field_id, Q(rcube_label('showemail'))),
- 'content' => $input->show($config['message_show_email']?1:0),
- );
- }
-
- // show checkbox for HTML/plaintext messages
- if (!isset($no_override['prefer_html'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_htmlmsg';
- $input = new html_checkbox(array('name' => '_prefer_html', 'id' => $field_id, 'value' => 1,
- 'onchange' => "$('#rcmfd_show_images').prop('disabled', !this.checked).val(0)"));
-
- $blocks['main']['options']['prefer_html'] = array(
- 'title' => html::label($field_id, Q(rcube_label('preferhtml'))),
- 'content' => $input->show($config['prefer_html']?1:0),
- );
- }
-
- if (!isset($no_override['default_charset'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_default_charset';
-
- $blocks['main']['options']['default_charset'] = array(
- 'title' => html::label($field_id, Q(rcube_label('defaultcharset'))),
- 'content' => $RCMAIL->output->charset_selector(array(
- 'id' => $field_id, 'name' => '_default_charset', 'selected' => $config['default_charset']
- )));
- }
-
- if (!isset($no_override['show_images'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_show_images';
- $input = new html_select(array('name' => '_show_images', 'id' => $field_id,
- 'disabled' => !$config['prefer_html']));
-
- $input->add(rcube_label('never'), 0);
- $input->add(rcube_label('fromknownsenders'), 1);
- $input->add(rcube_label('always'), 2);
-
- $blocks['main']['options']['show_images'] = array(
- 'title' => html::label($field_id, Q(rcube_label('showremoteimages'))),
- 'content' => $input->show($config['prefer_html'] ? $config['show_images'] : 0),
- );
- }
-
- if (!isset($no_override['inline_images'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_inline_images';
- $input = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['inline_images'] = array(
- 'title' => html::label($field_id, Q(rcube_label('showinlineimages'))),
- 'content' => $input->show($config['inline_images']?1:0),
- );
- }
-
- // "display after delete" checkbox
- if (!isset($no_override['display_next'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_displaynext';
- $input = new html_checkbox(array('name' => '_display_next', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['display_next'] = array(
- 'title' => html::label($field_id, Q(rcube_label('displaynext'))),
- 'content' => $input->show($config['display_next']?1:0),
- );
- }
- break;
-
- // Mail composition
- case 'compose':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- 'sig' => array('name' => Q(rcube_label('signatureoptions'))),
- 'spellcheck' => array('name' => Q(rcube_label('spellcheckoptions'))),
- );
-
- // show checkbox to compose messages in a new window
- if (!isset($no_override['compose_extwin'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfdcompose_extwin';
- $input = new html_checkbox(array('name' => '_compose_extwin', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['compose_extwin'] = array(
- 'title' => html::label($field_id, Q(rcube_label('composeextwin'))),
- 'content' => $input->show($config['compose_extwin']?1:0),
- );
- }
-
- if (!isset($no_override['htmleditor'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_htmleditor';
- $select = new html_select(array('name' => '_htmleditor', 'id' => $field_id));
-
- $select->add(rcube_label('never'), 0);
- $select->add(rcube_label('always'), 1);
- $select->add(rcube_label('htmlonreply'), 2);
- $select->add(rcube_label('htmlonreplyandforward'), 3);
-
- $blocks['main']['options']['htmleditor'] = array(
- 'title' => html::label($field_id, Q(rcube_label('htmleditor'))),
- 'content' => $select->show(intval($config['htmleditor'])),
- );
- }
-
- if (!isset($no_override['draft_autosave'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_autosave';
- $select = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox'])));
-
- $select->add(rcube_label('never'), 0);
- foreach (array(1, 3, 5, 10) as $i => $min) {
- $label = rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min)));
- $select->add($label, $min*60);
- }
-
- $blocks['main']['options']['draft_autosave'] = array(
- 'title' => html::label($field_id, Q(rcube_label('autosavedraft'))),
- 'content' => $select->show($config['draft_autosave']),
- );
- }
-
- if (!isset($no_override['mime_param_folding'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_param_folding';
- $select = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id));
-
- $select->add(rcube_label('2231folding'), 0);
- $select->add(rcube_label('miscfolding'), 1);
- $select->add(rcube_label('2047folding'), 2);
-
- $blocks['main']['options']['mime_param_folding'] = array(
- 'advanced' => true,
- 'title' => html::label($field_id, Q(rcube_label('mimeparamfolding'))),
- 'content' => $select->show($config['mime_param_folding']),
- );
- }
-
- if (!isset($no_override['force_7bit'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_force_7bit';
- $input = new html_checkbox(array('name' => '_force_7bit', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['force_7bit'] = array(
- 'advanced' => true,
- 'title' => html::label($field_id, Q(rcube_label('force7bit'))),
- 'content' => $input->show($config['force_7bit']?1:0),
- );
- }
-
- if (!isset($no_override['mdn_default'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_mdn_default';
- $input = new html_checkbox(array('name' => '_mdn_default', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['mdn_default'] = array(
- 'title' => html::label($field_id, Q(rcube_label('reqmdn'))),
- 'content' => $input->show($config['mdn_default']?1:0),
- );
- }
-
- if (!isset($no_override['dsn_default'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_dsn_default';
- $input = new html_checkbox(array('name' => '_dsn_default', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['dsn_default'] = array(
- 'title' => html::label($field_id, Q(rcube_label('reqdsn'))),
- 'content' => $input->show($config['dsn_default']?1:0),
- );
- }
-
- if (!isset($no_override['reply_same_folder'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_reply_same_folder';
- $input = new html_checkbox(array('name' => '_reply_same_folder', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['reply_same_folder'] = array(
- 'title' => html::label($field_id, Q(rcube_label('replysamefolder'))),
- 'content' => $input->show($config['reply_same_folder']?1:0),
- );
- }
-
- if (!isset($no_override['reply_mode'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_reply_mode';
- $select = new html_select(array('name' => '_reply_mode', 'id' => $field_id));
-
- $select->add(rcube_label('replyempty'), -1);
- $select->add(rcube_label('replybottomposting'), 0);
- $select->add(rcube_label('replytopposting'), 1);
-
- $blocks['main']['options']['reply_mode'] = array(
- 'title' => html::label($field_id, Q(rcube_label('whenreplying'))),
- 'content' => $select->show(intval($config['reply_mode'])),
- );
- }
-
- if (!isset($no_override['spellcheck_before_send']) && $config['enable_spellcheck']) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_spellcheck_before_send';
- $input = new html_checkbox(array('name' => '_spellcheck_before_send', 'id' => $field_id, 'value' => 1));
-
- $blocks['spellcheck']['options']['spellcheck_before_send'] = array(
- 'title' => html::label($field_id, Q(rcube_label('spellcheckbeforesend'))),
- 'content' => $input->show($config['spellcheck_before_send']?1:0),
- );
- }
-
- if ($config['enable_spellcheck']) {
- if (!$current) {
- continue 2;
- }
-
- foreach (array('syms', 'nums', 'caps') as $key) {
- $key = 'spellcheck_ignore_'.$key;
- if (!isset($no_override[$key])) {
- $input = new html_checkbox(array('name' => '_'.$key, 'id' => 'rcmfd_'.$key, 'value' => 1));
-
- $blocks['spellcheck']['options'][$key] = array(
- 'title' => html::label($field_id, Q(rcube_label(str_replace('_', '', $key)))),
- 'content' => $input->show($config[$key]?1:0),
- );
- }
- }
- }
-
- if (!isset($no_override['show_sig'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_show_sig';
- $select = new html_select(array('name' => '_show_sig', 'id' => $field_id));
-
- $select->add(rcube_label('never'), 0);
- $select->add(rcube_label('always'), 1);
- $select->add(rcube_label('newmessageonly'), 2);
- $select->add(rcube_label('replyandforwardonly'), 3);
-
- $blocks['sig']['options']['show_sig'] = array(
- 'title' => html::label($field_id, Q(rcube_label('autoaddsignature'))),
- 'content' => $select->show($RCMAIL->config->get('show_sig', 1)),
- );
- }
-
- if (!isset($no_override['strip_existing_sig'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_strip_existing_sig';
- $input = new html_checkbox(array('name' => '_strip_existing_sig', 'id' => $field_id, 'value' => 1));
-
- $blocks['sig']['options']['strip_existing_sig'] = array(
- 'title' => html::label($field_id, Q(rcube_label('replyremovesignature'))),
- 'content' => $input->show($config['strip_existing_sig']?1:0),
- );
- }
-
- if (!isset($no_override['forward_attachment'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_forward_attachment';
- $select = new html_select(array('name' => '_forward_attachment', 'id' => $field_id));
-
- $select->add(rcube_label('inline'), 0);
- $select->add(rcube_label('asattachment'), 1);
-
- $blocks['main']['options']['forward_attachment'] = array(
- 'title' => html::label($field_id, Q(rcube_label('forwardmode'))),
- 'content' => $select->show(intval($config['forward_attachment'])),
- );
- }
-
- if (!isset($no_override['default_font'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_default_font';
- $fonts = rcube_fontdefs();
- $selected = $config['default_font'];
-
- $select = '<select name="_default_font" id="'.$field_id.'">';
- $select .= '<option value=""' . (!$selected ? ' selected="selected"' : '') . '>---</option>';
- foreach ($fonts as $fname => $font) {
- $select .= '<option value="'.$fname.'"'
- . ($fname == $selected ? ' selected="selected"' : '')
- . ' style=\'font-family: ' . $font . '\'>'
- . Q($fname) . '</option>';
- }
- $select .= '</select>';
-
- $blocks['main']['options']['default_font'] = array(
- 'title' => html::label($field_id, Q(rcube_label('defaultfont'))),
- 'content' => $select
- );
- }
- break;
-
- // Addressbook config
- case 'addressbook':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- );
-
- if (!isset($no_override['default_addressbook'])
- && (!$current || ($books = $RCMAIL->get_address_sources(true, true)))
- ) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_default_addressbook';
- $select = new html_select(array('name' => '_default_addressbook', 'id' => $field_id));
-
- foreach ($books as $book) {
- $select->add(html_entity_decode($book['name'], ENT_COMPAT, 'UTF-8'), $book['id']);
- }
-
- $blocks['main']['options']['default_addressbook'] = array(
- 'title' => html::label($field_id, Q(rcube_label('defaultabook'))),
- 'content' => $select->show($config['default_addressbook']),
- );
- }
-
- // show addressbook listing mode selection
- if (!isset($no_override['addressbook_name_listing'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_addressbook_name_listing';
- $select = new html_select(array('name' => '_addressbook_name_listing', 'id' => $field_id));
-
- $select->add(rcube_label('name'), 0);
- $select->add(rcube_label('firstname') . ' ' . rcube_label('surname'), 1);
- $select->add(rcube_label('surname') . ' ' . rcube_label('firstname'), 2);
- $select->add(rcube_label('surname') . ', ' . rcube_label('firstname'), 3);
-
- $blocks['main']['options']['list_name_listing'] = array(
- 'title' => html::label($field_id, Q(rcube_label('listnamedisplay'))),
- 'content' => $select->show($config['addressbook_name_listing']),
- );
- }
-
- // show addressbook sort column
- if (!isset($no_override['addressbook_sort_col'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_addressbook_sort_col';
- $select = new html_select(array('name' => '_addressbook_sort_col', 'id' => $field_id));
-
- $select->add(rcube_label('name'), 'name');
- $select->add(rcube_label('firstname'), 'firstname');
- $select->add(rcube_label('surname'), 'surname');
-
- $blocks['main']['options']['sort_col'] = array(
- 'title' => html::label($field_id, Q(rcube_label('listsorting'))),
- 'content' => $select->show($config['addressbook_sort_col']),
- );
- }
-
- // show addressbook page size selection
- if (!isset($no_override['addressbook_pagesize'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_addressbook_pagesize';
- $input = new html_inputfield(array('name' => '_addressbook_pagesize', 'id' => $field_id, 'size' => 5));
- $size = intval($config['addressbook_pagesize'] ? $config['addressbook_pagesize'] : $config['pagesize']);
-
- $blocks['main']['options']['pagesize'] = array(
- 'title' => html::label($field_id, Q(rcube_label('pagesize'))),
- 'content' => $input->show($size ? $size : 50),
- );
- }
-
- if (!isset($no_override['autocomplete_single'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_autocomplete_single';
- $checkbox = new html_checkbox(array('name' => '_autocomplete_single', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['autocomplete_single'] = array(
- 'title' => html::label($field_id, Q(rcube_label('autocompletesingle'))),
- 'content' => $checkbox->show($config['autocomplete_single']?1:0),
- );
- }
- break;
-
- // Special IMAP folders
- case 'folders':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- );
-
- if (!isset($no_override['show_real_foldernames'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'show_real_foldernames';
- $input = new html_checkbox(array('name' => '_show_real_foldernames', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['show_real_foldernames'] = array(
- 'title' => html::label($field_id, Q(rcube_label('show_real_foldernames'))),
- 'content' => $input->show($config['show_real_foldernames']?1:0),
- );
- }
-
- // Configure special folders
- if (!isset($no_override['default_folders']) && $current) {
- $select = rcmail_mailbox_select(array(
- 'noselection' => '---',
- 'realnames' => true,
- 'maxlength' => 30,
- 'folder_filter' => 'mail',
- 'folder_rights' => 'w',
- ));
- }
-
- // #1486114, #1488279, #1489219
- $onchange = "if ($(this).val() == 'INBOX') $(this).val('')";
-
- if (!isset($no_override['drafts_mbox'])) {
- if (!$current) {
- continue 2;
- }
-
- $blocks['main']['options']['drafts_mbox'] = array(
- 'title' => Q(rcube_label('drafts')),
- 'content' => $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox", 'onchange' => $onchange)),
- );
- }
-
- if (!isset($no_override['sent_mbox'])) {
- if (!$current) {
- continue 2;
- }
-
- $blocks['main']['options']['sent_mbox'] = array(
- 'title' => Q(rcube_label('sent')),
- 'content' => $select->show($config['sent_mbox'], array('name' => "_sent_mbox", 'onchange' => '')),
- );
- }
-
- if (!isset($no_override['junk_mbox'])) {
- if (!$current) {
- continue 2;
- }
-
- $blocks['main']['options']['junk_mbox'] = array(
- 'title' => Q(rcube_label('junk')),
- 'content' => $select->show($config['junk_mbox'], array('name' => "_junk_mbox", 'onchange' => $onchange)),
- );
- }
-
- if (!isset($no_override['trash_mbox'])) {
- if (!$current) {
- continue 2;
- }
-
- $blocks['main']['options']['trash_mbox'] = array(
- 'title' => Q(rcube_label('trash')),
- 'content' => $select->show($config['trash_mbox'], array('name' => "_trash_mbox", 'onchange' => $onchange)),
- );
- }
- break;
-
- // Server settings
- case 'server':
- $blocks = array(
- 'main' => array('name' => Q(rcube_label('mainoptions'))),
- 'maintenance' => array('name' => Q(rcube_label('maintenance'))),
- );
-
- if (!isset($no_override['read_when_deleted'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_read_deleted';
- $input = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['read_when_deleted'] = array(
- 'title' => html::label($field_id, Q(rcube_label('readwhendeleted'))),
- 'content' => $input->show($config['read_when_deleted']?1:0),
- );
- }
-
- if (!isset($no_override['flag_for_deletion'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_flag_for_deletion';
- $input = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['flag_for_deletion'] = array(
- 'title' => html::label($field_id, Q(rcube_label('flagfordeletion'))),
- 'content' => $input->show($config['flag_for_deletion']?1:0),
- );
- }
-
- // don't show deleted messages
- if (!isset($no_override['skip_deleted'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_skip_deleted';
- $input = new html_checkbox(array('name' => '_skip_deleted', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['skip_deleted'] = array(
- 'title' => html::label($field_id, Q(rcube_label('skipdeleted'))),
- 'content' => $input->show($config['skip_deleted']?1:0),
- );
- }
-
- if (!isset($no_override['delete_always'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_delete_always';
- $input = new html_checkbox(array('name' => '_delete_always', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['delete_always'] = array(
- 'title' => html::label($field_id, Q(rcube_label('deletealways'))),
- 'content' => $input->show($config['delete_always']?1:0),
- );
- }
-
- if (!isset($no_override['delete_junk'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_delete_junk';
- $input = new html_checkbox(array('name' => '_delete_junk', 'id' => $field_id, 'value' => 1));
-
- $blocks['main']['options']['delete_junk'] = array(
- 'title' => html::label($field_id, Q(rcube_label('deletejunk'))),
- 'content' => $input->show($config['delete_junk']?1:0),
- );
- }
-
- // Trash purging on logout
- if (!isset($no_override['logout_purge'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_logout_purge';
- $input = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1));
-
- $blocks['maintenance']['options']['logout_purge'] = array(
- 'title' => html::label($field_id, Q(rcube_label('logoutclear'))),
- 'content' => $input->show($config['logout_purge']?1:0),
- );
- }
-
- // INBOX compacting on logout
- if (!isset($no_override['logout_expunge'])) {
- if (!$current) {
- continue 2;
- }
-
- $field_id = 'rcmfd_logout_expunge';
- $input = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1));
-
- $blocks['maintenance']['options']['logout_expunge'] = array(
- 'title' => html::label($field_id, Q(rcube_label('logoutcompact'))),
- 'content' => $input->show($config['logout_expunge']?1:0),
- );
- }
+ $blocks['main']['options']['prettydate'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('prettydate'))),
+ 'content' => $input_prettydate->show($config['prettydate']?1:0),
+ );
+ }
+
+ if (!isset($no_override['refresh_interval'])) {
+ $field_id = 'rcmfd_refresh_interval';
+ $select_refresh_interval = new html_select(array('name' => '_refresh_interval', 'id' => $field_id));
+
+ $select_refresh_interval->add(rcube_label('never'), 0);
+ foreach (array(1, 3, 5, 10, 15, 30, 60) as $min) {
+ if (!$config['min_refresh_interval'] || $config['min_refresh_interval'] <= $min * 60) {
+ $label = rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min)));
+ $select_refresh_interval->add($label, $min);
}
+ }
- $found = false;
- $data = $RCMAIL->plugins->exec_hook('preferences_list',
- array('section' => $sect['id'], 'blocks' => $blocks, 'current' => $current));
+ $blocks['main']['options']['refresh_interval'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('refreshinterval'))),
+ 'content' => $select_refresh_interval->show($config['refresh_interval']/60),
+ );
+ }
- // create output
- foreach ($data['blocks'] as $block) {
- if (!empty($block['content']) || !empty($block['options'])) {
- $found = true;
- break;
- }
+ // show drop-down for available skins
+ if (!isset($no_override['skin'])) {
+ $skins = rcmail_get_skins();
+
+ if (count($skins) > 1) {
+ $field_id = 'rcmfd_skin';
+ $input_skin = new html_radiobutton(array('name'=>'_skin'));
+
+ $blocks['skin'] = array('name' => Q(rcube_label('skin')),);
+
+ foreach($skins as $skin) {
+ $thumbnail = "./skins/$skin/thumbnail.png";
+ if (!is_file($thumbnail))
+ $thumbnail = './program/resources/blank.gif';
+
+ $skinname = ucfirst($skin);
+ $author_link = $license_link = '';
+ $meta = @json_decode(@file_get_contents("./skins/$skin/meta.json"), true);
+ if (is_array($meta) && $meta['name']) {
+ $skinname = $meta['name'];
+ $author_link = $meta['url'] ? html::a(array('href' => $meta['url'], 'target' => '_blank'), Q($meta['author'])) : Q($meta['author']);
+ $license_link = $meta['license-url'] ? html::a(array('href' => $meta['license-url'], 'target' => '_blank'), Q($meta['license'])) : Q($meta['license']);
+ }
+
+ $blocks['skin']['options'][$skin]['content'] = html::label(array('class' => 'skinselection'),
+ html::span('skinitem', $input_skin->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))) .
+ html::span('skinitem', html::span('skinname', Q($skinname)) . html::br() .
+ html::span('skinauthor', $author_link ? 'by ' . $author_link : '') . html::br() .
+ html::span('skinlicense', $license_link ? rcube_label('license').':&nbsp;' . $license_link : ''))
+ );
}
+ }
+ }
- if (!$found)
- unset($sections[$idx]);
- else
- $sections[$idx]['blocks'] = $data['blocks'];
+ $product_name = $RCMAIL->config->get('product_name', 'Roundcube Webmail');
+ $RCMAIL->output->add_script(sprintf("%s.check_protocol_handler('%s', '#mailtoprotohandler');",
+ JS_OBJECT_NAME, JQ($product_name)), 'foot');
+
+ $blocks['browser'] = array(
+ 'name' => Q(rcube_label('browseroptions')),
+ 'options' => array('mailtoprotohandler' => array(
+ 'content' => html::a(array(
+ 'href' => '#',
+ 'id' => 'mailtoprotohandler'), Q(rcube_label('mailtoprotohandler'))),
+ )),
+ );
+
+ break;
+
+ // Mailbox view (mail screen)
+ case 'mailbox':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ 'new_message' => array('name' => Q(rcube_label('newmessage'))),
+ );
+
+ // show config parameter for preview pane
+ if (!isset($no_override['preview_pane'])) {
+ $field_id = 'rcmfd_preview';
+ $input_preview = new html_checkbox(array('name' => '_preview_pane', 'id' => $field_id, 'value' => 1,
+ 'onchange' => "$('#rcmfd_preview_pane_mark_read').prop('disabled', !this.checked)"));
+
+ $blocks['main']['options']['preview_pane'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('previewpane'))),
+ 'content' => $input_preview->show($config['preview_pane']?1:0),
+ );
}
- return array($sections, $plugin['cols']);
-}
+ // show config parameter for preview pane auto mark as read delay
+ if (!isset($no_override['preview_pane_mark_read'])) {
+ // apply default if config option is not set at all
+ $config['preview_pane_mark_read'] = $RCMAIL->config->get('preview_pane_mark_read', 0);
+ $field_id = 'rcmfd_preview_pane_mark_read';
+ $select_delay = new html_select(array('name' => '_preview_pane_mark_read', 'id' => $field_id,
+ 'disabled' => $config['preview_pane']?0:1));
-function rcmail_get_skins()
-{
- $path = RCUBE_INSTALL_PATH . 'skins';
- $skins = array();
- $dir = opendir($path);
+ $select_delay->add(rcube_label('never'), '-1');
+ $select_delay->add(rcube_label('immediately'), 0);
+ foreach(array(5, 10, 20, 30) as $sec)
+ $select_delay->add(rcube_label(array('name' => 'afternseconds', 'vars' => array('n' => $sec))), $sec);
+
+ $blocks['main']['options']['preview_pane_mark_read'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('previewpanemarkread'))),
+ 'content' => $select_delay->show(intval($config['preview_pane_mark_read'])),
+ );
+ }
+
+ if (!isset($no_override['mdn_requests'])) {
+ $field_id = 'rcmfd_mdn_requests';
+ $select_mdn_requests = new html_select(array('name' => '_mdn_requests', 'id' => $field_id));
+ $select_mdn_requests->add(rcube_label('askuser'), 0);
+ $select_mdn_requests->add(rcube_label('autosend'), 1);
+ $select_mdn_requests->add(rcube_label('autosendknown'), 3);
+ $select_mdn_requests->add(rcube_label('autosendknownignore'), 4);
+ $select_mdn_requests->add(rcube_label('ignore'), 2);
+
+ $blocks['main']['options']['mdn_requests'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('mdnrequests'))),
+ 'content' => $select_mdn_requests->show($config['mdn_requests']),
+ );
+ }
+
+ $storage = $RCMAIL->get_storage();
+ $threading_supported = $storage->get_capability('THREAD');
+
+ if (!isset($no_override['autoexpand_threads']) && $threading_supported) {
+ $field_id = 'rcmfd_autoexpand_threads';
+ $select_autoexpand_threads = new html_select(array('name' => '_autoexpand_threads', 'id' => $field_id));
+ $select_autoexpand_threads->add(rcube_label('never'), 0);
+ $select_autoexpand_threads->add(rcube_label('do_expand'), 1);
+ $select_autoexpand_threads->add(rcube_label('expand_only_unread'), 2);
+
+ $blocks['main']['options']['autoexpand_threads'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('autoexpand_threads'))),
+ 'content' => $select_autoexpand_threads->show($config['autoexpand_threads']),
+ );
+ }
+
+ // show page size selection
+ if (!isset($no_override['mail_pagesize'])) {
+ $field_id = 'rcmfd_mail_pagesize';
+ $input_pagesize = new html_inputfield(array('name' => '_mail_pagesize', 'id' => $field_id, 'size' => 5));
+
+ $size = intval($config['mail_pagesize'] ? $config['mail_pagesize'] : $config['pagesize']);
+
+ $blocks['main']['options']['pagesize'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('pagesize'))),
+ 'content' => $input_pagesize->show($size ? $size : 50),
+ );
+ }
+ if (!isset($no_override['check_all_folders'])) {
+ $field_id = 'rcmfd_check_all_folders';
+ $input_check_all = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1));
+
+ $blocks['new_message']['options']['check_all_folders'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('checkallfolders'))),
+ 'content' => $input_check_all->show($config['check_all_folders']?1:0),
+ );
+ }
+
+ break;
+
+ // Message viewing
+ case 'mailview':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ );
+
+ // show checkbox to open message view in new window
+ if (!isset($no_override['message_extwin'])) {
+ $field_id = 'rcmfd_message_extwin';
+ $input_msgextwin = new html_checkbox(array('name' => '_message_extwin', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['message_extwin'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('showinextwin'))),
+ 'content' => $input_msgextwin->show($config['message_extwin']?1:0),
+ );
+ }
+
+ // show checkbox for HTML/plaintext messages
+ if (!isset($no_override['prefer_html'])) {
+ $field_id = 'rcmfd_htmlmsg';
+ $input_preferhtml = new html_checkbox(array('name' => '_prefer_html', 'id' => $field_id, 'value' => 1,
+ 'onchange' => "$('#rcmfd_show_images').prop('disabled', !this.checked).val(0)"));
+
+ $blocks['main']['options']['prefer_html'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('preferhtml'))),
+ 'content' => $input_preferhtml->show($config['prefer_html']?1:0),
+ );
+ }
+
+ if (!isset($no_override['default_charset'])) {
+ $field_id = 'rcmfd_default_charset';
+
+ $blocks['main']['options']['default_charset'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('defaultcharset'))),
+ 'content' => $RCMAIL->output->charset_selector(array(
+ 'name' => '_default_charset', 'selected' => $config['default_charset']
+ ))
+ );
+ }
+
+ if (!isset($no_override['show_images'])) {
+ $field_id = 'rcmfd_show_images';
+ $input_show_images = new html_select(array('name' => '_show_images', 'id' => $field_id,
+ 'disabled' => !$config['prefer_html']));
+ $input_show_images->add(rcube_label('never'), 0);
+ $input_show_images->add(rcube_label('fromknownsenders'), 1);
+ $input_show_images->add(rcube_label('always'), 2);
+
+ $blocks['main']['options']['show_images'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('showremoteimages'))),
+ 'content' => $input_show_images->show($config['prefer_html'] ? $config['show_images'] : 0),
+ );
+ }
+
+ if (!isset($no_override['inline_images'])) {
+ $field_id = 'rcmfd_inline_images';
+ $input_inline_images = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['inline_images'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('showinlineimages'))),
+ 'content' => $input_inline_images->show($config['inline_images']?1:0),
+ );
+ }
+
+ // "display after delete" checkbox
+ if (!isset($no_override['display_next'])) {
+ $field_id = 'rcmfd_displaynext';
+ $input_displaynext = new html_checkbox(array('name' => '_display_next', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['display_next'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('displaynext'))),
+ 'content' => $input_displaynext->show($config['display_next']?1:0),
+ );
+ }
+
+ break;
+
+ // Mail composition
+ case 'compose':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ 'sig' => array('name' => Q(rcube_label('signatureoptions'))),
+ 'spellcheck' => array('name' => Q(rcube_label('spellcheckoptions'))),
+ );
+
+ // show checkbox to compose messages in a new window
+ if (!isset($no_override['compose_extwin'])) {
+ $field_id = 'rcmfdcompose_extwin';
+ $input_compextwin = new html_checkbox(array('name' => '_compose_extwin', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['compose_extwin'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('composeextwin'))),
+ 'content' => $input_compextwin->show($config['compose_extwin']?1:0),
+ );
+ }
+
+ if (!isset($no_override['htmleditor'])) {
+ $field_id = 'rcmfd_htmleditor';
+ $select_htmleditor = new html_select(array('name' => '_htmleditor', 'id' => $field_id));
+ $select_htmleditor->add(rcube_label('never'), 0);
+ $select_htmleditor->add(rcube_label('always'), 1);
+ $select_htmleditor->add(rcube_label('htmlonreply'), 2);
+ $select_htmleditor->add(rcube_label('htmlonreplyandforward'), 3);
+
+ $blocks['main']['options']['htmleditor'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('htmleditor'))),
+ 'content' => $select_htmleditor->show(intval($config['htmleditor'])),
+ );
+ }
+
+ if (!isset($no_override['draft_autosave'])) {
+ $field_id = 'rcmfd_autosave';
+ $select_autosave = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox'])));
+ $select_autosave->add(rcube_label('never'), 0);
+ foreach (array(1, 3, 5, 10) as $i => $min)
+ $select_autosave->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min*60);
+
+ $blocks['main']['options']['draft_autosave'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('autosavedraft'))),
+ 'content' => $select_autosave->show($config['draft_autosave']),
+ );
+ }
+
+ if (!isset($no_override['mime_param_folding'])) {
+ $field_id = 'rcmfd_param_folding';
+ $select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id));
+ $select_param_folding->add(rcube_label('2231folding'), 0);
+ $select_param_folding->add(rcube_label('miscfolding'), 1);
+ $select_param_folding->add(rcube_label('2047folding'), 2);
+
+ $blocks['main']['options']['mime_param_folding'] = array(
+ 'advanced' => true,
+ 'title' => html::label($field_id, Q(rcube_label('mimeparamfolding'))),
+ 'content' => $select_param_folding->show($config['mime_param_folding']),
+ );
+ }
+
+ if (!isset($no_override['force_7bit'])) {
+ $field_id = 'rcmfd_force_7bit';
+ $input_7bit = new html_checkbox(array('name' => '_force_7bit', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['force_7bit'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('force7bit'))),
+ 'content' => $input_7bit->show($config['force_7bit']?1:0),
+ );
+ }
+
+ if (!isset($no_override['mdn_default'])) {
+ $field_id = 'rcmfd_mdn_default';
+ $input_mdn = new html_checkbox(array('name' => '_mdn_default', 'id' => $field_id, 'value' => 1));
- if (!$dir) {
- return false;
+ $blocks['main']['options']['mdn_default'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('reqmdn'))),
+ 'content' => $input_mdn->show($config['mdn_default']?1:0),
+ );
}
- while (($file = readdir($dir)) !== false) {
- $filename = $path.'/'.$file;
- if (!preg_match('/^\./', $file) && is_dir($filename) && is_readable($filename)) {
- $skins[] = $file;
+ if (!isset($no_override['dsn_default'])) {
+ $field_id = 'rcmfd_dsn_default';
+ $input_dsn = new html_checkbox(array('name' => '_dsn_default', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['dsn_default'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('reqdsn'))),
+ 'content' => $input_dsn->show($config['dsn_default']?1:0),
+ );
+ }
+
+ if (!isset($no_override['reply_same_folder'])) {
+ $field_id = 'rcmfd_reply_same_folder';
+ $input_reply_same_folder = new html_checkbox(array('name' => '_reply_same_folder', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['reply_same_folder'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('replysamefolder'))),
+ 'content' => $input_reply_same_folder->show($config['reply_same_folder']?1:0),
+ );
+ }
+
+ if (!isset($no_override['reply_mode'])) {
+ $field_id = 'rcmfd_reply_mode';
+ $select_replymode = new html_select(array('name' => '_reply_mode', 'id' => $field_id));
+ $select_replymode->add(rcube_label('replyempty'), -1);
+ $select_replymode->add(rcube_label('replybottomposting'), 0);
+ $select_replymode->add(rcube_label('replytopposting'), 1);
+
+ $blocks['main']['options']['reply_mode'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('whenreplying'))),
+ 'content' => $select_replymode->show(intval($config['reply_mode'])),
+ );
+ }
+
+ if (!isset($no_override['spellcheck_before_send']) && $config['enable_spellcheck']) {
+ $field_id = 'rcmfd_spellcheck_before_send';
+ $input_spellcheck = new html_checkbox(array('name' => '_spellcheck_before_send', 'id' => $field_id, 'value' => 1));
+
+ $blocks['spellcheck']['options']['spellcheck_before_send'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('spellcheckbeforesend'))),
+ 'content' => $input_spellcheck->show($config['spellcheck_before_send']?1:0),
+ );
+ }
+
+ if ($config['enable_spellcheck']) {
+ foreach (array('syms', 'nums', 'caps') as $key) {
+ $key = 'spellcheck_ignore_'.$key;
+ if (!isset($no_override[$key])) {
+ $input_spellcheck = new html_checkbox(array('name' => '_'.$key, 'id' => 'rcmfd_'.$key, 'value' => 1));
+
+ $blocks['spellcheck']['options'][$key] = array(
+ 'title' => html::label($field_id, Q(rcube_label(str_replace('_', '', $key)))),
+ 'content' => $input_spellcheck->show($config[$key]?1:0),
+ );
}
+ }
+ }
+
+ if (!isset($no_override['show_sig'])) {
+ $field_id = 'rcmfd_show_sig';
+ $select_show_sig = new html_select(array('name' => '_show_sig', 'id' => $field_id));
+ $select_show_sig->add(rcube_label('never'), 0);
+ $select_show_sig->add(rcube_label('always'), 1);
+ $select_show_sig->add(rcube_label('newmessageonly'), 2);
+ $select_show_sig->add(rcube_label('replyandforwardonly'), 3);
+
+ $blocks['sig']['options']['show_sig'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('autoaddsignature'))),
+ 'content' => $select_show_sig->show($RCMAIL->config->get('show_sig', 1)),
+ );
+ }
+
+ if (!isset($no_override['strip_existing_sig'])) {
+ $field_id = 'rcmfd_strip_existing_sig';
+ $input_stripexistingsig = new html_checkbox(array('name' => '_strip_existing_sig', 'id' => $field_id, 'value' => 1));
+
+ $blocks['sig']['options']['strip_existing_sig'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('replyremovesignature'))),
+ 'content' => $input_stripexistingsig->show($config['strip_existing_sig']?1:0),
+ );
+ }
+
+ if (!isset($no_override['forward_attachment'])) {
+ $field_id = 'rcmfd_forward_attachment';
+ $select = new html_select(array('name' => '_forward_attachment', 'id' => $field_id));
+ $select->add(rcube_label('inline'), 0);
+ $select->add(rcube_label('asattachment'), 1);
+
+ $blocks['main']['options']['forward_attachment'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('forwardmode'))),
+ 'content' => $select->show(intval($config['forward_attachment'])),
+ );
+ }
+
+ if (!isset($no_override['default_font'])) {
+ $field_id = 'rcmfd_default_font';
+ $fonts = rcube_fontdefs();
+ $selected = $config['default_font'];
+
+ $select = '<select name="_default_font" id="'.$field_id.'">';
+ $select .= '<option value=""' . (!$selected ? ' selected="selected"' : '') . '>---</option>';
+ foreach ($fonts as $fname => $font)
+ $select .= '<option value="'.$fname.'"'
+ . ($fname == $selected ? ' selected="selected"' : '')
+ . ' style=\'font-family: ' . $font . '\'>'
+ . Q($fname) . '</option>';
+ $select .= '</select>';
+
+ $blocks['main']['options']['default_font'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('defaultfont'))),
+ 'content' => $select
+ );
+ }
+
+ break;
+
+
+ // Addressbook config
+ case 'addressbook':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ );
+
+ if (!isset($no_override['default_addressbook'])
+ && ($books = $RCMAIL->get_address_sources(true, true))
+ ) {
+ $field_id = 'rcmfd_default_addressbook';
+ $select_abook = new html_select(array('name' => '_default_addressbook', 'id' => $field_id));
+
+ foreach ($books as $book) {
+ $select_abook->add(html_entity_decode($book['name'], ENT_COMPAT, 'UTF-8'), $book['id']);
+ }
+
+ $blocks['main']['options']['default_addressbook'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('defaultabook'))),
+ 'content' => $select_abook->show($config['default_addressbook']),
+ );
+ }
+
+ // show addressbook listing mode selection
+ if (!isset($no_override['addressbook_name_listing'])) {
+ $field_id = 'rcmfd_addressbook_name_listing';
+ $select_listing = new html_select(array('name' => '_addressbook_name_listing', 'id' => $field_id));
+ $select_listing->add(rcube_label('name'), 0);
+ $select_listing->add(rcube_label('firstname') . ' ' . rcube_label('surname'), 1);
+ $select_listing->add(rcube_label('surname') . ' ' . rcube_label('firstname'), 2);
+ $select_listing->add(rcube_label('surname') . ', ' . rcube_label('firstname'), 3);
+
+ $blocks['main']['options']['list_name_listing'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('listnamedisplay'))),
+ 'content' => $select_listing->show($config['addressbook_name_listing']),
+ );
}
- closedir($dir);
+ // show addressbook sort column
+ if (!isset($no_override['addressbook_sort_col'])) {
+ $field_id = 'rcmfd_addressbook_sort_col';
+ $select_sort = new html_select(array('name' => '_addressbook_sort_col', 'id' => $field_id));
+ $select_sort->add(rcube_label('name'), 'name');
+ $select_sort->add(rcube_label('firstname'), 'firstname');
+ $select_sort->add(rcube_label('surname'), 'surname');
+
+ $blocks['main']['options']['sort_col'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('listsorting'))),
+ 'content' => $select_sort->show($config['addressbook_sort_col']),
+ );
+ }
+
+ // show addressbook page size selection
+ if (!isset($no_override['addressbook_pagesize'])) {
+ $field_id = 'rcmfd_addressbook_pagesize';
+ $input_pagesize = new html_inputfield(array('name' => '_addressbook_pagesize', 'id' => $field_id, 'size' => 5));
+
+ $size = intval($config['addressbook_pagesize'] ? $config['addressbook_pagesize'] : $config['pagesize']);
+
+ $blocks['main']['options']['pagesize'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('pagesize'))),
+ 'content' => $input_pagesize->show($size ? $size : 50),
+ );
+ }
+
+ if (!isset($no_override['autocomplete_single'])) {
+ $field_id = 'rcmfd_autocomplete_single';
+ $checkbox = new html_checkbox(array('name' => '_autocomplete_single', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['autocomplete_single'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('autocompletesingle'))),
+ 'content' => $checkbox->show($config['autocomplete_single']?1:0),
+ );
+ }
+
+ break;
+
+ // Special IMAP folders
+ case 'folders':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ );
+
+ // Configure special folders
+ if (!isset($no_override['default_folders'])) {
+ // load folders list only when needed
+ if ($current) {
+ $select = rcmail_mailbox_select(array(
+ 'noselection' => '---',
+ 'realnames' => true,
+ 'maxlength' => 30,
+ 'folder_filter' => 'mail',
+ 'folder_rights' => 'w',
+ // #1486114, #1488279
+ 'onchange' => "if ($(this).val() == 'INBOX') $(this).val('')",
+ ));
+ }
+ else // dummy select
+ $select = new html_select();
+
+ if (!isset($no_override['drafts_mbox']))
+ $blocks['main']['options']['drafts_mbox'] = array(
+ 'title' => Q(rcube_label('drafts')),
+ 'content' => $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox")),
+ );
+
+ if (!isset($no_override['sent_mbox']))
+ $blocks['main']['options']['sent_mbox'] = array(
+ 'title' => Q(rcube_label('sent')),
+ 'content' => $select->show($config['sent_mbox'], array('name' => "_sent_mbox")),
+ );
+
+ if (!isset($no_override['junk_mbox']))
+ $blocks['main']['options']['junk_mbox'] = array(
+ 'title' => Q(rcube_label('junk')),
+ 'content' => $select->show($config['junk_mbox'], array('name' => "_junk_mbox")),
+ );
+
+ if (!isset($no_override['trash_mbox']))
+ $blocks['main']['options']['trash_mbox'] = array(
+ 'title' => Q(rcube_label('trash')),
+ 'content' => $select->show($config['trash_mbox'], array('name' => "_trash_mbox")),
+ );
+ }
+
+ break;
+
+ // Server settings
+ case 'server':
+
+ $blocks = array(
+ 'main' => array('name' => Q(rcube_label('mainoptions'))),
+ 'maintenance' => array('name' => Q(rcube_label('maintenance'))),
+ );
+
+ if (!isset($no_override['read_when_deleted'])) {
+ $field_id = 'rcmfd_read_deleted';
+ $input_readdeleted = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['read_when_deleted'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('readwhendeleted'))),
+ 'content' => $input_readdeleted->show($config['read_when_deleted']?1:0),
+ );
+ }
+
+ if (!isset($no_override['flag_for_deletion'])) {
+ $field_id = 'rcmfd_flag_for_deletion';
+ $input_flagfordeletion = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['flag_for_deletion'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('flagfordeletion'))),
+ 'content' => $input_flagfordeletion->show($config['flag_for_deletion']?1:0),
+ );
+ }
+
+ // don't show deleted messages
+ if (!isset($no_override['skip_deleted'])) {
+ $field_id = 'rcmfd_skip_deleted';
+ $input_purge = new html_checkbox(array('name' => '_skip_deleted', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['skip_deleted'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('skipdeleted'))),
+ 'content' => $input_purge->show($config['skip_deleted']?1:0),
+ );
+ }
+
+ if (!isset($no_override['delete_always'])) {
+ $field_id = 'rcmfd_delete_always';
+ $input_delete_always = new html_checkbox(array('name' => '_delete_always', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['delete_always'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('deletealways'))),
+ 'content' => $input_delete_always->show($config['delete_always']?1:0),
+ );
+ }
+
+ if (!isset($no_override['delete_junk'])) {
+ $field_id = 'rcmfd_delete_junk';
+ $input_delete_junk = new html_checkbox(array('name' => '_delete_junk', 'id' => $field_id, 'value' => 1));
+
+ $blocks['main']['options']['delete_junk'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('deletejunk'))),
+ 'content' => $input_delete_junk->show($config['delete_junk']?1:0),
+ );
+ }
+
+ // Trash purging on logout
+ if (!isset($no_override['logout_purge'])) {
+ $field_id = 'rcmfd_logout_purge';
+ $input_purge = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1));
+
+ $blocks['maintenance']['options']['logout_purge'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('logoutclear'))),
+ 'content' => $input_purge->show($config['logout_purge']?1:0),
+ );
+ }
+
+ // INBOX compacting on logout
+ if (!isset($no_override['logout_expunge'])) {
+ $field_id = 'rcmfd_logout_expunge';
+ $input_expunge = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1));
+
+ $blocks['maintenance']['options']['logout_expunge'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('logoutcompact'))),
+ 'content' => $input_expunge->show($config['logout_expunge']?1:0),
+ );
+ }
+
+ break;
+ }
+
+ $data = $RCMAIL->plugins->exec_hook('preferences_list', array('section' => $sect['id'], 'blocks' => $blocks));
+ $found = false;
+
+ // create output
+ foreach ($data['blocks'] as $block) {
+ if (!empty($block['content']) || !empty($block['options'])) {
+ $found = true;
+ break;
+ }
+ }
+
+ if (!$found)
+ unset($sections[$idx]);
+ else
+ $sections[$idx]['blocks'] = $data['blocks'];
+ }
+
+ return array($sections, $plugin['cols']);
+}
+
+
+function rcmail_get_skins()
+{
+ $path = 'skins';
+ $skins = array();
+
+ $dir = opendir($path);
+
+ if (!$dir)
+ return false;
+
+ while (($file = readdir($dir)) !== false)
+ {
+ $filename = $path.'/'.$file;
+ if (!preg_match('/^\./', $file) && is_dir($filename) && is_readable($filename))
+ $skins[] = $file;
+ }
+
+ closedir($dir);
- return $skins;
+ return $skins;
}
@@ -1238,9 +977,9 @@ function rcmail_update_folder_row($name, $oldname=null, $subscribe=false, $class
// register UI objects
$OUTPUT->add_handlers(array(
- 'prefsframe' => 'rcmail_preferences_frame',
- 'sectionslist' => 'rcmail_sections_list',
- 'identitieslist' => 'rcmail_identities_list',
+ 'prefsframe' => 'rcmail_preferences_frame',
+ 'sectionslist' => 'rcmail_sections_list',
+ 'identitieslist' => 'rcmail_identities_list',
));
// register action aliases
diff --git a/program/steps/settings/responses.inc b/program/steps/settings/responses.inc
new file mode 100644
index 000000000..cfc4148c3
--- /dev/null
+++ b/program/steps/settings/responses.inc
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/responses.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Manage and save canned response texts |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+
+if (!empty($_POST['_insert'])) {
+ $name = trim(get_input_value('_name', RCUBE_INPUT_POST));
+ $text = trim(get_input_value('_text', RCUBE_INPUT_POST));
+
+ if (!empty($name) && !empty($text)) {
+ $dupes = 0;
+ $responses = $RCMAIL->get_compose_responses(false, true);
+ foreach ($responses as $resp) {
+ if (strcasecmp($name, preg_replace('/\s\(\d+\)$/', '', $resp['name'])) == 0)
+ $dupes++;
+ }
+ if ($dupes) { // require a unique name
+ $name .= ' (' . ++$dupes . ')';
+ }
+
+ $response = array('name' => $name, 'text' => $text, 'format' => 'text', 'key' => substr(md5($name), 0, 16));
+ $responses[] = $response;
+
+ if ($RCMAIL->user->save_prefs(array('compose_responses' => $responses))) {
+ $RCMAIL->output->command('add_response_item', $response);
+ $RCMAIL->output->command('display_message', rcube_label('successfullysaved'), 'confirmation');
+ }
+ else {
+ $RCMAIL->output->command('display_message', rcube_label('errorsaving'), 'error');
+ }
+ }
+
+ // send response
+ $RCMAIL->output->send();
+}
+
+
+if ($RCMAIL->action == 'delete-response') {
+ if ($key = get_input_value('_key', RCUBE_INPUT_GPC)) {
+ $responses = $RCMAIL->get_compose_responses(false, true);
+ foreach ($responses as $i => $response) {
+ if (empty($response['key']))
+ $response['key'] = substr(md5($response['name']), 0, 16);
+ if ($response['key'] == $key) {
+ unset($responses[$i]);
+ $deleted = $RCMAIL->user->save_prefs(array('compose_responses' => $responses));
+ break;
+ }
+ }
+ }
+
+ if ($deleted) {
+ $RCMAIL->output->command('display_message', rcube_label('deletedsuccessfully'), 'confirmation');
+ $RCMAIL->output->command('remove_response', $key);
+ }
+
+ if ($RCMAIL->output->ajax_call) {
+ $RCMAIL->output->send();
+ }
+}
+
+
+$OUTPUT->set_pagetitle(rcube_label('responses'));
+$OUTPUT->include_script('list.js');
+
+
+/**
+ *
+ */
+function rcmail_responses_list($attrib)
+{
+ global $RCMAIL, $OUTPUT;
+
+ $attrib += array('id' => 'rcmresponseslist', 'tagname' => 'table', 'cols' => 1);
+
+ $plugin = $RCMAIL->plugins->exec_hook('responses_list', array(
+ 'list' => $RCMAIL->get_compose_responses(true),
+ 'cols' => array('name')
+ ));
+
+ $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'key');
+
+ // set client env
+ $OUTPUT->add_gui_object('responseslist', $attrib['id']);
+ $OUTPUT->set_env('readonly_responses', array_values(array_map(function($rec){ return $rec['key']; },
+ array_filter($plugin['list'], function($item){ return !empty($item['static']); }))));
+
+ return $out;
+}
+
+
+// similar function as /steps/addressbook/func.inc::rcmail_contact_frame()
+function rcmail_response_frame($attrib)
+{
+ global $OUTPUT;
+
+ if (!$attrib['id']) {
+ $attrib['id'] = 'rcmResponseFrame';
+ }
+
+ $OUTPUT->set_env('contentframe', $attrib['id']);
+ return $OUTPUT->frame($attrib, true);
+}
+
+$OUTPUT->add_handlers(array(
+ 'responseframe' => 'rcmail_response_frame',
+ 'responseslist' => 'rcmail_responses_list',
+));
+$OUTPUT->add_label('deleteresponseconfirm');
+
+$OUTPUT->send('responses');
diff --git a/program/steps/settings/save_prefs.inc b/program/steps/settings/save_prefs.inc
index 3e8b1d17e..945005d39 100644
--- a/program/steps/settings/save_prefs.inc
+++ b/program/steps/settings/save_prefs.inc
@@ -34,7 +34,6 @@ switch ($CURR_SECTION)
'time_format' => isset($_POST['_time_format']) ? get_input_value('_time_format', RCUBE_INPUT_POST) : ($CONFIG['time_format'] ? $CONFIG['time_format'] : 'H:i'),
'prettydate' => isset($_POST['_pretty_date']) ? TRUE : FALSE,
'refresh_interval' => isset($_POST['_refresh_interval']) ? intval($_POST['_refresh_interval'])*60 : $CONFIG['refresh_interval'],
- 'standard_windows' => isset($_POST['_standard_windows']) ? TRUE : FALSE,
'skin' => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'],
);
@@ -61,7 +60,6 @@ switch ($CURR_SECTION)
case 'mailview':
$a_user_prefs = array(
'message_extwin' => intval($_POST['_message_extwin']),
- 'message_show_email' => isset($_POST['_message_show_email']) ? TRUE : FALSE,
'prefer_html' => isset($_POST['_prefer_html']) ? TRUE : FALSE,
'inline_images' => isset($_POST['_inline_images']) ? TRUE : FALSE,
'show_images' => isset($_POST['_show_images']) ? intval($_POST['_show_images']) : 0,
@@ -120,8 +118,6 @@ switch ($CURR_SECTION)
case 'folders':
$a_user_prefs = array(
- 'show_real_foldernames' =>
- isset($_POST['_show_real_foldernames']) ? TRUE : FALSE,
'drafts_mbox' => get_input_value('_drafts_mbox', RCUBE_INPUT_POST, true),
'sent_mbox' => get_input_value('_sent_mbox', RCUBE_INPUT_POST, true),
'junk_mbox' => get_input_value('_junk_mbox', RCUBE_INPUT_POST, true),
diff --git a/program/steps/utils/save_pref.inc b/program/steps/utils/save_pref.inc
index 7def8733d..7c30be71b 100644
--- a/program/steps/utils/save_pref.inc
+++ b/program/steps/utils/save_pref.inc
@@ -5,7 +5,7 @@
| program/steps/utils/save_pref.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2010, The Roundcube Dev Team |
+ | Copyright (C) 2005-2013, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -19,16 +19,26 @@
+-----------------------------------------------------------------------+
*/
-$name = get_input_value('_name', RCUBE_INPUT_POST);
-$value = get_input_value('_value', RCUBE_INPUT_POST);
+$name = get_input_value('_name', RCUBE_INPUT_POST);
+$value = get_input_value('_value', RCUBE_INPUT_POST);
+$sessname = get_input_value('_session', RCUBE_INPUT_POST);
+
+// Whitelisted preferences and session variables, others
+// can be added by plugins
$whitelist = array(
'preview_pane',
'list_cols',
'collapsed_folders',
'collapsed_abooks',
);
+$whitelist_sess = array(
+ 'list_attrib/columns',
+);
+
+$whitelist = array_merge($whitelist, $RCMAIL->plugins->allowed_prefs);
+$whitelist_sess = array_merge($whitelist_sess, $RCMAIL->plugins->allowed_session_prefs);
-if (!in_array($name, array_merge($whitelist, $RCMAIL->plugins->allowed_prefs))) {
+if (!in_array($name, $whitelist) || ($sessname && !in_array($sessname, $whitelist_sess))) {
raise_error(array('code' => 500, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => sprintf("Hack attempt detected (user: %s)", $RCMAIL->get_user_name())),
@@ -42,7 +52,7 @@ if (!in_array($name, array_merge($whitelist, $RCMAIL->plugins->allowed_prefs)))
$RCMAIL->user->save_prefs(array($name => $value));
// update also session if requested
-if ($sessname = get_input_value('_session', RCUBE_INPUT_POST)) {
+if ($sessname) {
// Support multidimensional arrays...
$vars = explode('/', $sessname);
@@ -57,5 +67,3 @@ if ($sessname = get_input_value('_session', RCUBE_INPUT_POST)) {
$OUTPUT->reset();
$OUTPUT->send();
-
-
diff --git a/program/steps/utils/spell.inc b/program/steps/utils/spell.inc
index 1c68e8328..a0dd35d27 100644
--- a/program/steps/utils/spell.inc
+++ b/program/steps/utils/spell.inc
@@ -42,13 +42,6 @@ else {
$result = $spellchecker->get_xml();
}
-if ($err = $spellchecker->error()) {
- rcube::raise_error(array('code' => 500, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Spell check engine error: " . trim($err)),
- true, false);
-}
-
// set response length
header("Content-Length: " . strlen($result));
diff --git a/program/steps/utils/spell_html.inc b/program/steps/utils/spell_html.inc
index 96b41e230..861e4ba48 100644
--- a/program/steps/utils/spell_html.inc
+++ b/program/steps/utils/spell_html.inc
@@ -46,11 +46,6 @@ else if ($request['method'] == 'learnWord') {
}
if ($error = $spellchecker->error()) {
- rcube::raise_error(array('code' => 500, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => sprintf("Spell check engine error: " . $error)),
- true, false);
-
echo '{"error":{"errstr":"' . addslashes($error) . '","errfile":"","errline":null,"errcontext":"","level":"FATAL"}}';
exit;
}