Allow more advanced element focusing
[squirrelmail.git] / src / options.php
CommitLineData
59177427 1<?php
d3cdb279 2
35586184 3/**
4 * options.php
5 *
35586184 6 * Displays the options page. Pulls from proper user preference files
7 * and config.php. Displays preferences as selected and other options.
8 *
353d074a 9 * @copyright 1999-2018 The SquirrelMail Project Team
4b4abf93 10 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
30967a1e 11 * @version $Id$
8f6f9ba5 12 * @package squirrelmail
ca479ad1 13 * @subpackage prefs
35586184 14 */
cbe5423b 15
ebd2391c 16/** This is the options page */
17define('PAGE_NAME', 'options');
18
30967a1e 19/**
202bcbcc 20 * Include the SquirrelMail initialization file.
30967a1e 21 */
202bcbcc 22require('../include/init.php');
86725763 23
24/* SquirrelMail required files. */
202bcbcc 25
26//include(SM_PATH . 'functions/imap_general.php');
27require_once(SM_PATH . 'functions/options.php');
28require_once(SM_PATH . 'functions/forms.php');
cbe5423b 29
cbe5423b 30/*********************************/
31/*** Build the resultant page. ***/
32/*********************************/
33
cbe5423b 34define('SMOPT_MODE_DISPLAY', 'display');
35define('SMOPT_MODE_SUBMIT', 'submit');
36define('SMOPT_MODE_LINK', 'link');
37
38define('SMOPT_PAGE_MAIN', 'main');
39define('SMOPT_PAGE_PERSONAL', 'personal');
40define('SMOPT_PAGE_DISPLAY', 'display');
5ed9d4fd 41define('SMOPT_PAGE_COMPOSE', 'compose');
8949acd6 42define('SMOPT_PAGE_ACCESSIBILITY', 'accessibility');
cbe5423b 43define('SMOPT_PAGE_HIGHLIGHT', 'highlight');
44define('SMOPT_PAGE_FOLDER', 'folder');
45define('SMOPT_PAGE_ORDER', 'order');
46
8abb7e3a 47/**
48 * Save submitted options and calculate the most
49 * we need to refresh the page
50 *
51 * @param string $optpage The name of the page being submitted
52 * @param array $optpage_data An array of all the submitted options
53 *
54 * @return int The highest level of screen refresh needed per
55 * the options that were changed. This value will
56 * correspond to the SMOPT_REFRESH_* constants found
57 * in functions/options.php.
58 *
59 */
cbe5423b 60function process_optionmode_submit($optpage, $optpage_data) {
61 /* Initialize the maximum option refresh level. */
62 $max_refresh = SMOPT_REFRESH_NONE;
63
209e24bb 64
65
cbe5423b 66 /* Save each option in each option group. */
67 foreach ($optpage_data['options'] as $option_grp) {
68 foreach ($option_grp['options'] as $option) {
209e24bb 69
70 /* Special case: need to make sure emailaddress
71 * is saved if we use it as a test for ask_user_info */
72 global $ask_user_info;
73 if ( $optpage = SMOPT_PAGE_PERSONAL && $ask_user_info &&
74 $option->name == 'email_address' ) {
75 $option->setValue('');
76 }
77
534367eb 78 /* Remove Debug Mode Until Needed
cbe5423b 79 echo "name = '$option->name', "
80 . "value = '$option->value', "
6206f6c4 81 . "new_value = '$option->new_value'\n";
244a64a4 82//FIXME: NO HTML IN THE CORE!
39bfea8f 83 echo "<br />";
534367eb 84 */
cbe5423b 85 if ($option->changed()) {
86 $option->save();
87 $max_refresh = max($max_refresh, $option->refresh_level);
88 }
89 }
90 }
1e0628fb 91
cbe5423b 92 /* Return the max refresh level. */
93 return ($max_refresh);
94}
95
96function process_optionmode_link($optpage) {
97 /* There will be something here, later. */
98}
99
0b0e96c5 100
0b0e96c5 101
102/* ---------------------------- main ---------------------------- */
103
a32985a5 104/* get the globals that we may need */
1e12d1ff 105sqgetGlobalVar('optpage', $optpage);
199a9ab8 106sqgetGlobalVar('optmode', $optmode, SQ_FORM);
107sqgetGlobalVar('optpage_data',$optpage_data, SQ_POST);
cffe28e2 108sqgetGlobalVar('smtoken', $submitted_token, SQ_FORM, '');
a32985a5 109/* end of getting globals */
110
cbe5423b 111/* Make sure we have an Option Page set. Default to main. */
c1f7790a 112if ( !isset($optpage) || $optpage == '' ) {
113 $optpage = SMOPT_PAGE_MAIN;
114} else {
115 $optpage = strip_tags( $optpage );
cbe5423b 116}
117
118/* Make sure we have an Option Mode set. Default to display. */
119if (!isset($optmode)) {
120 $optmode = SMOPT_MODE_DISPLAY;
121}
122
0b0e96c5 123/*
91e0dccc 124 * First, set the load information for each option page.
0b0e96c5 125 */
cbe5423b 126
127/* Initialize load information variables. */
128$optpage_name = '';
129$optpage_file = '';
130$optpage_loader = '';
131
132/* Set the load information for each page. */
133switch ($optpage) {
91e0dccc 134 case SMOPT_PAGE_MAIN:
c1f7790a 135 break;
cbe5423b 136 case SMOPT_PAGE_PERSONAL:
a3439b27 137 $optpage_name = _("Personal Information");
08185f2a 138 $optpage_file = SM_PATH . 'include/options/personal.php';
a3439b27 139 $optpage_loader = 'load_optpage_data_personal';
140 $optpage_loadhook = 'optpage_loadhook_personal';
cbe5423b 141 break;
142 case SMOPT_PAGE_DISPLAY:
143 $optpage_name = _("Display Preferences");
08185f2a 144 $optpage_file = SM_PATH . 'include/options/display.php';
cbe5423b 145 $optpage_loader = 'load_optpage_data_display';
a3439b27 146 $optpage_loadhook = 'optpage_loadhook_display';
cbe5423b 147 break;
5ed9d4fd 148 case SMOPT_PAGE_COMPOSE:
149 $optpage_name = _("Compose Preferences");
150 $optpage_file = SM_PATH . 'include/options/compose.php';
151 $optpage_loader = 'load_optpage_data_compose';
152 $optpage_loadhook = 'optpage_loadhook_compose';
153 break;
8949acd6 154 case SMOPT_PAGE_ACCESSIBILITY:
155 $optpage_name = _("Accessibility Preferences");
156 $optpage_file = SM_PATH . 'include/options/accessibility.php';
157 $optpage_loader = 'load_optpage_data_accessibility';
158 $optpage_loadhook = 'optpage_loadhook_accessibility';
159 break;
cbe5423b 160 case SMOPT_PAGE_HIGHLIGHT:
161 $optpage_name = _("Message Highlighting");
08185f2a 162 $optpage_file = SM_PATH . 'include/options/highlight.php';
cbe5423b 163 $optpage_loader = 'load_optpage_data_highlight';
a3439b27 164 $optpage_loadhook = 'optpage_loadhook_highlight';
cbe5423b 165 break;
166 case SMOPT_PAGE_FOLDER:
167 $optpage_name = _("Folder Preferences");
08185f2a 168 $optpage_file = SM_PATH . 'include/options/folder.php';
cbe5423b 169 $optpage_loader = 'load_optpage_data_folder';
a3439b27 170 $optpage_loadhook = 'optpage_loadhook_folder';
cbe5423b 171 break;
172 case SMOPT_PAGE_ORDER:
173 $optpage_name = _("Index Order");
08185f2a 174 $optpage_file = SM_PATH . 'include/options/order.php';
cbe5423b 175 $optpage_loader = 'load_optpage_data_order';
a3439b27 176 $optpage_loadhook = 'optpage_loadhook_order';
cbe5423b 177 break;
6e515418 178 default: do_hook('optpage_set_loadinfo', $null);
cbe5423b 179}
180
181/**********************************************************/
182/*** Second, load the option information for this page. ***/
183/**********************************************************/
184
a32985a5 185if ( !@is_file( $optpage_file ) ) {
c1f7790a 186 $optpage = SMOPT_PAGE_MAIN;
64033e1c 187} elseif ($optpage != SMOPT_PAGE_MAIN ) {
cbe5423b 188 /* Include the file for this optionpage. */
91e0dccc 189
cbe5423b 190 require_once($optpage_file);
191
192 /* Assemble the data for this option page. */
193 $optpage_data = array();
194 $optpage_data = $optpage_loader();
6e515418 195 do_hook($optpage_loadhook, $null);
64033e1c 196 $optpage_data['options'] = create_option_groups($optpage_data['grps'], $optpage_data['vals']);
cbe5423b 197}
198
199/***********************************************************/
200/*** Next, process anything that needs to be processed. ***/
201/***********************************************************/
202
199a9ab8 203// security check before saving anything...
204//FIXME: what about SMOPT_MODE_LINK??
205if ($optmode == SMOPT_MODE_SUBMIT) {
2cefa62a 206 sm_validate_security_token($submitted_token, -1, TRUE);
199a9ab8 207}
208
288df1a0 209$optpage_save_error=array();
210
cc61478a 211if ( isset( $optpage_data ) ) {
212 switch ($optmode) {
213 case SMOPT_MODE_SUBMIT:
214 $max_refresh = process_optionmode_submit($optpage, $optpage_data);
215 break;
216 case SMOPT_MODE_LINK:
217 $max_refresh = process_optionmode_link($optpage, $optpage_data);
218 break;
219 }
cbe5423b 220}
cbe5423b 221
2de8b87f 222$optpage_title = _("Options");
223if (isset($optpage_name) && ($optpage_name != '')) {
224 $optpage_title .= " - $optpage_name";
225}
226
cbe5423b 227/*******************************************************************/
228/* DO OLD SAVING OF SUBMITTED OPTIONS. THIS WILL BE REMOVED LATER. */
229/*******************************************************************/
230
21f6d2ea 231//FIXME: let's remove these finally in 1.5.2..... but first, are there any plugins using them?
cbe5423b 232/* If in submit mode, select a save hook name and run it. */
7e235a1a 233if ($optmode == SMOPT_MODE_SUBMIT) {
cbe5423b 234 /* Select a save hook name. */
235 switch ($optpage) {
236 case SMOPT_PAGE_PERSONAL:
237 $save_hook_name = 'options_personal_save';
238 break;
239 case SMOPT_PAGE_DISPLAY:
240 $save_hook_name = 'options_display_save';
241 break;
10ad5e30 242 case SMOPT_PAGE_COMPOSE:
243 $save_hook_name = 'options_compose_save';
244 break;
8949acd6 245 case SMOPT_PAGE_ACCESSIBILITY:
246 $save_hook_name = 'options_accessibility_save';
247 break;
cbe5423b 248 case SMOPT_PAGE_FOLDER:
249 $save_hook_name = 'options_folder_save';
250 break;
91e0dccc 251 default:
cc61478a 252 $save_hook_name = 'options_save';
cbe5423b 253 break;
254 }
b5efadfa 255
cbe5423b 256 /* Run the options save hook. */
6e515418 257 do_hook($save_hook_name, $null);
cbe5423b 258}
259
260/***************************************************************/
261/* Apply logic to decide what optpage we want to display next. */
262/***************************************************************/
263
264/* If this is the result of an option page being submitted, then */
265/* show the main page. Otherwise, show whatever page was called. */
266
267if ($optmode == SMOPT_MODE_SUBMIT) {
268 $optpage = SMOPT_PAGE_MAIN;
f31cc5f7 269 $optpage_title = _("Options");
cbe5423b 270}
271
2de8b87f 272/***************************************************************/
273/* Finally, display whatever page we are supposed to show now. */
274/***************************************************************/
275
876fdb60 276displayPageHeader($color, null, (isset($optpage_data['xtra']) ? $optpage_data['xtra'] : ''));
2de8b87f 277
2de8b87f 278/*
279 * The main option page has a different layout then the rest of the option
280 * pages. Therefore, we create it here first, then the others below.
281 */
282if ($optpage == SMOPT_PAGE_MAIN) {
283 /**********************************************************/
284 /* First, display the results of a submission, if needed. */
285 /**********************************************************/
286 $notice = '';
287 if ($optmode == SMOPT_MODE_SUBMIT) {
288 if (!isset($frame_top)) {
289 $frame_top = '_top';
290 }
291
292 if (isset($optpage_save_error) && $optpage_save_error!=array()) {
8befffa8 293//FIXME: REMOVE HTML FROM CORE
64033e1c 294 $notice = _("Error(s) occurred while saving your options") . "<br />\n<ul>\n";
2de8b87f 295 foreach ($optpage_save_error as $error_message) {
296 $notice.= '<li><small>' . $error_message . "</small></li>\n";
297 }
64033e1c 298 $notice.= "</ul>\n" . _("Some of your preference changes were not applied.") . "\n";
2de8b87f 299 } else {
300 /* Display a message indicating a successful save. */
1a7dcf9d 301 // i18n: The %s represents the name of the option page saving the options
302 $notice = sprintf(_("Successfully Saved Options: %s"), $optpage_name) . "<br />\n";
2de8b87f 303 }
304
305 /* If $max_refresh != SMOPT_REFRESH_NONE, provide a refresh link. */
306 if ( !isset( $max_refresh ) ) {
307 } else if ($max_refresh == SMOPT_REFRESH_FOLDERLIST) {
8befffa8 308//FIXME: REMOVE HTML FROM CORE - when migrating, keep in mind that the javascript below assumes the folder list is in a separate sibling frame under the same parent, and it is called "left"
309 if (checkForJavascript()) {
310 $notice .= sprintf(_("Folder list should automatically %srefresh%s."), '<a href="../src/left_main.php" target="left">', '</a>') . '<br /><script type="text/javascript">' . "\n<!--\nparent.left.location = '../src/left_main.php';\n// -->\n</script>\n";
311 } else {
312 $notice .= '<a href="../src/left_main.php" target="left">' . _("Refresh Folder List") . '</a><br />';
313 }
2de8b87f 314 } else if ($max_refresh) {
8befffa8 315 if (checkForJavascript()) {
316//FIXME: REMOVE HTML FROM CORE - when migrating, keep in mind that the javascript below assumes the parent is the top-most SM frame and is what should be refreshed with webmail.php
317 $notice .= sprintf(_("This page should automatically %srefresh%s."), '<a href="../src/webmail.php?right_frame=options.php" target="' . $frame_top . '">', '</a>') . '<br /><script type="text/javascript">' . "\n<!--\nparent.location = '../src/webmail.php?right_frame=options.php';\n// -->\n</script>\n";
318 } else {
319 $notice .= '<a href="../src/webmail.php?right_frame=options.php" target="' . $frame_top . '">' . _("Refresh Page") . '</a><br />';
320 }
2de8b87f 321 }
322 }
64033e1c 323
324 if (!empty($notice)) {
203f4ab0 325 $oTemplate->assign('note', $notice);
64033e1c 326 $oTemplate->display('note.tpl');
327 }
328
2de8b87f 329 /******************************************/
330 /* Build our array of Option Page Blocks. */
331 /******************************************/
332 $optpage_blocks = array();
333
96698334 334 // access keys...
335 global $accesskey_options_personal, $accesskey_options_display,
336 $accesskey_options_highlighting, $accesskey_options_folders,
337 $accesskey_options_index_order, $accesskey_options_compose,
338 $accesskey_options_accessibility;
339
2de8b87f 340 /* Build a section for Personal Options. */
341 $optpage_blocks[] = array(
96698334 342 'name' => _("Personal Information"),
343 'url' => 'options.php?optpage=' . SMOPT_PAGE_PERSONAL,
344 'desc' => _("This contains personal information about yourself such as your name, your email address, etc."),
345 'js' => false,
346 'accesskey' => $accesskey_options_personal,
2de8b87f 347 );
348
349 /* Build a section for Display Options. */
350 $optpage_blocks[] = array(
96698334 351 'name' => _("Display Preferences"),
352 'url' => 'options.php?optpage=' . SMOPT_PAGE_DISPLAY,
353 'desc' => _("You can change the way that SquirrelMail looks and displays information to you, such as the colors, the language, and other settings."),
354 'js' => false,
355 'accesskey' => $accesskey_options_display,
2de8b87f 356 );
357
358 /* Build a section for Message Highlighting Options. */
359 $optpage_blocks[] = array(
96698334 360 'name' =>_("Message Highlighting"),
361 'url' => 'options_highlight.php',
362 'desc' =>_("Based upon given criteria, incoming messages can have different background colors in the message list. This helps to easily distinguish who the messages are from, especially for mailing lists."),
363 'js' => false,
364 'accesskey' => $accesskey_options_highlighting,
2de8b87f 365 );
366
367 /* Build a section for Folder Options. */
368 $optpage_blocks[] = array(
96698334 369 'name' => _("Folder Preferences"),
370 'url' => 'options.php?optpage=' . SMOPT_PAGE_FOLDER,
371 'desc' => _("These settings change the way your folders are displayed and manipulated."),
372 'js' => false,
373 'accesskey' => $accesskey_options_folders,
2de8b87f 374 );
375
376 /* Build a section for Index Order Options. */
377 $optpage_blocks[] = array(
96698334 378 'name' => _("Index Order"),
379 'url' => 'options_order.php',
380 'desc' => _("The order of the message index can be rearranged and changed to contain the headers in any order you want."),
381 'js' => false,
382 'accesskey' => $accesskey_options_index_order,
2de8b87f 383 );
384
385 /* Build a section for Compose Options. */
386 $optpage_blocks[] = array(
96698334 387 'name' => _("Compose Preferences"),
388 'url' => 'options.php?optpage=' . SMOPT_PAGE_COMPOSE,
389 'desc' => _("Control the behaviour and layout of writing new mail messages, replying to and forwarding messages."),
390 'js' => false,
391 'accesskey' => $accesskey_options_compose,
2de8b87f 392 );
393
8949acd6 394 /* Build a section for Accessibility Options. */
395 $optpage_blocks[] = array(
96698334 396 'name' => _("Accessibility Preferences"),
397 'url' => 'options.php?optpage=' . SMOPT_PAGE_ACCESSIBILITY,
398 'desc' => _("You can configure features that improve interface usability."),
399 'js' => false,
400 'accesskey' => $accesskey_options_accessibility,
8949acd6 401 );
402
2de8b87f 403 /* Build a section for plugins wanting to register an optionpage. */
6e515418 404 do_hook('optpage_register_block', $null);
2de8b87f 405
406 /*****************************************************/
407 /* Let's sort Javascript Option Pages to the bottom. */
408 /*****************************************************/
409 $js_optpage_blocks = array();
410 $reg_optpage_blocks = array();
411 foreach ($optpage_blocks as $cur_optpage) {
96698334 412 if (!isset($cur_optpage['accesskey'])) {
413 $cur_optpage['accesskey'] = 'NONE';
414 }
2de8b87f 415 if (!isset($cur_optpage['js']) || !$cur_optpage['js']) {
416 $reg_optpage_blocks[] = $cur_optpage;
457e8593 417 } else if (checkForJavascript()) {
2de8b87f 418 $js_optpage_blocks[] = $cur_optpage;
419 }
420 }
421 $optpage_blocks = array_merge($reg_optpage_blocks, $js_optpage_blocks);
422
423 /********************************************/
424 /* Now, print out each option page section. */
425 /********************************************/
64033e1c 426 $oTemplate->assign('page_title', $optpage_title);
427 $oTemplate->assign('options', $optpage_blocks);
2de8b87f 428
2de8b87f 429 $oTemplate->display('option_groups.tpl');
64033e1c 430
6e515418 431 do_hook('options_link_and_description', $null);
cbe5423b 432
cbe5423b 433
2de8b87f 434/*************************************************************************/
435/* If we are not looking at the main option page, display the page here. */
436/*************************************************************************/
437} else {
fcc81e7a 438 /* Set the bottom_hook_name and submit_name. */
2de8b87f 439 switch ($optpage) {
440 case SMOPT_PAGE_PERSONAL:
2de8b87f 441 $bottom_hook_name = 'options_personal_bottom';
442 $submit_name = 'submit_personal';
443 break;
444 case SMOPT_PAGE_DISPLAY:
2de8b87f 445 $bottom_hook_name = 'options_display_bottom';
446 $submit_name = 'submit_display';
447 break;
448 case SMOPT_PAGE_COMPOSE:
2de8b87f 449 $bottom_hook_name = 'options_compose_bottom';
450 $submit_name = 'submit_compose';
451 break;
8949acd6 452 case SMOPT_PAGE_ACCESSIBILITY:
453 $bottom_hook_name = 'options_accessibility_bottom';
454 $submit_name = 'submit_accessibility';
455 break;
2de8b87f 456 case SMOPT_PAGE_HIGHLIGHT:
2de8b87f 457 $bottom_hook_name = 'options_highlight_bottom';
458 $submit_name = 'submit_highlight';
459 break;
460 case SMOPT_PAGE_FOLDER:
2de8b87f 461 $bottom_hook_name = 'options_folder_bottom';
462 $submit_name = 'submit_folder';
463 break;
464 case SMOPT_PAGE_ORDER:
2de8b87f 465 $bottom_hook_name = 'options_order_bottom';
466 $submit_name = 'submit_order';
467 break;
468 default:
2de8b87f 469 $bottom_hook_name = '';
470 $submit_name = 'submit';
471 }
472
64033e1c 473 // Begin output form
199a9ab8 474 echo addForm('options.php', 'post', 'option_form', '', '', array(), TRUE)
64033e1c 475 . create_optpage_element($optpage)
476 . create_optmode_element(SMOPT_MODE_SUBMIT);
477
64033e1c 478 // This is the only variable that is needed by *just* the template.
6c06cf54 479 $oTemplate->assign('option_groups', $optpage_data['options']);
64033e1c 480
ad3aa533 481 global $ask_user_info, $org_name;
75b4ac6f 482 if ( $optpage == SMOPT_PAGE_PERSONAL && $ask_user_info
209e24bb 483 && getPref($data_dir, $username,'email_address') == "" ) {
484 $oTemplate->assign('topmessage',
ad3aa533 485 sprintf(_("Welcome to %s. Please supply your full name and email address."), $org_name) );
209e24bb 486 }
487
fcc81e7a 488 // These variables are not specifically needed by the template,
489 // but they are relevant to the page being built, so we'll add
490 // them in case some plugin is modifying the page, etc....
491 //
64033e1c 492 $oTemplate->assign('max_refresh', isset($max_refresh) ? $max_refresh : NULL);
493 $oTemplate->assign('page_title', $optpage_title);
fcc81e7a 494 $oTemplate->assign('optpage', $optpage);
495 $oTemplate->assign('optpage_name', $optpage_name);
496 $oTemplate->assign('optmode', $optmode);
497 $oTemplate->assign('optpage_data', $optpage_data);
64033e1c 498
835db280 499 $oTemplate->assign('submit_name', $submit_name);
64033e1c 500 $oTemplate->display('options.tpl');
501
244a64a4 502 $oTemplate->display('form_close.tpl');
2de8b87f 503
504 /* If it is not empty, trigger the bottom hook. */
505 if ($bottom_hook_name != '') {
6e515418 506 do_hook($bottom_hook_name, $null);
2de8b87f 507 }
64033e1c 508
2de8b87f 509}
a2b193bc 510
6e4bf7c9 511$oTemplate->display('footer.tpl');