summaryrefslogtreecommitdiff
path: root/webmail/program/steps/settings
diff options
context:
space:
mode:
Diffstat (limited to 'webmail/program/steps/settings')
-rw-r--r--webmail/program/steps/settings/about.inc129
-rw-r--r--webmail/program/steps/settings/delete_identity.inc51
-rw-r--r--webmail/program/steps/settings/edit_folder.inc311
-rw-r--r--webmail/program/steps/settings/edit_identity.inc174
-rw-r--r--webmail/program/steps/settings/edit_prefs.inc86
-rw-r--r--webmail/program/steps/settings/folders.inc440
-rw-r--r--webmail/program/steps/settings/func.inc995
-rw-r--r--webmail/program/steps/settings/identities.inc43
-rw-r--r--webmail/program/steps/settings/save_folder.inc202
-rw-r--r--webmail/program/steps/settings/save_identity.inc215
-rw-r--r--webmail/program/steps/settings/save_prefs.inc219
11 files changed, 2865 insertions, 0 deletions
diff --git a/webmail/program/steps/settings/about.inc b/webmail/program/steps/settings/about.inc
new file mode 100644
index 0000000..9b13402
--- /dev/null
+++ b/webmail/program/steps/settings/about.inc
@@ -0,0 +1,129 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/about.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2011, The Roundcube Dev Team |
+ | Copyright (C) 2011, Kolab Systems AG |
+ | |
+ | 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 license information about program and enabled plugins |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+
+function rcmail_supportlink($attrib)
+{
+ global $RCMAIL;
+
+ if ($url = $RCMAIL->config->get('support_url')) {
+ $label = $attrib['label'] ? $attrib['label'] : 'support';
+ $attrib['href'] = $url;
+ return html::a($attrib, rcube_label($label));
+ }
+}
+
+function rcmail_plugins_list($attrib)
+{
+ global $RCMAIL;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmpluginlist';
+
+ $plugins = array_filter((array) $RCMAIL->config->get('plugins'));
+ $plugins = array_flip($plugins);
+
+ foreach ($plugins as $name => $plugin) {
+ rcube_plugin_data($name, $plugins);
+ }
+
+ if (empty($plugins)) {
+ return '';
+ }
+
+ ksort($plugins, SORT_LOCALE_STRING);
+
+ $table = new html_table($attrib);
+
+ // add table header
+ $table->add_header('name', rcube_label('plugin'));
+ $table->add_header('version', rcube_label('version'));
+ $table->add_header('license', rcube_label('license'));
+ $table->add_header('source', rcube_label('source'));
+
+ foreach ($plugins as $name => $data) {
+ $uri = $data['srcuri'] ? $data['srcuri'] : $data['uri'];
+ if ($uri && stripos($uri, 'http') !== 0) {
+ $uri = 'http://' . $uri;
+ }
+
+ $table->add_row();
+ $table->add('name', Q($data['name'] ? $data['name'] : $name));
+ $table->add('version', Q($data['version']));
+ $table->add('license', $data['license_uri'] ? html::a(array('target' => '_blank', href=> Q($data['license_uri'])),
+ Q($data['license'])) : $data['license']);
+ $table->add('source', $uri ? html::a(array('target' => '_blank', href=> Q($uri)),
+ Q(rcube_label('download'))) : '');
+ }
+
+ 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'));
+
+$OUTPUT->add_handler('supportlink', 'rcmail_supportlink');
+$OUTPUT->add_handler('pluginlist', 'rcmail_plugins_list');
+
+$OUTPUT->send('about');
diff --git a/webmail/program/steps/settings/delete_identity.inc b/webmail/program/steps/settings/delete_identity.inc
new file mode 100644
index 0000000..d5146db
--- /dev/null
+++ b/webmail/program/steps/settings/delete_identity.inc
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/delete_identity.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: |
+ | Delete the submitted identities (IIDs) from the database |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+$iid = get_input_value('_iid', RCUBE_INPUT_GPC);
+
+// check request token
+if (!$OUTPUT->ajax_call && !$RCMAIL->check_request(RCUBE_INPUT_GPC)) {
+ $OUTPUT->show_message('invalidrequest', 'error');
+ rcmail_overwrite_action('identities');
+ return;
+}
+
+if ($iid && preg_match('/^[0-9]+(,[0-9]+)*$/', $iid))
+{
+ $plugin = $RCMAIL->plugins->exec_hook('identity_delete', array('id' => $iid));
+
+ $deleted = !$plugin['abort'] ? $RCMAIL->user->delete_identity($iid) : $plugin['result'];
+
+ if ($deleted > 0 && $deleted !== false)
+ $OUTPUT->show_message('deletedsuccessfully', 'confirmation', null, false);
+ else
+ $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : ($deleted < 0 ? 'nodeletelastidentity' : 'errorsaving'), 'error', null, false);
+
+ // send response
+ if ($OUTPUT->ajax_call)
+ $OUTPUT->send();
+}
+
+if ($OUTPUT->ajax_call)
+ exit;
+
+// go to identities page
+rcmail_overwrite_action('identities');
diff --git a/webmail/program/steps/settings/edit_folder.inc b/webmail/program/steps/settings/edit_folder.inc
new file mode 100644
index 0000000..fdb38e6
--- /dev/null
+++ b/webmail/program/steps/settings/edit_folder.inc
@@ -0,0 +1,311 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/edit_folder.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: |
+ | Provide functionality to create/edit a folder |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+// WARNING: folder names in UI are encoded with RCMAIL_CHARSET
+
+function rcmail_folder_form($attrib)
+{
+ global $RCMAIL;
+
+ $storage = $RCMAIL->get_storage();
+
+ // edited folder name (empty in create-folder mode)
+ $mbox = trim(get_input_value('_mbox', RCUBE_INPUT_GPC, true));
+ $mbox_imap = rcube_charset_convert($mbox, RCMAIL_CHARSET, 'UTF7-IMAP');
+
+ // predefined path for new folder
+ $parent = trim(get_input_value('_path', RCUBE_INPUT_GPC, true));
+ $parent_imap = rcube_charset_convert($parent, RCMAIL_CHARSET, 'UTF7-IMAP');
+
+ $threading_supported = $storage->get_capability('THREAD');
+ $delimiter = $storage->get_hierarchy_delimiter();
+
+ // Get mailbox parameters
+ if (strlen($mbox)) {
+ $options = rcmail_folder_options($mbox_imap);
+ $namespace = $storage->get_namespace();
+
+ $path = explode($delimiter, $mbox_imap);
+ $folder = array_pop($path);
+ $path = implode($delimiter, $path);
+ $folder = rcube_charset_convert($folder, 'UTF7-IMAP');
+
+ $hidden_fields = array('name' => '_mbox', 'value' => $mbox);
+ }
+ else {
+ $options = array();
+ $path = $parent_imap;
+
+ // allow creating subfolders of INBOX folder
+ if ($path == 'INBOX') {
+ $path = $storage->mod_folder($path, 'in');
+ }
+ }
+
+ // remove personal namespace prefix
+ if (strlen($path)) {
+ $path_id = $path;
+ $path = $storage->mod_folder($path.$delimiter);
+ if ($path[strlen($path)-1] == $delimiter) {
+ $path = substr($path, 0, -1);
+ }
+ }
+
+ $form = array();
+
+ // General tab
+ $form['props'] = array(
+ 'name' => rcube_label('properties'),
+ );
+
+ // Location (name)
+ if ($options['protected']) {
+ $foldername = str_replace($delimiter, ' &raquo; ', Q(rcmail_localize_folderpath($mbox_imap)));
+ }
+ else if ($options['norename']) {
+ $foldername = Q($folder);
+ }
+ else {
+ if (isset($_POST['_name']))
+ $folder = trim(get_input_value('_name', RCUBE_INPUT_POST, true));
+
+ $foldername = new html_inputfield(array('name' => '_name', 'id' => '_name', 'size' => 30));
+ $foldername = $foldername->show($folder);
+
+ if ($options['special']) {
+ $foldername .= '&nbsp;(' . Q(rcmail_localize_foldername($mbox_imap)) .')';
+ }
+ }
+
+ $form['props']['fieldsets']['location'] = array(
+ 'name' => rcube_label('location'),
+ 'content' => array(
+ 'name' => array(
+ 'label' => rcube_label('foldername'),
+ 'value' => $foldername,
+ ),
+ ),
+ );
+
+ if (!empty($options) && ($options['norename'] || $options['protected'])) {
+ // prevent user from moving folder
+ $hidden_path = new html_hiddenfield(array('name' => '_parent', 'value' => $path));
+ $form['props']['fieldsets']['location']['content']['name']['value'] .= $hidden_path->show();
+ }
+ else {
+ $selected = isset($_POST['_parent']) ? $_POST['_parent'] : $path_id;
+ $exceptions = array($mbox_imap);
+
+ // Exclude 'prefix' namespace from parent folders list (#1488349)
+ // If INBOX. namespace exists, folders created as INBOX subfolders
+ // will be listed at the same level - selecting INBOX as a parent does nothing
+ if ($prefix = $storage->get_namespace('prefix')) {
+ $exceptions[] = substr($prefix, 0, -1);
+ }
+
+ $select = rcmail_mailbox_select(array(
+ 'name' => '_parent',
+ 'noselection' => '---',
+ 'realnames' => false,
+ 'maxlength' => 150,
+ 'unsubscribed' => true,
+ 'skip_noinferiors' => true,
+ 'exceptions' => $exceptions,
+ ));
+
+ $form['props']['fieldsets']['location']['content']['path'] = array(
+ 'label' => rcube_label('parentfolder'),
+ 'value' => $select->show($selected),
+ );
+ }
+
+ // Settings
+ $form['props']['fieldsets']['settings'] = array(
+ 'name' => rcube_label('settings'),
+ );
+
+ // Settings: threading
+ if ($threading_supported && ($mbox_imap == 'INBOX' || (!$options['noselect'] && !$options['is_root']))) {
+ $select = new html_select(array('name' => '_viewmode', 'id' => '_listmode'));
+ $select->add(rcube_label('list'), 0);
+ $select->add(rcube_label('threads'), 1);
+
+ if (isset($_POST['_viewmode'])) {
+ $value = (int) $_POST['_viewmode'];
+ }
+ else if (strlen($mbox_imap)) {
+ $a_threaded = $RCMAIL->config->get('message_threading', array());
+ $value = (int) isset($a_threaded[$mbox_imap]);
+ }
+
+ $form['props']['fieldsets']['settings']['content']['viewmode'] = array(
+ 'label' => rcube_label('listmode'),
+ 'value' => $select->show($value),
+ );
+ }
+/*
+ // Settings: sorting column
+ $select = new html_select(array('name' => '_sortcol', 'id' => '_sortcol'));
+ $select->add(rcube_label('nonesort'), '');
+ $select->add(rcube_label('arrival'), 'arrival');
+ $select->add(rcube_label('sentdate'), 'date');
+ $select->add(rcube_label('subject'), 'subject');
+ $select->add(rcube_label('fromto'), 'from');
+ $select->add(rcube_label('replyto'), 'replyto');
+ $select->add(rcube_label('cc'), 'cc');
+ $select->add(rcube_label('size'), 'size');
+
+ $value = isset($_POST['_sortcol']) ? $_POST['_sortcol'] : '';
+
+ $form['props']['fieldsets']['settings']['content']['sortcol'] = array(
+ 'label' => rcube_label('listsorting'),
+ 'value' => $select->show($value),
+ );
+
+ // Settings: sorting order
+ $select = new html_select(array('name' => '_sortord', 'id' => '_sortord'));
+ $select->add(rcube_label('asc'), 'ASC');
+ $select->add(rcube_label('desc'), 'DESC');
+
+ $value = isset($_POST['_sortord']) ? $_POST['_sortord'] : '';
+
+ $form['props']['fieldsets']['settings']['content']['sortord'] = array(
+ 'label' => rcube_label('listorder'),
+ 'value' => $select->show(),
+ );
+*/
+ // Information (count, size) - Edit mode
+ if (strlen($mbox)) {
+ // Number of messages
+ $form['props']['fieldsets']['info'] = array(
+ 'name' => rcube_label('info'),
+ 'content' => array()
+ );
+
+ if ((!$options['noselect'] && !$options['is_root']) || $mbox_imap == 'INBOX') {
+ $msgcount = $storage->count($mbox_imap, 'ALL', true, false);
+
+ // Size
+ if ($msgcount) {
+ // create link with folder-size command
+ $onclick = sprintf("return %s.command('folder-size', '%s', this)",
+ JS_OBJECT_NAME, JQ($mbox_imap));
+ $size = html::a(array('href' => '#', 'onclick' => $onclick,
+ 'id' => 'folder-size'), rcube_label('getfoldersize'));
+ }
+ else {
+ // no messages -> zero size
+ $size = 0;
+ }
+
+ $form['props']['fieldsets']['info']['content']['count'] = array(
+ 'label' => rcube_label('messagecount'),
+ 'value' => (int) $msgcount
+ );
+ $form['props']['fieldsets']['info']['content']['size'] = array(
+ 'label' => rcube_label('size'),
+ 'value' => $size,
+ );
+ }
+
+ // show folder type only if we have non-private namespaces
+ if (!empty($namespace['shared']) || !empty($namespace['others'])) {
+ $form['props']['fieldsets']['info']['content']['foldertype'] = array(
+ 'label' => rcube_label('foldertype'),
+ 'value' => rcube_label($options['namespace'] . 'folder'));
+ }
+ }
+
+ // Allow plugins to modify folder form content
+ $plugin = $RCMAIL->plugins->exec_hook('folder_form',
+ array('form' => $form, 'options' => $options,
+ 'name' => $mbox_imap, 'parent_name' => $parent_imap));
+
+ $form = $plugin['form'];
+
+ // Set form tags and hidden fields
+ list($form_start, $form_end) = get_form_tags($attrib, 'save-folder', null, $hidden_fields);
+
+ unset($attrib['form'], $attrib['id']);
+
+ // return the complete edit form as table
+ $out = "$form_start\n";
+
+ // Create form output
+ foreach ($form as $tab) {
+ if (!empty($tab['fieldsets']) && is_array($tab['fieldsets'])) {
+ $content = '';
+ foreach ($tab['fieldsets'] as $fieldset) {
+ $subcontent = rcmail_get_form_part($fieldset, $attrib);
+ if ($subcontent) {
+ $content .= html::tag('fieldset', null, html::tag('legend', null, Q($fieldset['name'])) . $subcontent) ."\n";
+ }
+ }
+ }
+ else {
+ $content = rcmail_get_form_part($tab, $attrib);
+ }
+
+ if ($content) {
+ $out .= html::tag('fieldset', null, html::tag('legend', null, Q($tab['name'])) . $content) ."\n";
+ }
+ }
+
+ $out .= "\n$form_end";
+
+ $RCMAIL->output->set_env('messagecount', (int) $msgcount);
+
+ return $out;
+}
+
+function rcmail_get_form_part($form, $attrib = array())
+{
+ $content = '';
+
+ if (is_array($form['content']) && !empty($form['content'])) {
+ $table = new html_table(array('cols' => 2));
+ foreach ($form['content'] as $col => $colprop) {
+ $colprop['id'] = '_'.$col;
+ $label = !empty($colprop['label']) ? $colprop['label'] : rcube_label($col);
+
+ $table->add('title', html::label($colprop['id'], Q($label)));
+ $table->add(null, $colprop['value']);
+ }
+ $content = $table->show($attrib);
+ }
+ else {
+ $content = $form['content'];
+ }
+
+ return $content;
+}
+
+
+//$OUTPUT->set_pagetitle(rcube_label('folders'));
+
+// register UI objects
+$OUTPUT->add_handlers(array(
+ 'folderdetails' => 'rcmail_folder_form',
+));
+
+$OUTPUT->add_label('nonamewarning');
+
+$OUTPUT->send('folderedit');
diff --git a/webmail/program/steps/settings/edit_identity.inc b/webmail/program/steps/settings/edit_identity.inc
new file mode 100644
index 0000000..edd4ba6
--- /dev/null
+++ b/webmail/program/steps/settings/edit_identity.inc
@@ -0,0 +1,174 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/edit_identity.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2011, 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 identity record or to add a new one |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('IDENTITIES_LEVEL', intval($RCMAIL->config->get('identities_level', 0)));
+
+// edit-identity
+if (($_GET['_iid'] || $_POST['_iid']) && $RCMAIL->action=='edit-identity') {
+ $IDENTITY_RECORD = $RCMAIL->user->get_identity(get_input_value('_iid', RCUBE_INPUT_GPC));
+
+ if (is_array($IDENTITY_RECORD))
+ $OUTPUT->set_env('iid', $IDENTITY_RECORD['identity_id']);
+ else {
+ $OUTPUT->show_message('dberror', 'error');
+ // go to identities page
+ rcmail_overwrite_action('identities');
+ return;
+ }
+}
+// add-identity
+else {
+ if (IDENTITIES_LEVEL > 1) {
+ $OUTPUT->show_message('opnotpermitted', 'error');
+ // go to identities page
+ rcmail_overwrite_action('identities');
+ return;
+ }
+ else if (IDENTITIES_LEVEL == 1) {
+ $IDENTITY_RECORD['email'] = $RCMAIL->get_user_email();
+ }
+}
+
+
+function rcube_identity_form($attrib)
+{
+ global $IDENTITY_RECORD, $RCMAIL, $OUTPUT;
+
+ // Add HTML editor script(s)
+ rcube_html_editor('identity');
+
+ // add some labels to client
+ $OUTPUT->add_label('noemailwarning', 'nonamewarning', 'converting', 'editorwarning');
+
+ $i_size = !empty($attrib['size']) ? $attrib['size'] : 40;
+ $t_rows = !empty($attrib['textarearows']) ? $attrib['textarearows'] : 6;
+ $t_cols = !empty($attrib['textareacols']) ? $attrib['textareacols'] : 40;
+
+ // list of available cols
+ $form = array(
+ 'addressing' => array(
+ 'name' => rcube_label('settings'),
+ 'content' => array(
+ 'name' => array('type' => 'text', 'size' => $i_size),
+ 'email' => array('type' => 'text', 'size' => $i_size),
+ 'organization' => array('type' => 'text', 'size' => $i_size),
+ 'reply-to' => array('type' => 'text', 'size' => $i_size),
+ 'bcc' => array('type' => 'text', 'size' => $i_size),
+ 'standard' => array('type' => 'checkbox', 'label' => rcube_label('setdefault')),
+ )),
+ 'signature' => array(
+ 'name' => rcube_label('signature'),
+ 'content' => array(
+ 'signature' => array('type' => 'textarea', 'size' => $t_cols, 'rows' => $t_rows,
+ 'spellcheck' => true),
+ 'html_signature' => array('type' => 'checkbox', 'label' => rcube_label('htmlsignature'),
+ 'onclick' => 'return rcmail_toggle_editor(this, \'rcmfd_signature\');'),
+ ))
+ );
+
+ // Enable TinyMCE editor
+ if ($IDENTITY_RECORD['html_signature']) {
+ $form['signature']['content']['signature']['class'] = 'mce_editor';
+ $form['signature']['content']['signature']['is_escaped'] = true;
+
+ // Correctly handle HTML entities in HTML editor (#1488483)
+ $IDENTITY_RECORD['signature'] = htmlspecialchars($IDENTITY_RECORD['signature'], ENT_NOQUOTES, RCMAIL_CHARSET);
+ }
+
+ // disable some field according to access level
+ if (IDENTITIES_LEVEL == 1 || IDENTITIES_LEVEL == 3) {
+ $form['addressing']['content']['email']['disabled'] = true;
+ $form['addressing']['content']['email']['class'] = 'disabled';
+ }
+
+ if (IDENTITIES_LEVEL == 4) {
+ foreach($form['addressing']['content'] as $formfield => $value){
+ $form['addressing']['content'][$formfield]['disabled'] = true;
+ $form['addressing']['content'][$formfield]['class'] = 'disabled';
+ }
+ }
+
+ $IDENTITY_RECORD['email'] = rcube_idn_to_utf8($IDENTITY_RECORD['email']);
+
+ // Allow plugins to modify identity form content
+ $plugin = $RCMAIL->plugins->exec_hook('identity_form', array(
+ 'form' => $form, 'record' => $IDENTITY_RECORD));
+
+ $form = $plugin['form'];
+ $IDENTITY_RECORD = $plugin['record'];
+
+ // Set form tags and hidden fields
+ list($form_start, $form_end) = get_form_tags($attrib, 'save-identity',
+ intval($IDENTITY_RECORD['identity_id']),
+ array('name' => '_iid', 'value' => $IDENTITY_RECORD['identity_id']));
+
+ unset($plugin);
+ unset($attrib['form'], $attrib['id']);
+
+ // return the complete edit form as table
+ $out = "$form_start\n";
+
+ foreach ($form as $fieldset) {
+ if (empty($fieldset['content']))
+ continue;
+
+ $content = '';
+ if (is_array($fieldset['content'])) {
+ $table = new html_table(array('cols' => 2));
+ foreach ($fieldset['content'] as $col => $colprop) {
+ $colprop['id'] = 'rcmfd_'.$col;
+
+ $label = !empty($colprop['label']) ? $colprop['label'] :
+ rcube_label(str_replace('-', '', $col));
+
+ $value = !empty($colprop['value']) ? $colprop['value'] :
+ rcmail_get_edit_field($col, $IDENTITY_RECORD[$col], $colprop, $colprop['type']);
+
+ $table->add('title', html::label($colprop['id'], Q($label)));
+ $table->add(null, $value);
+ }
+ $content = $table->show($attrib);
+ }
+ else {
+ $content = $fieldset['content'];
+ }
+
+ $out .= html::tag('fieldset', null, html::tag('legend', null, Q($fieldset['name'])) . $content) ."\n";
+ }
+
+ $out .= $form_end;
+
+ return $out;
+}
+
+$OUTPUT->include_script('list.js');
+$OUTPUT->add_handler('identityform', 'rcube_identity_form');
+$OUTPUT->set_env('identities_level', IDENTITIES_LEVEL);
+$OUTPUT->add_label('deleteidentityconfirm');
+
+$OUTPUT->set_pagetitle(rcube_label(($RCMAIL->action=='add-identity' ? 'newidentity' : 'edititem')));
+
+if ($RCMAIL->action=='add-identity' && $OUTPUT->template_exists('identityadd'))
+ $OUTPUT->send('identityadd');
+
+$OUTPUT->send('identityedit');
+
+
diff --git a/webmail/program/steps/settings/edit_prefs.inc b/webmail/program/steps/settings/edit_prefs.inc
new file mode 100644
index 0000000..971ed60
--- /dev/null
+++ b/webmail/program/steps/settings/edit_prefs.inc
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/edit_prefs.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2007, 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 functionality for user's settings & preferences |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+if (!$OUTPUT->ajax_call)
+ $OUTPUT->set_pagetitle(rcube_label('preferences'));
+
+
+$CURR_SECTION = get_input_value('_section', RCUBE_INPUT_GPC);
+list($SECTIONS,) = rcmail_user_prefs($CURR_SECTION);
+
+function rcmail_user_prefs_form($attrib)
+{
+ global $RCMAIL, $CURR_SECTION, $SECTIONS;
+
+ // add some labels to client
+ $RCMAIL->output->add_label('nopagesizewarning');
+
+ unset($attrib['form']);
+
+ list($form_start, $form_end) = get_form_tags($attrib, 'save-prefs', null,
+ array('name' => '_section', 'value' => $CURR_SECTION));
+
+ $out = $form_start;
+
+ foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $idx => $block) {
+ if (!empty($block['options'])) {
+ $table = new html_table(array('cols' => 2));
+
+ foreach ($block['options'] as $option) {
+ if ($option['advanced'])
+ $table->set_row_attribs('advanced');
+
+ if (isset($option['title'])) {
+ $table->add('title', $option['title']);
+ $table->add(null, $option['content']);
+ }
+ else {
+ $table->add(array('colspan' => 2), $option['content']);
+ }
+ }
+
+ $out .= html::tag('fieldset', null, html::tag('legend', null, $block['name']) . $table->show($attrib));
+ }
+ else if (!empty($block['content'])) {
+ $out .= html::tag('fieldset', null, html::tag('legend', null, $block['name']) . $block['content']);
+ }
+ }
+
+ return $out . $form_end;
+}
+
+function rcmail_prefs_section_name()
+{
+ global $SECTIONS, $CURR_SECTION;
+
+ return $SECTIONS[$CURR_SECTION]['section'];
+}
+
+
+// register UI objects
+$OUTPUT->add_handlers(array(
+ 'userprefs' => 'rcmail_user_prefs_form',
+ 'sectionname' => 'rcmail_prefs_section_name',
+));
+
+$OUTPUT->send('settingsedit');
+
+
diff --git a/webmail/program/steps/settings/folders.inc b/webmail/program/steps/settings/folders.inc
new file mode 100644
index 0000000..778d93c
--- /dev/null
+++ b/webmail/program/steps/settings/folders.inc
@@ -0,0 +1,440 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/folders.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: |
+ | Provide functionality of folders management |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+// WARNING: folder names in UI are encoded with RCMAIL_CHARSET
+
+// init IMAP connection
+$STORAGE = $RCMAIL->get_storage();
+
+// subscribe mailbox
+if ($RCMAIL->action == 'subscribe')
+{
+ $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true, 'UTF7-IMAP');
+ if (strlen($mbox)) {
+ $result = $STORAGE->subscribe(array($mbox));
+
+ // Handle virtual (non-existing) folders
+ if (!$result && $STORAGE->get_error_code() == -1 &&
+ $STORAGE->get_response_code() == rcube_storage::TRYCREATE
+ ) {
+ $result = $STORAGE->create_folder($mbox, true);
+ if ($result) {
+ // @TODO: remove 'virtual' class of folder's row
+ }
+ }
+
+ if ($result) {
+ // Handle subscription of protected folder (#1487656)
+ if ($RCMAIL->config->get('protect_default_folders')
+ && in_array($mbox, (array)$RCMAIL->config->get('default_folders'))
+ ) {
+ $OUTPUT->command('disable_subscription', $mbox);
+ }
+
+ $OUTPUT->show_message('foldersubscribed', 'confirmation');
+ }
+ else
+ rcmail_display_server_error('errorsaving');
+ }
+}
+
+// unsubscribe mailbox
+else if ($RCMAIL->action == 'unsubscribe')
+{
+ $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true, 'UTF7-IMAP');
+ if (strlen($mbox)) {
+ $result = $STORAGE->unsubscribe(array($mbox));
+ if ($result)
+ $OUTPUT->show_message('folderunsubscribed', 'confirmation');
+ else
+ rcmail_display_server_error('errorsaving');
+ }
+}
+
+// delete an existing mailbox
+else if ($RCMAIL->action == 'delete-folder')
+{
+ $mbox_utf8 = get_input_value('_mbox', RCUBE_INPUT_POST, true);
+ $mbox = rcube_charset_convert($mbox_utf8, RCMAIL_CHARSET, 'UTF7-IMAP');
+
+ if (strlen($mbox)) {
+ $plugin = $RCMAIL->plugins->exec_hook('folder_delete', array('name' => $mbox));
+
+ if (!$plugin['abort']) {
+ $deleted = $STORAGE->delete_folder($plugin['name']);
+ }
+ else {
+ $deleted = $plugin['result'];
+ }
+
+ // #1488692: update session
+ if ($deleted && $_SESSION['mbox'] === $mbox) {
+ $RCMAIL->session->remove('mbox');
+ }
+ }
+
+ if ($OUTPUT->ajax_call && $deleted) {
+ // Remove folder and subfolders rows
+ $OUTPUT->command('remove_folder_row', $mbox_utf8, true);
+ $OUTPUT->show_message('folderdeleted', 'confirmation');
+ // Clear content frame
+ $OUTPUT->command('subscription_select');
+ $OUTPUT->command('set_quota', rcmail_quota_content());
+ }
+ else if (!$deleted) {
+ rcmail_display_server_error('errorsaving');
+ }
+}
+
+// rename an existing mailbox
+else if ($RCMAIL->action == 'rename-folder')
+{
+ $name_utf8 = trim(get_input_value('_folder_newname', RCUBE_INPUT_POST, true));
+ $oldname_utf8 = trim(get_input_value('_folder_oldname', RCUBE_INPUT_POST, true));
+
+ if (strlen($name_utf8) && strlen($oldname_utf8)) {
+ $name = rcube_charset_convert($name_utf8, RCMAIL_CHARSET, 'UTF7-IMAP');
+ $oldname = rcube_charset_convert($oldname_utf8, RCMAIL_CHARSET, 'UTF7-IMAP');
+
+ $rename = rcmail_rename_folder($oldname, $name);
+ }
+
+ if ($rename && $OUTPUT->ajax_call) {
+ rcmail_update_folder_row($name, $oldname);
+ }
+ else if (!$rename) {
+ rcmail_display_server_error('errorsaving');
+ }
+}
+
+// clear mailbox
+else if ($RCMAIL->action == 'purge')
+{
+ $mbox_utf8 = get_input_value('_mbox', RCUBE_INPUT_POST, true);
+ $mbox = rcube_charset_convert($mbox_utf8, RCMAIL_CHARSET, 'UTF7-IMAP');
+ $delimiter = $STORAGE->get_hierarchy_delimiter();
+ $trash_regexp = '/^' . preg_quote($CONFIG['trash_mbox'] . $delimiter, '/') . '/';
+
+ // we should only be purging trash (or their subfolders)
+ if (!strlen($CONFIG['trash_mbox']) || $mbox == $CONFIG['trash_mbox']
+ || preg_match($trash_regexp, $mbox)
+ ) {
+ $success = $STORAGE->delete_message('*', $mbox);
+ $delete = true;
+ }
+ // copy to Trash
+ else {
+ $success = $STORAGE->move_message('1:*', $CONFIG['trash_mbox'], $mbox);
+ $delete = false;
+ }
+
+ if ($success) {
+ $OUTPUT->set_env('messagecount', 0);
+ if ($delete) {
+ $OUTPUT->show_message('folderpurged', 'confirmation');
+ $OUTPUT->command('set_quota', rcmail_quota_content());
+ }
+ else {
+ $OUTPUT->show_message('messagemoved', 'confirmation');
+ }
+ $_SESSION['unseen_count'][$mbox] = 0;
+ $OUTPUT->command('show_folder', $mbox_utf8, null, true);
+ }
+ else {
+ rcmail_display_server_error('errorsaving');
+ }
+}
+
+// get mailbox size
+else if ($RCMAIL->action == 'folder-size')
+{
+ $name = trim(get_input_value('_mbox', RCUBE_INPUT_POST, true));
+
+ $size = $STORAGE->folder_size($name);
+
+ // @TODO: check quota and show percentage usage of specified mailbox?
+
+ if ($size !== false) {
+ $OUTPUT->command('folder_size_update', show_bytes($size));
+ }
+ else {
+ rcmail_display_server_error();
+ }
+}
+
+if ($OUTPUT->ajax_call)
+ $OUTPUT->send();
+
+
+// build table with all folders listed by server
+function rcube_subscription_form($attrib)
+{
+ global $RCMAIL, $OUTPUT;
+
+ list($form_start, $form_end) = get_form_tags($attrib, 'folders');
+ unset($attrib['form']);
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmSubscriptionlist';
+
+ $table = new html_table();
+
+ if ($attrib['noheader'] !== true && $attrib['noheader'] != "true") {
+ // add table header
+ $table->add_header('name', rcube_label('foldername'));
+ $table->add_header('subscribed', '');
+ }
+
+ $STORAGE = $RCMAIL->get_storage();
+
+ // get folders from server
+ $STORAGE->clear_cache('mailboxes', true);
+
+ $a_unsubscribed = $STORAGE->list_folders();
+ $a_subscribed = $STORAGE->list_folders_subscribed('', '*', null, null, true); // unsorted
+ $delimiter = $STORAGE->get_hierarchy_delimiter();
+ $namespace = $STORAGE->get_namespace();
+ $a_js_folders = array();
+ $seen = array();
+ $list_folders = array();
+
+ $default_folders = (array) $RCMAIL->config->get('default_folders');
+ $protect_default = $RCMAIL->config->get('protect_default_folders');
+
+ // pre-process folders list
+ foreach ($a_unsubscribed as $i => $folder) {
+ $folder_id = $folder;
+ $folder = $STORAGE->mod_folder($folder);
+ $foldersplit = explode($delimiter, $folder);
+ $name = rcube_charset_convert(array_pop($foldersplit), 'UTF7-IMAP');
+ $parent_folder = join($delimiter, $foldersplit);
+ $level = count($foldersplit);
+
+ // 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(
+ 'id' => $ancestor_folder,
+ 'name' => $ancestor_name,
+ 'level' => $i-1,
+ 'virtual' => true,
+ );
+ }
+ }
+ }
+
+ // Handle properly INBOX.INBOX situation
+ if (isset($seen[$folder])) {
+ continue;
+ }
+
+ $seen[$folder]++;
+
+ $list_folders[] = array(
+ 'id' => $folder_id,
+ 'name' => $name,
+ 'level' => $level,
+ );
+ }
+
+ unset($seen);
+
+ // add drop-target representing 'root'
+ $table->add_row(array('id' => 'mailboxroot', 'class' => 'virtual root'));
+ $table->add('name', '&nbsp;');
+ $table->add(null, '&nbsp;');
+
+ $a_js_folders['mailboxroot'] = array('', '', true);
+
+ $checkbox_subscribe = new html_checkbox(array(
+ 'name' => '_subscribed[]',
+ 'title' => rcube_label('changesubscription'),
+ 'onclick' => JS_OBJECT_NAME.".command(this.checked?'subscribe':'unsubscribe',this.value)",
+ ));
+
+ // create list of available folders
+ foreach ($list_folders as $i => $folder) {
+ $idx = $i + 1;
+ $sub_key = array_search($folder['id'], $a_subscribed);
+ $subscribed = $sub_key !== false;
+ $protected = $protect_default && in_array($folder['id'], $default_folders);
+ $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']);
+
+ if ($folder['virtual']) {
+ $classes[] = 'virtual';
+ }
+
+ if (!$protected) {
+ $attrs = $STORAGE->folder_attributes($folder['id']);
+ $noselect = in_array('\\Noselect', $attrs);
+ }
+
+ $disabled = (($protected && $subscribed) || $noselect);
+
+ // Below we will disable subscription option for "virtual" folders
+ // according to namespaces, but only if they aren't already subscribed.
+ // User should be able to unsubscribe from the folder
+ // even if it doesn't exists or is not accessible (OTRS:1000059)
+ if (!$subscribed && !$disabled && !empty($namespace) && $folder['virtual']) {
+ // check if the folder is a namespace prefix, then disable subscription option on it
+ if (!$disabled && $folder['level'] == 0) {
+ $fname = $folder['id'] . $delimiter;
+ foreach ($namespace as $ns) {
+ if (is_array($ns)) {
+ foreach ($ns as $item) {
+ if ($item[0] === $fname) {
+ $disabled = true;
+ break 2;
+ }
+ }
+ }
+ }
+ }
+ // check if the folder is an other users virtual-root folder, then disable subscription option on it
+ if (!$disabled && $folder['level'] == 1 && !empty($namespace['other'])) {
+ $parts = explode($delimiter, $folder['id']);
+ $fname = $parts[0] . $delimiter;
+ foreach ($namespace['other'] as $item) {
+ if ($item[0] === $fname) {
+ $disabled = true;
+ break;
+ }
+ }
+ }
+ // check if the folder is shared, then disable subscription option on it (if not subscribed already)
+ if (!$disabled) {
+ $tmp_ns = array_merge((array)$namespace['other'], (array)$namespace['shared']);
+ foreach ($tmp_ns as $item) {
+ if (strpos($folder['id'], $item[0]) === 0) {
+ $disabled = true;
+ break;
+ }
+ }
+ }
+ }
+
+ $table->add_row(array('id' => 'rcmrow'.$idx, 'class' => join(' ', $classes),
+ 'foldername' => $folder['id']));
+
+ $table->add('name', $display_folder);
+ $table->add('subscribed', $checkbox_subscribe->show(($subscribed ? $folder_utf8 : ''),
+ array('value' => $folder_utf8, 'disabled' => $disabled ? 'disabled' : '')));
+
+ $a_js_folders['rcmrow'.$idx] = array($folder_utf8,
+ $display_folder, $protected || $folder['virtual']);
+ }
+
+ $RCMAIL->plugins->exec_hook('folders_list', array('table' => $table));
+
+ $OUTPUT->add_gui_object('subscriptionlist', $attrib['id']);
+ $OUTPUT->set_env('subscriptionrows', $a_js_folders);
+ $OUTPUT->set_env('defaultfolders', $default_folders);
+ $OUTPUT->set_env('delimiter', $delimiter);
+
+ return $form_start . $table->show($attrib) . $form_end;
+}
+
+function rcmail_folder_frame($attrib)
+{
+ global $OUTPUT;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmfolderframe';
+
+ return $OUTPUT->frame($attrib, true);
+}
+
+function rcmail_rename_folder($oldname, $newname)
+{
+ global $RCMAIL;
+
+ $storage = $RCMAIL->get_storage();
+ $delimiter = $storage->get_hierarchy_delimiter();
+
+ $plugin = $RCMAIL->plugins->exec_hook('folder_rename', array(
+ 'oldname' => $oldname, 'newname' => $newname));
+
+ if (!$plugin['abort']) {
+ $renamed = $storage->rename_folder($oldname, $newname);
+ }
+ else {
+ $renamed = $plugin['result'];
+ }
+
+ // update per-folder options for modified folder and its subfolders
+ if ($renamed) {
+ $a_threaded = (array) $RCMAIL->config->get('message_threading', array());
+ $oldprefix = '/^' . preg_quote($oldname . $delimiter, '/') . '/';
+
+ foreach ($a_threaded as $key => $val) {
+ if ($key == $oldname) {
+ unset($a_threaded[$key]);
+ $a_threaded[$newname] = true;
+ }
+ else if (preg_match($oldprefix, $key)) {
+ unset($a_threaded[$key]);
+ $a_threaded[preg_replace($oldprefix, $newname.$delimiter, $key)] = true;
+ }
+ }
+ $RCMAIL->user->save_prefs(array('message_threading' => $a_threaded));
+
+ // #1488692: update session
+ if ($_SESSION['mbox'] === $oldname) {
+ $_SESSION['mbox'] = $newname;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+
+$OUTPUT->set_pagetitle(rcube_label('folders'));
+$OUTPUT->include_script('list.js');
+$OUTPUT->set_env('prefix_ns', $STORAGE->get_namespace('prefix'));
+if ($STORAGE->get_capability('QUOTA')) {
+ $OUTPUT->set_env('quota', true);
+}
+
+// add some labels to client
+$OUTPUT->add_label('deletefolderconfirm', 'purgefolderconfirm', 'folderdeleting',
+ 'foldermoving', 'foldersubscribing', 'folderunsubscribing', 'quota');
+
+// register UI objects
+$OUTPUT->add_handlers(array(
+ 'foldersubscription' => 'rcube_subscription_form',
+ 'folderframe' => 'rcmail_folder_frame',
+ 'quotadisplay' => 'rcmail_quota_display',
+));
+
+$OUTPUT->send('folders');
+
diff --git a/webmail/program/steps/settings/func.inc b/webmail/program/steps/settings/func.inc
new file mode 100644
index 0000000..981d4e4
--- /dev/null
+++ b/webmail/program/steps/settings/func.inc
@@ -0,0 +1,995 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/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 functionality for user's settings & preferences |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+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;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmprefsframe';
+
+ return $OUTPUT->frame($attrib, true);
+}
+
+
+function rcmail_sections_list($attrib)
+{
+ global $RCMAIL;
+
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmsectionslist';
+
+ list($list, $cols) = rcmail_user_prefs();
+
+ // 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');
+
+ return $out;
+}
+
+
+function rcmail_identities_list($attrib)
+{
+ global $OUTPUT, $RCMAIL;
+
+ // 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 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');
+
+ // set client env
+ $OUTPUT->add_gui_object('identitieslist', $attrib['id']);
+
+ 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();
+ }
+
+ $form_end = !strlen($attrib['form']) ? '</form>' : '';
+
+ $EDIT_FORM = !empty($attrib['form']) ? $attrib['form'] : 'form';
+ $RCMAIL->output->add_gui_object('editform', $EDIT_FORM);
+ }
+
+ return array($form_start, $form_end);
+}
+
+
+function rcmail_user_prefs($current=null)
+{
+ 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 = $plugin['list'];
+
+ $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();
+
+ 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),
+ );
+ }
+
+ // 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['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);
+ }
+ }
+
+ $blocks['main']['options']['refresh_interval'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('refreshinterval'))),
+ 'content' => $select_refresh_interval->show($config['refresh_interval']/60),
+ );
+ }
+
+ // 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 : ''))
+ );
+ }
+ }
+ }
+
+ $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),
+ );
+ }
+
+ // 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));
+
+ $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));
+
+ $blocks['main']['options']['mdn_default'] = array(
+ 'title' => html::label($field_id, Q(rcube_label('reqmdn'))),
+ 'content' => $input_mdn->show($config['mdn_default']?1:0),
+ );
+ }
+
+ 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']),
+ );
+ }
+
+ // 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;
+}
+
+
+function rcmail_folder_options($mailbox)
+{
+ global $RCMAIL;
+
+ $options = $RCMAIL->get_storage()->folder_info($mailbox);
+ $options['protected'] = $options['is_root'] || ($options['special'] && $RCMAIL->config->get('protect_default_folders'));
+
+ return $options;
+}
+
+/**
+ * Updates (or creates) folder row in the subscriptions table
+ *
+ * @param string $name Folder name
+ * @param string $oldname Old folder name (for update)
+ * @param bool $subscribe Checks subscription checkbox
+ * @param string $class CSS class name for folder row
+ */
+function rcmail_update_folder_row($name, $oldname=null, $subscribe=false, $class_name=null)
+{
+ global $RCMAIL, $OUTPUT;
+
+ $default_folders = (array) $RCMAIL->config->get('default_folders');
+ $protect_folders = $RCMAIL->config->get('protect_default_folders');
+
+ $storage = $RCMAIL->get_storage();
+ $delimiter = $storage->get_hierarchy_delimiter();
+ $name_utf8 = rcube_charset_convert($name, 'UTF7-IMAP');
+ $protected = $protect_folders && in_array($name, $default_folders);
+
+ $foldersplit = explode($delimiter, $storage->mod_folder($name));
+ $level = count($foldersplit) - 1;
+ $display_name = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $level)
+ . Q($protected ? rcmail_localize_foldername($name) : rcube_charset_convert($foldersplit[$level], 'UTF7-IMAP'));
+
+ if ($oldname === null)
+ $OUTPUT->command('add_folder_row', $name_utf8, $display_name, $protected, $subscribe,
+ false, $class_name);
+ else
+ $OUTPUT->command('replace_folder_row', rcube_charset_convert($oldname, 'UTF7-IMAP'),
+ $name_utf8, $display_name, $protected, $class_name);
+}
+
+
+// register UI objects
+$OUTPUT->add_handlers(array(
+ 'prefsframe' => 'rcmail_preferences_frame',
+ 'sectionslist' => 'rcmail_sections_list',
+ 'identitieslist' => 'rcmail_identities_list',
+));
+
+// register action aliases
+$RCMAIL->register_action_map(array(
+ 'folders' => 'folders.inc',
+ 'rename-folder' => 'folders.inc',
+ 'delete-folder' => 'folders.inc',
+ 'subscribe' => 'folders.inc',
+ 'unsubscribe' => 'folders.inc',
+ 'purge' => 'folders.inc',
+ 'folder-size' => 'folders.inc',
+ 'add-identity' => 'edit_identity.inc',
+));
diff --git a/webmail/program/steps/settings/identities.inc b/webmail/program/steps/settings/identities.inc
new file mode 100644
index 0000000..82a1841
--- /dev/null
+++ b/webmail/program/steps/settings/identities.inc
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/identities.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2007, 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 identities of a user account |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('IDENTITIES_LEVEL', intval($RCMAIL->config->get('identities_level', 0)));
+
+$OUTPUT->set_pagetitle(rcube_label('identities'));
+$OUTPUT->include_script('list.js');
+
+
+// similar function as /steps/addressbook/func.inc::rcmail_contact_frame()
+function rcmail_identity_frame($attrib)
+ {
+ global $OUTPUT;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmIdentityFrame';
+
+ return $OUTPUT->frame($attrib, true);
+ }
+
+$OUTPUT->add_handler('identityframe', 'rcmail_identity_frame');
+$OUTPUT->set_env('identities_level', IDENTITIES_LEVEL);
+$OUTPUT->add_label('deleteidentityconfirm');
+
+$OUTPUT->send('identities');
diff --git a/webmail/program/steps/settings/save_folder.inc b/webmail/program/steps/settings/save_folder.inc
new file mode 100644
index 0000000..877b0fb
--- /dev/null
+++ b/webmail/program/steps/settings/save_folder.inc
@@ -0,0 +1,202 @@
+<?php
+
+/**
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/save_folder.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 functionality to create/edit a folder |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+// WARNING: folder names in UI are encoded with RCMAIL_CHARSET
+
+// init IMAP connection
+$STORAGE = $RCMAIL->get_storage();
+
+
+$name = trim(get_input_value('_name', RCUBE_INPUT_POST, true));
+$old = trim(get_input_value('_mbox', RCUBE_INPUT_POST, true));
+$path = trim(get_input_value('_parent', RCUBE_INPUT_POST, true));
+
+$name_imap = rcube_charset_convert($name, RCMAIL_CHARSET, 'UTF7-IMAP');
+$old_imap = rcube_charset_convert($old, RCMAIL_CHARSET, 'UTF7-IMAP');
+// $path is in UTF7-IMAP already
+
+$delimiter = $STORAGE->get_hierarchy_delimiter();
+$options = strlen($old_imap) ? rcmail_folder_options($old_imap) : array();
+
+// Folder name checks
+if ($options['protected'] || $options['norename']) {
+}
+else if (!strlen($name)) {
+ $error = rcube_label('cannotbeempty');
+}
+else if (mb_strlen($name) > 128) {
+ $error = rcube_label('nametoolong');
+}
+else {
+ // these characters are problematic e.g. when used in LIST/LSUB
+ foreach (array($delimiter, '%', '*') as $char) {
+ if (strpos($name, $delimiter) !== false) {
+ $error = rcube_label('forbiddencharacter') . " ($char)";
+ break;
+ }
+ }
+}
+
+if ($error) {
+ $OUTPUT->command('display_message', $error, 'error');
+}
+else {
+ if ($options['protected'] || $options['norename']) {
+ $name_imap = $old_imap;
+ }
+ else if (strlen($path)) {
+ $name_imap = $path . $delimiter . $name_imap;
+ }
+ else {
+ $name_imap = $STORAGE->mod_folder($name_imap, 'in');
+ }
+}
+
+// Check access rights to the parent folder
+if (!$error && strlen($path) && (!strlen($old_imap) || $old_imap != $name_imap)) {
+ $parent_opts = $STORAGE->folder_info($path);
+ if ($parent_opts['namespace'] != 'personal'
+ && (empty($parent_opts['rights']) || !preg_match('/[ck]/', implode($parent_opts['rights'])))
+ ) {
+ $error = rcube_label('parentnotwritable');
+ }
+}
+
+if ($error) {
+ $OUTPUT->command('display_message', $error, 'error');
+}
+else {
+ $folder['name'] = $name_imap;
+ $folder['oldname'] = $old_imap;
+ $folder['class'] = '';
+ $folder['options'] = $options;
+ $folder['settings'] = array(
+ // List view mode: 0-list, 1-threads
+ 'view_mode' => (int) get_input_value('_viewmode', RCUBE_INPUT_POST),
+ 'sort_column' => get_input_value('_sortcol', RCUBE_INPUT_POST),
+ 'sort_order' => get_input_value('_sortord', RCUBE_INPUT_POST),
+ );
+}
+
+// create a new mailbox
+if (!$error && !strlen($old)) {
+
+ $folder['subscribe'] = true;
+
+ $plugin = $RCMAIL->plugins->exec_hook('folder_create', array('record' => $folder));
+
+ $folder = $plugin['record'];
+
+ if (!$plugin['abort']) {
+ $created = $STORAGE->create_folder($folder['name'], $folder['subscribe']);
+ }
+ else {
+ $created = $plugin['result'];
+ }
+
+ if ($created) {
+ // Save folder settings
+ if (isset($_POST['_viewmode'])) {
+ $a_threaded = (array) $RCMAIL->config->get('message_threading', array());
+
+ if ($_POST['_viewmode'])
+ $a_threaded[$folder['name']] = true;
+ else
+ unset($a_threaded[$folder['name']]);
+
+ $RCMAIL->user->save_prefs(array('message_threading' => $a_threaded));
+ }
+
+ rcmail_update_folder_row($folder['name'], null, $folder['subscribe'], $folder['class']);
+ $OUTPUT->show_message('foldercreated', 'confirmation');
+ // reset folder preview frame
+ $OUTPUT->command('subscription_select');
+ $OUTPUT->send('iframe');
+ }
+ else {
+ // show error message
+ $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error', null, false);
+ }
+}
+
+// update a mailbox
+else if (!$error) {
+ $plugin = $RCMAIL->plugins->exec_hook('folder_update', array('record' => $folder));
+
+ $folder = $plugin['record'];
+ $rename = ($folder['oldname'] != $folder['name']);
+
+ if (!$plugin['abort']) {
+ if ($rename) {
+ $updated = $STORAGE->rename_folder($folder['oldname'], $folder['name']);
+ }
+ else {
+ $updated = true;
+ }
+ }
+ else {
+ $updated = $plugin['result'];
+ }
+
+ if ($updated) {
+ // Update folder settings,
+ if (isset($_POST['_viewmode'])) {
+ $a_threaded = (array) $RCMAIL->config->get('message_threading', array());
+
+ // In case of name change update names of childrens in settings
+ if ($rename) {
+ $oldprefix = '/^' . preg_quote($folder['oldname'] . $delimiter, '/') . '/';
+ foreach ($a_threaded as $key => $val) {
+ if ($key == $folder['oldname']) {
+ unset($a_threaded[$key]);
+ }
+ else if (preg_match($oldprefix, $key)) {
+ unset($a_threaded[$key]);
+ $a_threaded[preg_replace($oldprefix, $folder['name'].$delimiter, $key)] = true;
+ }
+ }
+ }
+ if ($_POST['_viewmode'])
+ $a_threaded[$folder['name']] = true;
+ else
+ unset($a_threaded[$folder['name']]);
+
+ $RCMAIL->user->save_prefs(array('message_threading' => $a_threaded));
+ }
+
+ $OUTPUT->show_message('folderupdated', 'confirmation');
+
+ if ($rename) {
+ // #1488692: update session
+ if ($_SESSION['mbox'] === $folder['oldname']) {
+ $_SESSION['mbox'] = $folder['name'];
+ }
+ rcmail_update_folder_row($folder['name'], $folder['oldname'], $folder['subscribe'], $folder['class']);
+ $OUTPUT->send('iframe');
+ }
+ }
+ else {
+ // show error message
+ $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error', null, false);
+ }
+}
+
+rcmail_overwrite_action('edit-folder');
diff --git a/webmail/program/steps/settings/save_identity.inc b/webmail/program/steps/settings/save_identity.inc
new file mode 100644
index 0000000..d3b132f
--- /dev/null
+++ b/webmail/program/steps/settings/save_identity.inc
@@ -0,0 +1,215 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/save_identity.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: |
+ | Save an identity record or to add a new one |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('IDENTITIES_LEVEL', intval($RCMAIL->config->get('identities_level', 0)));
+
+$a_save_cols = array('name', 'email', 'organization', 'reply-to', 'bcc', 'standard', 'signature', 'html_signature');
+$a_boolean_cols = array('standard', 'html_signature');
+$updated = $default_id = false;
+
+// check input
+if (IDENTITIES_LEVEL != 4 && (empty($_POST['_name']) || (empty($_POST['_email']) && IDENTITIES_LEVEL != 1 && IDENTITIES_LEVEL != 3))) {
+ $OUTPUT->show_message('formincomplete', 'warning');
+ rcmail_overwrite_action('edit-identity');
+ return;
+}
+
+$save_data = array();
+foreach ($a_save_cols as $col) {
+ $fname = '_'.$col;
+ if (isset($_POST[$fname]))
+ $save_data[$col] = get_input_value($fname, RCUBE_INPUT_POST, true);
+}
+
+// set "off" values for checkboxes that were not checked, and therefore
+// not included in the POST body.
+foreach ($a_boolean_cols as $col) {
+ $fname = '_' . $col;
+ if (!isset($_POST[$fname]))
+ $save_data[$col] = 0;
+}
+
+// unset email address if user has no rights to change it
+if (IDENTITIES_LEVEL == 1 || IDENTITIES_LEVEL == 3) {
+ unset($save_data['email']);
+}
+// unset all fields except signature
+else if (IDENTITIES_LEVEL == 4) {
+ foreach ($save_data as $idx => $value) {
+ if ($idx != 'signature' && $idx != 'html_signature') {
+ unset($save_data[$idx]);
+ }
+ }
+}
+
+// Validate e-mail addresses
+$email_checks = array(rcube_idn_to_ascii($save_data['email']));
+foreach (array('reply-to', 'bcc') as $item) {
+ foreach (rcube_mime::decode_address_list($save_data[$item], null, false) as $rcpt)
+ $email_checks[] = rcube_idn_to_ascii($rcpt['mailto']);
+}
+
+foreach ($email_checks as $email) {
+ if ($email && !check_email($email)) {
+ // show error message
+ $OUTPUT->show_message('emailformaterror', 'error', array('email' => rcube_idn_to_utf8($email)), false);
+ rcmail_overwrite_action('edit-identity');
+ return;
+ }
+}
+
+// XSS protection in HTML signature (#1489251)
+if (!empty($save_data['signature']) && !empty($save_data['html_signature'])) {
+ $save_data['signature'] = rcmail_wash_html($save_data['signature']);
+
+ // clear POST data of signature, we want to use safe content
+ // when the form is displayed again
+ unset($_POST['_signature']);
+}
+
+// update an existing contact
+if ($_POST['_iid']) {
+ $iid = get_input_value('_iid', RCUBE_INPUT_POST);
+
+ if (in_array(IDENTITIES_LEVEL, array(1,3,4))) {
+ // merge with old identity data, fixes #1488834
+ $identity = $RCMAIL->user->get_identity($iid);
+ $save_data = array_merge($identity, $save_data);
+ unset($save_data['changed'], $save_data['del'], $save_data['user_id'], $save_data['identity_id']);
+ }
+
+ $plugin = $RCMAIL->plugins->exec_hook('identity_update', array('id' => $iid, 'record' => $save_data));
+ $save_data = $plugin['record'];
+
+ if ($save_data['email'])
+ $save_data['email'] = rcube_idn_to_ascii($save_data['email']);
+ if (!$plugin['abort'])
+ $updated = $RCMAIL->user->update_identity($iid, $save_data);
+ else
+ $updated = $plugin['result'];
+
+ if ($updated) {
+ $OUTPUT->show_message('successfullysaved', 'confirmation');
+
+ if (!empty($save_data['standard']))
+ $default_id = $iid;
+
+ if ($_POST['_framed']) {
+ // update the changed col in list
+ $OUTPUT->command('parent.update_identity_row', $iid, Q(trim($save_data['name'] . ' <' . rcube_idn_to_utf8($save_data['email']) .'>')));
+ }
+ }
+ else {
+ // show error message
+ $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error', null, false);
+ rcmail_overwrite_action('edit-identity');
+ return;
+ }
+}
+
+// insert a new identity record
+else if (IDENTITIES_LEVEL < 2) {
+ if (IDENTITIES_LEVEL == 1) {
+ $save_data['email'] = $RCMAIL->get_user_email();
+ }
+
+ $plugin = $RCMAIL->plugins->exec_hook('identity_create', array('record' => $save_data));
+ $save_data = $plugin['record'];
+
+ if ($save_data['email'])
+ $save_data['email'] = rcube_idn_to_ascii($save_data['email']);
+
+ if (!$plugin['abort'])
+ $insert_id = $save_data['email'] ? $RCMAIL->user->insert_identity($save_data) : null;
+ else
+ $insert_id = $plugin['result'];
+
+ if ($insert_id) {
+ $OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
+
+ $_GET['_iid'] = $insert_id;
+
+ if (!empty($save_data['standard']))
+ $default_id = $insert_id;
+
+ if ($_POST['_framed']) {
+ // add a new row to the list
+ $OUTPUT->command('parent.update_identity_row', $insert_id, Q(trim($save_data['name'] . ' <' . rcube_idn_to_utf8($save_data['email']) .'>')), true);
+ }
+ }
+ else {
+ // show error message
+ $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error', null, false);
+ rcmail_overwrite_action('edit-identity');
+ return;
+ }
+}
+else
+ $OUTPUT->show_message('opnotpermitted', 'error');
+
+
+// mark all other identities as 'not-default'
+if ($default_id)
+ $RCMAIL->user->set_default($default_id);
+
+// go to next step
+if (!empty($_REQUEST['_framed'])) {
+ rcmail_overwrite_action('edit-identity');
+}
+else
+ rcmail_overwrite_action('identities');
+
+
+/**
+ * Sanity checks/cleanups on HTML body of signature
+ */
+function rcmail_wash_html($html)
+{
+ // Add header with charset spec., washtml cannot work without that
+ $html = '<html><head>'
+ . '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />'
+ . '</head><body>' . $html . '</body></html>';
+
+ // clean HTML with washhtml by Frederic Motte
+ $wash_opts = array(
+ 'show_washed' => false,
+ 'allow_remote' => 1,
+ 'charset' => RCMAIL_CHARSET,
+ 'html_elements' => array('body', 'link'),
+ 'html_attribs' => array('rel', 'type'),
+ );
+
+ // initialize HTML washer
+ $washer = new rcube_washtml($wash_opts);
+
+ //$washer->add_callback('form', 'rcmail_washtml_callback');
+ //$washer->add_callback('style', 'rcmail_washtml_callback');
+
+ // Remove non-UTF8 characters (#1487813)
+ $html = rc_utf8_clean($html);
+
+ $html = $washer->wash($html);
+
+ // remove unwanted comments and tags (produced by washtml)
+ $html = preg_replace(array('/<!--[^>]+-->/', '/<\/?body>/'), '', $html);
+
+ return $html;
+}
diff --git a/webmail/program/steps/settings/save_prefs.inc b/webmail/program/steps/settings/save_prefs.inc
new file mode 100644
index 0000000..945005d
--- /dev/null
+++ b/webmail/program/steps/settings/save_prefs.inc
@@ -0,0 +1,219 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/save_prefs.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: |
+ | Save user preferences to DB and to the current session |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+$CURR_SECTION = get_input_value('_section', RCUBE_INPUT_POST);
+
+$a_user_prefs = array();
+
+// set options for specified section
+switch ($CURR_SECTION)
+{
+ case 'general':
+ $a_user_prefs = array(
+ 'language' => isset($_POST['_language']) ? get_input_value('_language', RCUBE_INPUT_POST) : $CONFIG['language'],
+ 'timezone' => isset($_POST['_timezone']) ? get_input_value('_timezone', RCUBE_INPUT_POST) : $CONFIG['timezone'],
+ 'date_format' => isset($_POST['_date_format']) ? get_input_value('_date_format', RCUBE_INPUT_POST) : $CONFIG['date_format'],
+ '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'],
+ 'skin' => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'],
+ );
+
+ // compose derived date/time format strings
+ if ((isset($_POST['_date_format']) || isset($_POST['_time_format'])) && $a_user_prefs['date_format'] && $a_user_prefs['time_format']) {
+ $a_user_prefs['date_short'] = 'D ' . $a_user_prefs['time_format'];
+ $a_user_prefs['date_long'] = $a_user_prefs['date_format'] . ' ' . $a_user_prefs['time_format'];
+ }
+
+ break;
+
+ case 'mailbox':
+ $a_user_prefs = array(
+ 'preview_pane' => isset($_POST['_preview_pane']) ? TRUE : FALSE,
+ 'preview_pane_mark_read' => isset($_POST['_preview_pane_mark_read']) ? intval($_POST['_preview_pane_mark_read']) : $CONFIG['preview_pane_mark_read'],
+ 'autoexpand_threads' => isset($_POST['_autoexpand_threads']) ? intval($_POST['_autoexpand_threads']) : 0,
+ 'mdn_requests' => isset($_POST['_mdn_requests']) ? intval($_POST['_mdn_requests']) : 0,
+ 'check_all_folders' => isset($_POST['_check_all_folders']) ? TRUE : FALSE,
+ 'mail_pagesize' => is_numeric($_POST['_mail_pagesize']) ? max(2, intval($_POST['_mail_pagesize'])) : $CONFIG['mail_pagesize'],
+ );
+
+ break;
+
+ case 'mailview':
+ $a_user_prefs = array(
+ 'message_extwin' => intval($_POST['_message_extwin']),
+ '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,
+ 'display_next' => isset($_POST['_display_next']) ? TRUE : FALSE,
+ 'default_charset' => get_input_value('_default_charset', RCUBE_INPUT_POST),
+ );
+
+ break;
+
+ case 'compose':
+ $a_user_prefs = array(
+ 'compose_extwin' => intval($_POST['_compose_extwin']),
+ 'htmleditor' => intval($_POST['_htmleditor']),
+ 'draft_autosave' => isset($_POST['_draft_autosave']) ? intval($_POST['_draft_autosave']) : 0,
+ 'mime_param_folding' => isset($_POST['_mime_param_folding']) ? intval($_POST['_mime_param_folding']) : 0,
+ 'force_7bit' => isset($_POST['_force_7bit']) ? TRUE : FALSE,
+ 'mdn_default' => isset($_POST['_mdn_default']) ? TRUE : FALSE,
+ 'dsn_default' => isset($_POST['_dsn_default']) ? TRUE : FALSE,
+ 'reply_same_folder' => isset($_POST['_reply_same_folder']) ? TRUE : FALSE,
+ 'spellcheck_before_send' => isset($_POST['_spellcheck_before_send']) ? TRUE : FALSE,
+ 'spellcheck_ignore_syms' => isset($_POST['_spellcheck_ignore_syms']) ? TRUE : FALSE,
+ 'spellcheck_ignore_nums' => isset($_POST['_spellcheck_ignore_nums']) ? TRUE : FALSE,
+ 'spellcheck_ignore_caps' => isset($_POST['_spellcheck_ignore_caps']) ? TRUE : FALSE,
+ 'show_sig' => isset($_POST['_show_sig']) ? intval($_POST['_show_sig']) : 1,
+ 'reply_mode' => isset($_POST['_reply_mode']) ? intval($_POST['_reply_mode']) : 0,
+ 'strip_existing_sig' => isset($_POST['_strip_existing_sig']),
+ 'default_font' => get_input_value('_default_font', RCUBE_INPUT_POST),
+ 'forward_attachment' => !empty($_POST['_forward_attachment']),
+ );
+
+ break;
+
+ case 'addressbook':
+ $a_user_prefs = array(
+ 'default_addressbook' => get_input_value('_default_addressbook', RCUBE_INPUT_POST, true),
+ 'autocomplete_single' => isset($_POST['_autocomplete_single']) ? TRUE : FALSE,
+ 'addressbook_sort_col' => get_input_value('_addressbook_sort_col', RCUBE_INPUT_POST),
+ 'addressbook_name_listing' => intval(get_input_value('_addressbook_name_listing', RCUBE_INPUT_POST)),
+ 'addressbook_pagesize' => is_numeric($_POST['_addressbook_pagesize']) ? max(2, intval($_POST['_addressbook_pagesize'])) : $CONFIG['addressbook_pagesize'],
+ );
+
+ break;
+
+ case 'server':
+ $a_user_prefs = array(
+ 'read_when_deleted' => isset($_POST['_read_when_deleted']) ? TRUE : FALSE,
+ 'skip_deleted' => isset($_POST['_skip_deleted']) ? TRUE : FALSE,
+ 'flag_for_deletion' => isset($_POST['_flag_for_deletion']) ? TRUE : FALSE,
+ 'delete_always' => isset($_POST['_delete_always']) ? TRUE : FALSE,
+ 'delete_junk' => isset($_POST['_delete_junk']) ? TRUE : FALSE,
+ 'logout_purge' => isset($_POST['_logout_purge']) ? TRUE : FALSE,
+ 'logout_expunge' => isset($_POST['_logout_expunge']) ? TRUE : FALSE,
+ );
+
+ break;
+
+ case 'folders':
+ $a_user_prefs = array(
+ '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),
+ 'trash_mbox' => get_input_value('_trash_mbox', RCUBE_INPUT_POST, true),
+ );
+
+ break;
+}
+
+$plugin = rcmail::get_instance()->plugins->exec_hook('preferences_save',
+ array('prefs' => $a_user_prefs, 'section' => $CURR_SECTION));
+
+$a_user_prefs = $plugin['prefs'];
+
+// don't override these parameters
+foreach ((array)$CONFIG['dont_override'] as $p)
+ $a_user_prefs[$p] = $CONFIG[$p];
+
+
+// verify some options
+switch ($CURR_SECTION)
+{
+ case 'general':
+
+ // switch UI language
+ if (isset($_POST['_language']) && $a_user_prefs['language'] != $_SESSION['language']) {
+ $RCMAIL->load_language($a_user_prefs['language']);
+ $OUTPUT->command('reload', 500);
+ }
+
+ // switch skin (if valid, otherwise unset the pref and fall back to default)
+ if (!$OUTPUT->set_skin($a_user_prefs['skin']))
+ unset($a_user_prefs['skin']);
+ else if ($RCMAIL->config->get('skin') != $a_user_prefs['skin'])
+ $OUTPUT->command('reload', 500);
+
+ $a_user_prefs['timezone'] = (string) $a_user_prefs['timezone'];
+
+ if (!empty($a_user_prefs['refresh_interval']) && !empty($CONFIG['min_refresh_interval'])) {
+ if ($a_user_prefs['refresh_interval'] < $CONFIG['min_refresh_interval']) {
+ $a_user_prefs['refresh_interval'] = $CONFIG['min_refresh_interval'];
+ }
+ }
+
+ break;
+
+ case 'mailbox':
+
+ // force min size
+ if ($a_user_prefs['mail_pagesize'] < 1)
+ $a_user_prefs['mail_pagesize'] = 10;
+
+ if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['mail_pagesize'] > $CONFIG['max_pagesize']))
+ $a_user_prefs['mail_pagesize'] = (int) $CONFIG['max_pagesize'];
+
+ break;
+
+ case 'addressbook':
+
+ // force min size
+ if ($a_user_prefs['addressbook_pagesize'] < 1)
+ $a_user_prefs['addressbook_pagesize'] = 10;
+
+ if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['addressbook_pagesize'] > $CONFIG['max_pagesize']))
+ $a_user_prefs['addressbook_pagesize'] = (int) $CONFIG['max_pagesize'];
+
+ break;
+
+ case 'folders':
+
+ // special handling for 'default_folders'
+ if (in_array('default_folders', (array)$CONFIG['dont_override'])) {
+ foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p)
+ $a_user_prefs[$p] = $CONFIG[$p];
+ } else {
+ $a_user_prefs['default_folders'] = array('INBOX');
+ foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) {
+ if ($a_user_prefs[$p])
+ $a_user_prefs['default_folders'][] = $a_user_prefs[$p];
+ }
+ }
+
+ break;
+}
+
+// Save preferences
+if (!$plugin['abort'])
+ $saved = $RCMAIL->user->save_prefs($a_user_prefs);
+else
+ $saved = $plugin['result'];
+
+if ($saved)
+ $OUTPUT->show_message('successfullysaved', 'confirmation');
+else
+ $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error');
+
+// display the form again
+rcmail_overwrite_action('edit-prefs');
+