6 * Functions needed to display the options pages.
8 * @copyright © 1999-2006 The SquirrelMail Project Team
9 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
11 * @package squirrelmail
15 /**********************************************/
16 /* Define constants used in the options code. */
17 /**********************************************/
19 /* Define constants for the various option types. */
20 define('SMOPT_TYPE_STRING', 0);
21 define('SMOPT_TYPE_STRLIST', 1);
22 define('SMOPT_TYPE_TEXTAREA', 2);
23 define('SMOPT_TYPE_INTEGER', 3);
24 define('SMOPT_TYPE_FLOAT', 4);
25 define('SMOPT_TYPE_BOOLEAN', 5);
26 define('SMOPT_TYPE_HIDDEN', 6);
27 define('SMOPT_TYPE_COMMENT', 7);
28 define('SMOPT_TYPE_FLDRLIST', 8);
30 /* Define constants for the options refresh levels. */
31 define('SMOPT_REFRESH_NONE', 0);
32 define('SMOPT_REFRESH_FOLDERLIST', 1);
33 define('SMOPT_REFRESH_ALL', 2);
35 /* Define constants for the options size. */
36 define('SMOPT_SIZE_TINY', 0);
37 define('SMOPT_SIZE_SMALL', 1);
38 define('SMOPT_SIZE_MEDIUM', 2);
39 define('SMOPT_SIZE_LARGE', 3);
40 define('SMOPT_SIZE_HUGE', 4);
41 define('SMOPT_SIZE_NORMAL', 5);
43 define('SMOPT_SAVE_DEFAULT', 'save_option');
44 define('SMOPT_SAVE_NOOP', 'save_option_noop');
47 * SquirrelOption: An option for SquirrelMail.
49 * @package squirrelmail
52 class SquirrelOption
{
54 * The name of this setting
59 * The text that prefaces setting on the preferences page
64 * The type of INPUT element
66 * See SMOPT_TYPE_* defines
71 * Indicates if a link should be shown to refresh part
72 * or all of the window
74 * See SMOPT_REFRESH_* defines
79 * Specifies the size of certain input items
81 * See SMOPT_SIZE_* defines
86 * Text that follows a text input or
87 * select list input on the preferences page
89 * useful for indicating units, meanings of special values, etc.
94 * text displayed to the user
96 * Used with SMOPT_TYPE_COMMENT options
101 * additional javascript or other code added to the user input
106 * script (usually Javascript) that will be placed after (outside of)
113 * The name of the Save Function for this option.
118 /* The various 'values' for this options. */
120 * default/preselected value for this option
130 * associative array, where each key is an actual input value
131 * and the corresponding value is what is displayed to the user
132 * for that list item in the drop-down list
135 var $possible_values;
137 * disables html sanitizing.
139 * WARNING - don't use it, if user input is possible in option
140 * or use own sanitizing functions. Currently works only with
141 * SMOPT_TYPE_STRLIST.
144 var $htmlencoded=false;
146 * Controls folder list limits in SMOPT_TYPE_FLDRLIST widget.
147 * See $flag argument in sqimap_mailbox_option_list() function.
151 var $folder_filter='noselect';
154 * Constructor function
155 * @param string $name
156 * @param string $caption
157 * @param integer $type
158 * @param integer $refresh_level
159 * @param mixed $initial_value
160 * @param array $possible_values
161 * @param bool $htmlencoded
163 function SquirrelOption
164 ($name, $caption, $type, $refresh_level, $initial_value = '', $possible_values = '', $htmlencoded = false) {
165 /* Set the basic stuff. */
167 $this->caption
= $caption;
169 $this->refresh_level
= $refresh_level;
170 $this->possible_values
= $possible_values;
171 $this->htmlencoded
= $htmlencoded;
172 $this->size
= SMOPT_SIZE_MEDIUM
;
173 $this->trailing_text
= '';
176 $this->post_script
= '';
178 //Check for a current value.
179 if (isset($GLOBALS[$name])) {
180 $this->value
= $GLOBALS[$name];
181 } else if (!empty($initial_value)) {
182 $this->value
= $initial_value;
187 /* Check for a new value. */
188 if ( !sqgetGlobalVar("new_$name", $this->new_value
, SQ_POST
) ) {
189 $this->new_value
= '';
192 /* Set the default save function. */
193 if (($type != SMOPT_TYPE_HIDDEN
) && ($type != SMOPT_TYPE_COMMENT
)) {
194 $this->save_function
= SMOPT_SAVE_DEFAULT
;
196 $this->save_function
= SMOPT_SAVE_NOOP
;
201 * Set the value for this option.
202 * @param mixed $value
204 function setValue($value) {
205 $this->value
= $value;
209 * Set the new value for this option.
210 * @param mixed $new_value
212 function setNewValue($new_value) {
213 $this->new_value
= $new_value;
217 * Set the size for this option.
218 * @param integer $size
220 function setSize($size) {
225 * Set the trailing_text for this option.
226 * @param string $trailing_text
228 function setTrailingText($trailing_text) {
229 $this->trailing_text
= $trailing_text;
233 * Set the comment for this option.
234 * @param string $comment
236 function setComment($comment) {
237 $this->comment
= $comment;
241 * Set the script for this option.
242 * @param string $script
244 function setScript($script) {
245 $this->script
= $script;
249 * Set the "post script" for this option.
250 * @param string $post_script
252 function setPostScript($post_script) {
253 $this->post_script
= $post_script;
257 * Set the save function for this option.
258 * @param string $save_function
260 function setSaveFunction($save_function) {
261 $this->save_function
= $save_function;
265 * Set the trailing_text for this option.
266 * @param string $folder_filter
269 function setFolderFilter($folder_filter) {
270 $this->folder_filter
= $folder_filter;
274 * Creates fields on option pages according to option type
276 * Function that calls other createWidget* functions.
277 * @return string html formated option field
279 function createHTMLWidget() {
282 // Use new value if available
283 if (!empty($this->new_value
)) {
284 $tempValue = $this->value
;
285 $this->value
= $this->new_value
;
288 /* Get the widget for this option type. */
289 switch ($this->type
) {
290 case SMOPT_TYPE_STRING
:
291 $result = $this->createWidget_String();
293 case SMOPT_TYPE_STRLIST
:
294 $result = $this->createWidget_StrList();
296 case SMOPT_TYPE_TEXTAREA
:
297 $result = $this->createWidget_TextArea();
299 case SMOPT_TYPE_INTEGER
:
300 $result = $this->createWidget_Integer();
302 case SMOPT_TYPE_FLOAT
:
303 $result = $this->createWidget_Float();
305 case SMOPT_TYPE_BOOLEAN
:
306 $result = $this->createWidget_Boolean();
308 case SMOPT_TYPE_HIDDEN
:
309 $result = $this->createWidget_Hidden();
311 case SMOPT_TYPE_COMMENT
:
312 $result = $this->createWidget_Comment();
314 case SMOPT_TYPE_FLDRLIST
:
315 $result = $this->createWidget_FolderList();
318 $result = '<font color="' . $color[2] . '">'
319 . sprintf(_("Option Type '%s' Not Found"), $this->type
)
323 /* Add the "post script" for this option. */
324 $result .= $this->post_script
;
326 // put correct value back if need be
327 if (!empty($this->new_value
)) {
328 $this->value
= $tempValue;
331 /* Now, return the created widget. */
336 * Create string field
337 * @return string html formated option field
339 function createWidget_String() {
340 switch ($this->size
) {
341 case SMOPT_SIZE_TINY
:
344 case SMOPT_SIZE_SMALL
:
347 case SMOPT_SIZE_LARGE
:
350 case SMOPT_SIZE_HUGE
:
353 case SMOPT_SIZE_NORMAL
:
358 $result = "<input type=\"text\" name=\"new_$this->name\" value=\"" .
359 htmlspecialchars($this->value
) .
360 "\" size=\"$width\" $this->script />$this->trailing_text\n";
365 * Create selection box
366 * @return string html formated selection box
368 function createWidget_StrList() {
369 /* Begin the select tag. */
370 $result = "<select name=\"new_$this->name\" $this->script>\n";
372 /* Add each possible value to the select list. */
373 foreach ($this->possible_values
as $real_value => $disp_value) {
374 /* Start the next new option string. */
375 $new_option = '<option value="' .
376 ($this->htmlencoded ?
$real_value : htmlspecialchars($real_value)) . '"';
378 /* If this value is the current value, select it. */
379 if ($real_value == $this->value
) {
380 $new_option .= ' selected="selected"';
383 /* Add the display value to our option string. */
384 $new_option .= '>' . ($this->htmlencoded ?
$disp_value : htmlspecialchars($disp_value)) . "</option>\n";
386 /* And add the new option string to our select tag. */
387 $result .= $new_option;
390 /* Close the select tag and return our happy result. */
391 $result .= "</select>$this->trailing_text\n";
396 * Create folder selection box
397 * @return string html formated selection box
399 function createWidget_FolderList() {
400 $selected = array(strtolower($this->value
));
402 /* set initial value */
405 /* Add each possible value to the select list. */
406 foreach ($this->possible_values
as $real_value => $disp_value) {
407 if ( is_array($disp_value) ) {
408 /* For folder list, we passed in the array of boxes.. */
409 $new_option = sqimap_mailbox_option_list(0, $selected, 0, $disp_value, $this->folder_filter
);
411 /* Start the next new option string. */
412 $new_option = '<option value="' . htmlspecialchars($real_value) . '"';
414 /* If this value is the current value, select it. */
415 if ($real_value == $this->value
) {
416 $new_option .= ' selected="selected"';
419 /* Add the display value to our option string. */
420 $new_option .= '>' . htmlspecialchars($disp_value) . "</option>\n";
422 /* And add the new option string to our select tag. */
423 $result .= $new_option;
427 if (empty($result)) {
428 // string is displayed when interface can't build folder selection box
429 return _("unavailable");
431 /* Begin the select tag. */
432 $ret = "<select name=\"new_$this->name\" $this->script>\n";
434 /* Close the select tag and return our happy result. */
435 $ret.= "</select>\n";
442 * @return string html formated textarea field
444 function createWidget_TextArea() {
445 switch ($this->size
) {
446 case SMOPT_SIZE_TINY
: $rows = 3; $cols = 10; break;
447 case SMOPT_SIZE_SMALL
: $rows = 4; $cols = 30; break;
448 case SMOPT_SIZE_LARGE
: $rows = 10; $cols = 60; break;
449 case SMOPT_SIZE_HUGE
: $rows = 20; $cols = 80; break;
450 case SMOPT_SIZE_NORMAL
:
451 default: $rows = 5; $cols = 50;
453 //FIXME: we need to change $this->script into $this->aExtraAttribs, and anyone who wants to add some javascript or other attributes to an options widget can put them in an array and pass them as extra attributes (key == attrib name, value == attrib value).... for now, this is the only place it is used, and there is no place in the code that text areas get extra attribs or javascript... in fact the only place that was using $this->script is include/options/display.php:200, so that's easy to change.... just have to go through this file and change all the places that use "script"
454 $this->aExtraAttribs
= array();
455 return addTextArea('new_' . $this->name
, $this->value
, $cols, $rows, $this->aExtraAttribs
);
459 * Creates field for integer
461 * Difference from createWidget_String is visible only when javascript is enabled
462 * @return string html formated option field
464 function createWidget_Integer() {
466 // add onChange javascript handler to a regular string widget
467 // which will strip out all non-numeric chars
468 if (checkForJavascript())
469 return preg_replace('/\/>/', ' onChange="origVal=this.value; newVal=\'\'; '
470 . 'for (i=0;i<origVal.length;i++) { if (origVal.charAt(i)>=\'0\' '
471 . '&& origVal.charAt(i)<=\'9\') newVal += origVal.charAt(i); } '
472 . 'this.value=newVal;" />', $this->createWidget_String());
474 return $this->createWidget_String();
478 * Creates field for floating number
479 * Difference from createWidget_String is visible only when javascript is enabled
480 * @return string html formated option field
482 function createWidget_Float() {
484 // add onChange javascript handler to a regular string widget
485 // which will strip out all non-numeric (period also OK) chars
486 if (checkForJavascript())
487 return preg_replace('/\/>/', ' onChange="origVal=this.value; newVal=\'\'; '
488 . 'for (i=0;i<origVal.length;i++) { if ((origVal.charAt(i)>=\'0\' '
489 . '&& origVal.charAt(i)<=\'9\') || origVal.charAt(i)==\'.\') '
490 . 'newVal += origVal.charAt(i); } this.value=newVal;" />'
491 , $this->createWidget_String());
493 return $this->createWidget_String();
497 * Creates radio field (yes/no)
498 * @return string html formated radio field
500 function createWidget_Boolean() {
501 /* Do the whole current value thing. */
502 if ($this->value
!= SMPREF_NO
) {
503 $yes_chk = ' checked="checked"';
507 $no_chk = ' checked="checked"';
510 /* Build the yes choice. */
511 $yes_option = '<input type="radio" id="new_' . $this->name
. '_yes" '
512 . 'name="new_' . $this->name
. '" value="' . SMPREF_YES
. '"'
513 . $yes_chk . ' ' . $this->script
. ' /> '
514 . '<label for="new_'.$this->name
.'_yes">' . _("Yes") . '</label>';
516 /* Build the no choice. */
517 $no_option = '<input type="radio" id="new_' . $this->name
. '_no" '
518 . 'name="new_' . $this->name
. '" value="' . SMPREF_NO
. '"'
519 . $no_chk . ' ' . $this->script
. ' /> '
520 . '<label for="new_'.$this->name
.'_no">' . _("No") . '</label>';
522 /* Build and return the combined "boolean widget". */
523 $result = "$yes_option $no_option";
528 * Creates hidden field
529 * @return string html formated hidden input field
531 function createWidget_Hidden() {
532 $result = '<input type="hidden" name="new_' . $this->name
533 . '" value="' . htmlspecialchars($this->value
)
534 . '" ' . $this->script
. ' />';
540 * @return string comment
542 function createWidget_Comment() {
543 $result = $this->comment
;
551 $function = $this->save_function
;
559 return ($this->value
!= $this->new_value
);
561 } /* End of SquirrelOption class*/
565 * @param object $option object that holds option name and new_value
567 function save_option($option) {
568 if ( !sqgetGlobalVar('username', $username, SQ_SESSION
) ) {
569 /* Can't save the pref if we don't have the username */
573 setPref($data_dir, $username, $option->name
, $option->new_value
);
577 * save function that does not save
578 * @param object $option
580 function save_option_noop($option) {
581 /* Do nothing here... */
585 * Create hidden 'optpage' input field with value set by argument
586 * @param string $optpage identification of option page
587 * @return string html formated hidden input field
589 function create_optpage_element($optpage) {
590 return create_hidden_element('optpage', $optpage);
594 * Create hidden 'optmode' input field with value set by argument
595 * @param string $optmode
596 * @return string html formated hidden input field
598 function create_optmode_element($optmode) {
599 return create_hidden_element('optmode', $optmode);
603 * Create hidden field.
604 * @param string $name field name
605 * @param string $value field value
606 * @return string html formated hidden input field
608 function create_hidden_element($name, $value) {
609 $result = '<input type="hidden" '
610 . 'name="' . $name . '" '
611 . 'value="' . htmlspecialchars($value) . '" />';
616 * @param array $optgrps
617 * @param array $optvals
620 function create_option_groups($optgrps, $optvals) {
621 /* Build a simple array with which to start. */
624 /* Create option group for each option group name. */
625 foreach ($optgrps as $grpkey => $grpname) {
626 $result[$grpkey] = array();
627 $result[$grpkey]['name'] = $grpname;
628 $result[$grpkey]['options'] = array();
631 /* Create a new SquirrelOption for each set of option values. */
632 foreach ($optvals as $grpkey => $grpopts) {
633 foreach ($grpopts as $optset) {
634 /* Create a new option with all values given. */
635 $next_option = new SquirrelOption(
639 (isset($optset['refresh']) ?
$optset['refresh'] : SMOPT_REFRESH_NONE
),
640 (isset($optset['initial_value']) ?
$optset['initial_value'] : ''),
641 (isset($optset['posvals']) ?
$optset['posvals'] : ''),
642 (isset($optset['htmlencoded']) ?
$optset['htmlencoded'] : false)
645 /* If provided, set the size for this option. */
646 if (isset($optset['size'])) {
647 $next_option->setSize($optset['size']);
650 /* If provided, set the trailing_text for this option. */
651 if (isset($optset['trailing_text'])) {
652 $next_option->setTrailingText($optset['trailing_text']);
655 /* If provided, set the comment for this option. */
656 if (isset($optset['comment'])) {
657 $next_option->setComment($optset['comment']);
660 /* If provided, set the save function for this option. */
661 if (isset($optset['save'])) {
662 $next_option->setSaveFunction($optset['save']);
665 /* If provided, set the script for this option. */
666 if (isset($optset['script'])) {
667 $next_option->setScript($optset['script']);
670 /* If provided, set the "post script" for this option. */
671 if (isset($optset['post_script'])) {
672 $next_option->setPostScript($optset['post_script']);
675 /* If provided, set the folder_filter for this option. */
676 if (isset($optset['folder_filter'])) {
677 $next_option->setFolderFilter($optset['folder_filter']);
680 /* Add this option to the option array. */
681 $result[$grpkey]['options'][] = $next_option;
685 /* Return our resulting array. */