Source for file options.php

Documentation is available at options.php

  1. <?php
  2.  
  3. /**
  4.  * options.php
  5.  *
  6.  * Functions needed to display the options pages.
  7.  *
  8.  * @copyright 1999-2014 The SquirrelMail Project Team
  9.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  10.  * @version $Id: options.php 14422 2014-01-01 20:59:43Z pdontthink $
  11.  * @package squirrelmail
  12.  * @subpackage prefs
  13.  */
  14.  
  15. /**********************************************/
  16. /* Define constants used in the options code. */
  17. /**********************************************/
  18.  
  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);
  29. define('SMOPT_TYPE_FLDRLIST_MULTI'9);
  30. define('SMOPT_TYPE_EDIT_LIST'10);
  31. define('SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE'11);
  32. define('SMOPT_TYPE_STRLIST_MULTI'12);
  33. define('SMOPT_TYPE_BOOLEAN_CHECKBOX'13);
  34. define('SMOPT_TYPE_BOOLEAN_RADIO'14);
  35. define('SMOPT_TYPE_STRLIST_RADIO'15);
  36. define('SMOPT_TYPE_SUBMIT'16);
  37. define('SMOPT_TYPE_INFO'17);
  38. define('SMOPT_TYPE_PASSWORD'18);
  39.  
  40. /* Define constants for the layout scheme for edit lists. */
  41. define('SMOPT_EDIT_LIST_LAYOUT_LIST'0);
  42. define('SMOPT_EDIT_LIST_LAYOUT_SELECT'1);
  43.  
  44. /* Define constants for the options refresh levels. */
  45. define('SMOPT_REFRESH_NONE'0);
  46. define('SMOPT_REFRESH_FOLDERLIST'1);
  47. define('SMOPT_REFRESH_ALL'2);
  48.  
  49. /* Define constants for the options size. */
  50. define('SMOPT_SIZE_TINY'0);
  51. define('SMOPT_SIZE_SMALL'1);
  52. define('SMOPT_SIZE_MEDIUM'2);
  53. define('SMOPT_SIZE_LARGE'3);
  54. define('SMOPT_SIZE_HUGE'4);
  55. define('SMOPT_SIZE_NORMAL'5);
  56.  
  57. define('SMOPT_SAVE_DEFAULT''save_option');
  58. define('SMOPT_SAVE_NOOP''save_option_noop');
  59.  
  60. /**
  61.  * SquirrelOption: An option for Squirrelmail.
  62.  *
  63.  * This class is a work in progress. When complete, it will handle
  64.  * presentation and saving of Squirrelmail user options in a simple,
  65.  * streamline manner. Stay tuned for more stuff.
  66.  *
  67.  * Also, I'd like to ask that people leave this alone (mostly :) until
  68.  * I get it a little further along. That should only be a day or two or
  69.  * three. I will remove this message when it is ready for primetime usage.
  70.  * @package squirrelmail
  71.  */
  72. class SquirrelOption {
  73.     /* The basic stuff. */
  74.     var $raw_option_array;
  75.     var $name;
  76.     var $caption;
  77.     var $caption_wrap;
  78.     var $type;
  79.     var $refresh_level;
  80.     var $size;
  81.     var $layout_type;
  82.     var $comment;
  83.     var $script;
  84.     var $post_script;
  85.     var $trailing_text;
  86.     var $yes_text;
  87.     var $no_text;
  88.     var $use_add_widget;
  89.     var $use_delete_widget;
  90.     var $poss_value_folders;
  91.  
  92.     /* The name of the Save Function for this option. */
  93.     var $save_function;
  94.  
  95.     /* The various 'values' for this options. */
  96.     var $value;
  97.     var $new_value;
  98.     var $possible_values;
  99.     var $htmlencoded=false;
  100.  
  101.     function SquirrelOption
  102.     ($raw_option_array$name$caption$type$refresh_level$initial_value ''$possible_values ''$htmlencoded false{
  103.         /* Set the basic stuff. */
  104.         $this->raw_option_array = $raw_option_array;
  105.         $this->name = $name;
  106.         $this->caption = $caption;
  107.         $this->caption_wrap = TRUE;
  108.         $this->type = $type;
  109.         $this->refresh_level = $refresh_level;
  110.         $this->possible_values = $possible_values;
  111.         $this->htmlencoded = $htmlencoded;
  112. // FIXME: why isn't this set by default to NORMAL?
  113.         $this->size = SMOPT_SIZE_MEDIUM;
  114.         $this->layout_type = 0;
  115.         $this->comment = '';
  116.         $this->script = '';
  117.         $this->post_script = '';
  118.         $this->trailing_text = '';
  119.         $this->yes_text = '';
  120.         $this->no_text = '';
  121.         $this->use_add_widget = TRUE;
  122.         $this->use_delete_widget = TRUE;
  123.         $this->poss_value_folders = '';
  124.  
  125.         /* Check for a current value. */
  126.         if (isset($GLOBALS[$name])) {
  127.             $this->value = $GLOBALS[$name];
  128.         else if (!empty($initial_value)) {
  129.             $this->value = $initial_value;
  130.         else {
  131.             $this->value = '';
  132.         }
  133.  
  134.         /* Check for a new value. */
  135.     if !sqgetGlobalVar("new_$name"$this->new_valueSQ_POST ) ) {
  136.             $this->new_value = NULL;
  137.         }
  138.  
  139.         /* Set the default save function. */
  140.         if ($type != SMOPT_TYPE_HIDDEN
  141.          && $type != SMOPT_TYPE_INFO
  142.          && $type != SMOPT_TYPE_COMMENT{
  143.             $this->save_function = SMOPT_SAVE_DEFAULT;
  144.         else {
  145.             $this->save_function = SMOPT_SAVE_NOOP;
  146.         }
  147.     }
  148.  
  149.     /** Convenience function that identifies which types of
  150.         widgets are stored as (serialized) array values. */
  151.     function is_multiple_valued({
  152.         return ($this->type == SMOPT_TYPE_FLDRLIST_MULTI
  153.              || $this->type == SMOPT_TYPE_STRLIST_MULTI
  154.              || $this->type == SMOPT_TYPE_EDIT_LIST
  155.              || $this->type == SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE);
  156.     }
  157.  
  158.     /* Set the value for this option. */
  159.     function setValue($value{
  160.         $this->value = $value;
  161.     }
  162.  
  163.     /* Set the new value for this option. */
  164.     function setNewValue($new_value{
  165.         $this->new_value = $new_value;
  166.     }
  167.  
  168.     /* Set whether the caption is allowed to wrap for this option. */
  169.     function setCaptionWrap($caption_wrap{
  170.         $this->caption_wrap = $caption_wrap;
  171.     }
  172.  
  173.     /* Set the size for this option. */
  174.     function setSize($size{
  175.         $this->size = $size;
  176.     }
  177.  
  178.     /* Set the trailing text for this option. */
  179.     function setTrailingText($trailing_text{
  180.         $this->trailing_text = $trailing_text;
  181.     }
  182.  
  183.     /* Set the yes text for this option. */
  184.     function setYesText($yes_text{
  185.         $this->yes_text = $yes_text;
  186.     }
  187.  
  188.     /* Set the no text for this option. */
  189.     function setNoText($no_text{
  190.         $this->no_text = $no_text;
  191.     }
  192.  
  193.     /* Set the "use add widget" value for this option. */
  194.     function setUseAddWidget($use_add_widget{
  195.         $this->use_add_widget = $use_add_widget;
  196.     }
  197.  
  198.     /* Set the "use delete widget" value for this option. */
  199.     function setUseDeleteWidget($use_delete_widget{
  200.         $this->use_delete_widget = $use_delete_widget;
  201.     }
  202.  
  203.     /* Set the "poss value folders" value for this option.
  204.        See the associative edit list widget, which uses this
  205.        to offer folder list selection for the values */
  206.     function setPossValueFolders($poss_value_folders{
  207.         $this->poss_value_folders = $poss_value_folders;
  208.     }
  209.  
  210.     /* Set the layout type for this option. */
  211.     function setLayoutType($layout_type{
  212.         $this->layout_type = $layout_type;
  213.     }
  214.  
  215.     /* Set the comment for this option. */
  216.     function setComment($comment{
  217.         $this->comment = $comment;
  218.     }
  219.  
  220.     /* Set the script for this option. */
  221.     function setScript($script{
  222.         $this->script = $script;
  223.     }
  224.  
  225.     /* Set the "post script" for this option. */
  226.     function setPostScript($post_script{
  227.         $this->post_script = $post_script;
  228.     }
  229.  
  230.     /* Set the save function for this option. */
  231.     function setSaveFunction($save_function{
  232.         $this->save_function = $save_function;
  233.     }
  234.  
  235.     function createHTMLWidget({
  236.         global $javascript_on$color;
  237.  
  238.         // Use new value if available
  239.         if (!is_null($this->new_value)) {
  240.             $tempValue $this->value;
  241.             $this->value = $this->new_value;
  242.         }
  243.  
  244.         /* Get the widget for this option type. */
  245.         switch ($this->type{
  246.             case SMOPT_TYPE_STRING:
  247.                 $result $this->createWidget_String();
  248.                 break;
  249.             case SMOPT_TYPE_PASSWORD:
  250.                 $result $this->createWidget_String(TRUE);
  251.                 break;
  252.             case SMOPT_TYPE_STRLIST:
  253.                 $result $this->createWidget_StrList();
  254.                 break;
  255.             case SMOPT_TYPE_TEXTAREA:
  256.                 $result $this->createWidget_TextArea();
  257.                 break;
  258.             case SMOPT_TYPE_INTEGER:
  259.                 $result $this->createWidget_Integer();
  260.                 break;
  261.             case SMOPT_TYPE_FLOAT:
  262.                 $result $this->createWidget_Float();
  263.                 break;
  264.             case SMOPT_TYPE_BOOLEAN:
  265.                 $result $this->createWidget_Boolean();
  266.                 break;
  267.             case SMOPT_TYPE_BOOLEAN_CHECKBOX:
  268.                 $result $this->createWidget_Boolean(TRUE);
  269.                 break;
  270.             case SMOPT_TYPE_BOOLEAN_RADIO:
  271.                 $result $this->createWidget_Boolean(FALSE);
  272.                 break;
  273.             case SMOPT_TYPE_HIDDEN:
  274.                 $result $this->createWidget_Hidden();
  275.                 break;
  276.             case SMOPT_TYPE_COMMENT:
  277.                 $result $this->createWidget_Comment();
  278.                 break;
  279.             case SMOPT_TYPE_FLDRLIST:
  280.                 $result $this->createWidget_FolderList();
  281.                 break;
  282.             case SMOPT_TYPE_FLDRLIST_MULTI:
  283.                 $result $this->createWidget_FolderList(TRUE);
  284.                 break;
  285.             case SMOPT_TYPE_EDIT_LIST:
  286.                 $result $this->createWidget_EditList();
  287.                 break;
  288.             case SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE:
  289.                 $result $this->createWidget_EditListAssociative();
  290.                 break;
  291.             case SMOPT_TYPE_STRLIST_MULTI:
  292.                 $result $this->createWidget_StrList(TRUE);
  293.                 break;
  294.             case SMOPT_TYPE_STRLIST_RADIO:
  295.                 $result $this->createWidget_StrList(FALSETRUE);
  296.                 break;
  297.             case SMOPT_TYPE_SUBMIT:
  298.                 $result $this->createWidget_Submit();
  299.                 break;
  300.             case SMOPT_TYPE_INFO:
  301.                 $result $this->createWidget_Info();
  302.                 break;
  303.             default:
  304.                $result '<font color="' $color[2'">'
  305.                        . sprintf(_("Option Type '%s' Not Found")$this->type)
  306.                        . '</font>';
  307.         }
  308.  
  309.         /* Add the "post script" for this option. */
  310.         $result .= $this->post_script;
  311.  
  312.         // put correct value back if need be
  313.         if (!is_null($this->new_value)) {
  314.             $this->value = $tempValue;
  315.         }
  316.  
  317.         /* Now, return the created widget. */
  318.         return $result;
  319.     }
  320.  
  321.     function createWidget_Info({
  322.         $result sm_encode_html_special_chars($this->value"\n";
  323.         return $result;
  324.     }
  325.  
  326.     /**
  327.      * Create text box
  328.      *
  329.      * @param boolean $password When TRUE, the text in the input
  330.      *                           widget will be obscured (OPTIONAL;
  331.      *                           default = FALSE).
  332.      *
  333.      * @return string html formated text input
  334.      *
  335.      */
  336.     function createWidget_String($password=FALSE{
  337.         switch ($this->size{
  338.             case SMOPT_SIZE_TINY:
  339.                 $width 5;
  340.                 break;
  341.             case SMOPT_SIZE_SMALL:
  342.                 $width 12;
  343.                 break;
  344.             case SMOPT_SIZE_LARGE:
  345.                 $width 38;
  346.                 break;
  347.             case SMOPT_SIZE_HUGE:
  348.                 $width 50;
  349.                 break;
  350.             case SMOPT_SIZE_NORMAL:
  351.             default:
  352.                 $width 25;
  353.         }
  354.  
  355.         $result "<input type=\"" 
  356.                 . ($password 'password' 'text'
  357.                 . "\" name=\"new_$this->name\" value=\""
  358.                 . sm_encode_html_special_chars($this->value)
  359.                 . "\" size=\"$width\" $this->script /> 
  360.                 . sm_encode_html_special_chars($this->trailing_text"\n";
  361.         return $result;
  362.     }
  363.  
  364.     /**
  365.      * Create selection box or radio group
  366.      *
  367.      * When $this->htmlencoded is TRUE, the keys and values in
  368.      * $this->possible_values are assumed to be display-safe.
  369.      * Use with care!
  370.      *
  371.      * Note that when building radio buttons instead of a select
  372.      * widget, if the "size" attribute is SMOPT_SIZE_TINY, the
  373.      * radio buttons will be output one after another without
  374.      * linebreaks between them.  Otherwise, each radio button
  375.      * goes on a line of its own.
  376.      *
  377.      * @param boolean $multiple_select When TRUE, the select widget
  378.      *                                  will allow multiple selections
  379.      *                                  (OPTIONAL; default is FALSE
  380.      *                                  (single select list))
  381.      * @param boolean $radio_buttons   When TRUE, the widget will
  382.      *                                  instead be built as a group
  383.      *                                  of radio buttons (and
  384.      *                                  $multiple_select will be
  385.      *                                  forced to FALSE) (OPTIONAL;
  386.      *                                  default is FALSE (select widget))
  387.      *
  388.      * @return string html formated selection box or radio buttons
  389.      *
  390.      */
  391.     function createWidget_StrList($multiple_select=FALSE$radio_buttons=FALSE{
  392.  
  393.         // radio buttons instead of select widget?
  394.         //
  395.         if ($radio_buttons{
  396.  
  397.             $result '';
  398.             foreach ($this->possible_values as $real_value => $disp_value{
  399.                 $result .= "\n" '<input type="radio" name="new_' $this->name 
  400.                          . '" id="new_' $this->name . '_' 
  401.                          . ($this->htmlencoded ? $real_value sm_encode_html_special_chars($real_value))
  402.                          . '" value="'
  403.                          . ($this->htmlencoded ? $real_value sm_encode_html_special_chars($real_value))
  404.                          . '"' ($real_value == $this->value ? ' checked="checked"' '')
  405.                          . ' /> <label for="new_' $this->name . '_'
  406.                          . ($this->htmlencoded ? $real_value sm_encode_html_special_chars($real_value))
  407.                          . '">'
  408.                          . ($this->htmlencoded ? $disp_value sm_encode_html_special_chars($disp_value))
  409.                          . '</label>';
  410.                 if ($this->size != SMOPT_SIZE_TINY)
  411.                     $result .= '<br />';
  412.             }
  413.  
  414.             return $result;
  415.         }
  416.  
  417.  
  418.         // everything below applies to select widgets
  419.         //
  420.         switch ($this->size{
  421. //FIXME: not sure about these sizes... seems like we could add another on the "large" side...
  422.             case SMOPT_SIZE_TINY:
  423.                 $height 3;
  424.                 break;
  425.             case SMOPT_SIZE_SMALL:
  426.                 $height 8;
  427.                 break;
  428.             case SMOPT_SIZE_LARGE:
  429.                 $height 15;
  430.                 break;
  431.             case SMOPT_SIZE_HUGE:
  432.                 $height 25;
  433.                 break;
  434.             case SMOPT_SIZE_NORMAL:
  435.             default:
  436.                 $height 5;
  437.         }
  438.  
  439.         // multiple select lists should already have array values
  440.         if (is_array($this->value))
  441.             $selected $this->value;
  442.         else
  443.             $selected array(strtolower($this->value));
  444.  
  445.         /* Begin the select tag. */
  446.         $result '<select name="new_' $this->name
  447.             . ($multiple_select '[]" multiple="multiple" size="' $height '" ' '" ')
  448.             . $this->script . ">\n";
  449.  
  450.         /* Add each possible value to the select list. */
  451.         foreach ($this->possible_values as $real_value => $disp_value{
  452.             /* Start the next new option string. */
  453.             $new_option '<option value="' .
  454.                 ($this->htmlencoded ? $real_value sm_encode_html_special_chars($real_value)) '"';
  455.  
  456.             // multiple select lists have possibly more than one default selection
  457.             if ($multiple_select{
  458.                 foreach ($selected as $default{
  459.                     if ((string)$default == (string)$real_value{
  460.                         $new_option .= ' selected="selected"';
  461.                         break;
  462.                     }
  463.                 }
  464.             }
  465.  
  466.             /* If this value is the current value, select it. */
  467.             else if ($real_value == $this->value{
  468.                $new_option .= ' selected="selected"';
  469.             }
  470.  
  471.             /* Add the display value to our option string. */
  472.             $new_option .= '>' ($this->htmlencoded ? $disp_value sm_encode_html_special_chars($disp_value)) "</option>\n";
  473.             /* And add the new option string to our select tag. */
  474.             $result .= $new_option;
  475.         }
  476.  
  477.         /* Close the select tag and return our happy result. */
  478.         $result .= '</select>' sm_encode_html_special_chars($this->trailing_text"\n";
  479.         return $result;
  480.     }
  481.  
  482.     /**
  483.      * Create folder selection box
  484.      *
  485.      * @param boolean $multiple_select When TRUE, the select widget
  486.      *                                  will allow multiple selections
  487.      *                                  (OPTIONAL; default is FALSE
  488.      *                                  (single select list))
  489.      *
  490.      * @return string html formated selection box
  491.      *
  492.      */
  493.     function createWidget_FolderList($multiple_select=FALSE{
  494.  
  495.         switch ($this->size{
  496. //FIXME: not sure about these sizes... seems like we could add another on the "large" side...
  497.             case SMOPT_SIZE_TINY:
  498.                 $height 3;
  499.                 break;
  500.             case SMOPT_SIZE_SMALL:
  501.                 $height 8;
  502.                 break;
  503.             case SMOPT_SIZE_LARGE:
  504.                 $height 15;
  505.                 break;
  506.             case SMOPT_SIZE_HUGE:
  507.                 $height 25;
  508.                 break;
  509.             case SMOPT_SIZE_NORMAL:
  510.             default:
  511.                 $height 5;
  512.         }
  513.  
  514.         // multiple select lists should already have array values
  515.         if (is_array($this->value))
  516.             $selected $this->value;
  517.         else
  518.             $selected array(strtolower($this->value));
  519.  
  520.         /* Begin the select tag. */
  521.         $result '<select name="new_' $this->name
  522.                 . ($multiple_select '[]" multiple="multiple" size="' $height '"' '"')
  523.                 . " $this->script>\n";
  524.  
  525.         /* Add each possible value to the select list. */
  526.         foreach ($this->possible_values as $real_value => $disp_value{
  527.  
  528.             if is_array($disp_value) ) {
  529.                 /* For folder list, we passed in the array of boxes.. */
  530.                 $selected_lowercase array();
  531.                 foreach ($selected as $i => $box
  532.                     $selected_lowercase[$istrtolower($box);
  533.                 $new_option sqimap_mailbox_option_list(0$selected_lowercase0$disp_value);
  534.  
  535.             else {
  536.                 /* Start the next new option string. */
  537.                 $new_option '<option value="' sm_encode_html_special_chars($real_value'"';
  538.  
  539.                 // multiple select lists have possibly more than one default selection
  540.                 if ($multiple_select{
  541.                     foreach ($selected as $default{
  542.                         if ((string)$default == (string)$real_value{
  543.                             $new_option .= ' selected="selected"';
  544.                             break;
  545.                         }
  546.                     }
  547.                 }
  548.  
  549.                 /* If this value is the current value, select it. */
  550.                 else if ($real_value == $this->value{
  551.                    $new_option .= ' selected="selected"';
  552.                 }
  553.  
  554.                 /* Add the display value to our option string. */
  555.                 $new_option .= '>' sm_encode_html_special_chars($disp_value"</option>\n";
  556.             }
  557.             /* And add the new option string to our select tag. */
  558.             $result .= $new_option;
  559.         }
  560.         /* Close the select tag and return our happy result. */
  561.         $result .= '</select>' sm_encode_html_special_chars($this->trailing_text"\n";
  562.         return $result;
  563.     }
  564.  
  565.  
  566.     function createWidget_TextArea({
  567.         switch ($this->size{
  568.             case SMOPT_SIZE_TINY:  $rows 3$cols =  10break;
  569.             case SMOPT_SIZE_SMALL$rows 4$cols =  30break;
  570.             case SMOPT_SIZE_LARGE$rows 10$cols =  60break;
  571.             case SMOPT_SIZE_HUGE:  $rows 20$cols =  80break;
  572.             case SMOPT_SIZE_NORMAL:
  573.             default$rows 5$cols =  50;
  574.         }
  575.         $result "<textarea name=\"new_$this->name\" rows=\"$rows\" "
  576.                 . "cols=\"$cols\" $this->script>"
  577.                 . sm_encode_html_special_chars($this->value"</textarea>\n";
  578.         return ($result);
  579.     }
  580.  
  581.     function createWidget_Integer({
  582.  
  583.         global $javascript_on;
  584.  
  585.         // add onChange javascript handler to a regular string widget
  586.         // which will strip out all non-numeric chars
  587.         if ($javascript_on)
  588.            return preg_replace('/\/>/'' onChange="origVal=this.value; newVal=\'\'; '
  589.                     . 'for (i=0;i<origVal.length;i++) { if (origVal.charAt(i)>=\'0\' '
  590.                     . '&& origVal.charAt(i)<=\'9\') newVal += origVal.charAt(i); } '
  591.                     . 'this.value=newVal;" />'$this->createWidget_String());
  592.         else
  593.            return $this->createWidget_String();
  594.     }
  595.  
  596.     function createWidget_Float({
  597.  
  598.         global $javascript_on;
  599.  
  600.         // add onChange javascript handler to a regular string widget
  601.         // which will strip out all non-numeric (period also OK) chars
  602.         if ($javascript_on)
  603.            return preg_replace('/\/>/'' onChange="origVal=this.value; newVal=\'\'; '
  604.                     . 'for (i=0;i<origVal.length;i++) { if ((origVal.charAt(i)>=\'0\' '
  605.                     . '&& origVal.charAt(i)<=\'9\') || origVal.charAt(i)==\'.\') '
  606.                     . 'newVal += origVal.charAt(i); } this.value=newVal;" />'
  607.                 $this->createWidget_String());
  608.         else
  609.            return $this->createWidget_String();
  610.     }
  611.  
  612.     /**
  613.      * Create boolean widget
  614.      *
  615.      * When creating Yes/No radio buttons, the "yes_text"
  616.      * and "no_text" option attributes are used to override
  617.      * the typical "Yes" and "No" text.
  618.      *
  619.      * @param boolean $checkbox When TRUE, the widget will be
  620.      *                           constructed as a checkbox,
  621.      *                           otherwise it will be a set of
  622.      *                           Yes/No radio buttons (OPTIONAL;
  623.      *                           default is TRUE (checkbox)).
  624.      *
  625.      * @return string html formated boolean widget
  626.      *
  627.      */
  628.     function createWidget_Boolean($checkbox=TRUE{
  629.         /* Do the whole current value thing. */
  630.         if ($this->value != SMPREF_NO{
  631.             $yes_chk ' checked="checked"';
  632.             $no_chk '';
  633.         else {
  634.             $yes_chk '';
  635.             $no_chk ' checked="checked"';
  636.         }
  637.  
  638.         // checkbox...
  639.         //
  640.         if ($checkbox{
  641.             $result '<input type="checkbox" name="new_' $this->name
  642.                     . '" id="new_' $this->name . '" value="' SMPREF_YES
  643.                     . "\" $yes_chk $this->script . ' />&nbsp;'
  644.                     . '<label for="new_' $this->name . '">' 
  645.                     . sm_encode_html_special_chars($this->trailing_text'</label>';
  646.         }
  647.  
  648.         // radio buttons...
  649.         //
  650.         else {
  651.  
  652.             /* Build the yes choice. */
  653.             $yes_option '<input type="radio" name="new_' $this->name 
  654.                         . '" id="new_' $this->name . '_yes"'
  655.                         . ' value="' SMPREF_YES "\"$yes_chk $this->script />&nbsp;"
  656.                         . '<label for="new_' $this->name . '_yes">' (!empty($this->yes_textsm_encode_html_special_chars($this->yes_text_("Yes")) '</label>';
  657.  
  658.             /* Build the no choice. */
  659.             $no_option '<input type="radio" name="new_' $this->name
  660.                        . '" id="new_' $this->name . '_no"'
  661.                        . ' value="' SMPREF_NO "\"$no_chk $this->script />&nbsp;"
  662.                        . '<label for="new_' $this->name . '_no">' (!empty($this->no_textsm_encode_html_special_chars($this->no_text_("No")) '</label>';
  663.     
  664.             /* Build the combined "boolean widget". */
  665.             $result "$yes_option&nbsp;&nbsp;&nbsp;&nbsp;$no_option";
  666.  
  667.         }
  668.  
  669.         return ($result);
  670.     }
  671.  
  672.     function createWidget_Hidden({
  673.         $result '<input type="hidden" name="new_' $this->name
  674.                 . '" value="' sm_encode_html_special_chars($this->value)
  675.                 . '" ' $this->script . ' />';
  676.         return ($result);
  677.     }
  678.  
  679.     function createWidget_Comment({
  680.         $result $this->comment;
  681.         return ($result);
  682.     }
  683.  
  684.     /**
  685.      * Creates a (non-associative) edit list
  686.      *
  687.      * Note that multiple layout types are supported for this widget.
  688.      * $this->layout_type must be one of the SMOPT_EDIT_LIST_LAYOUT_*
  689.      * constants.
  690.      *
  691.      * @return string html formated list of edit fields and
  692.      *                 their associated controls
  693.      */
  694.     function createWidget_EditList({
  695.  
  696.         switch ($this->size{
  697.             case SMOPT_SIZE_TINY:
  698.                 $height 3;
  699.                 break;
  700.             case SMOPT_SIZE_SMALL:
  701.                 $height 8;
  702.                 break;
  703.             case SMOPT_SIZE_MEDIUM:
  704.                 $height 15;
  705.                 break;
  706.             case SMOPT_SIZE_LARGE:
  707.                 $height 25;
  708.                 break;
  709.             case SMOPT_SIZE_HUGE:
  710.                 $height 40;
  711.                 break;
  712.             case SMOPT_SIZE_NORMAL:
  713.             default:
  714.                 $height 5;
  715.         }
  716.  
  717.  
  718.         // ensure correct format of current value(s)
  719.         //
  720.         if (empty($this->possible_values)) $this->possible_values = array();
  721.         if (!is_array($this->possible_values)) $this->possible_values = array($this->possible_values);
  722.  
  723.  
  724.         global $javascript_on$color;
  725.  
  726.         switch ($this->layout_type{
  727.             case SMOPT_EDIT_LIST_LAYOUT_SELECT:
  728.                 $result '';
  729.                 if ($this->use_add_widget)
  730.                     $result .= _("Add"'&nbsp;<input name="add_' $this->name 
  731.                              . '" size="38" /><br />';
  732.                 $result .= '<select name="new_' $this->name
  733.                     . '[]" multiple="multiple" size="' $height '"'
  734.                     . ($javascript_on ' onchange="if (typeof(window.addinput_' $this->name . ') == \'undefined\') { var f = document.forms.length; var i = 0; var pos = -1; while( pos == -1 && i < f ) { var e = document.forms[i].elements.length; var j = 0; while( pos == -1 && j < e ) { if ( document.forms[i].elements[j].type == \'text\' && document.forms[i].elements[j].name == \'add_' $this->name . '\' ) { pos = j; i=f-1; j=e-1; } j++; } i++; } if( pos >= 0 ) { window.addinput_' $this->name . ' = document.forms[i-1].elements[pos]; } } for (x = 0; x < this.length; x++) { if (this.options[x].selected) { window.addinput_' $this->name . '.value = this.options[x].text; break; } }"' '')
  735. // NOTE: i=f-1; j=e-1 is in lieu of break 2
  736.                     . ' ' $this->script . ">\n";
  737.  
  738.  
  739.                 if (is_array($this->value))
  740.                     $selected $this->value;
  741.                 else
  742.                     $selected array($this->value);
  743.  
  744.  
  745.                 // Add each possible value to the select list.
  746.                 //
  747.                 foreach ($this->possible_values as $value{
  748.  
  749.                     // Start the next new option string.
  750.                     //
  751.                     $result .= '<option value="' sm_encode_html_special_chars($value'"';
  752.  
  753.                     // having a selected item in the edit list doesn't have
  754.                     // any meaning, but maybe someone will think of a way to
  755.                     // use it, so we might as well put the code in
  756.                     //
  757.                     foreach ($selected as $default{
  758.                         if ((string)$default == (string)$value{
  759.                             $result .= ' selected="selected"';
  760.                             break;
  761.                         }
  762.                     }
  763.  
  764.                     // Add the display value to our option string.
  765.                     //
  766.                     $result .= '>' sm_encode_html_special_chars($value"</option>\n";
  767.  
  768.                 }
  769.  
  770.                 $result .= '</select>';
  771.                 if (!empty($this->possible_values&& $this->use_delete_widget)
  772.                     $result .= '<br /><input type="checkbox" name="delete_' 
  773.                              . $this->name . '" id="delete_' $this->name 
  774.                              . '" value="1" />&nbsp;<label for="delete_'
  775.                              . $this->name . '">' _("Delete Selected")
  776.                              . '</label>';
  777.  
  778.                 break;
  779.  
  780.  
  781.  
  782.             case SMOPT_EDIT_LIST_LAYOUT_LIST:
  783.                 $result '<table width="80%" cellpadding="1" cellspacing="0" border="0" bgcolor="'
  784.                         . $color[0'"><tr><td>';
  785.                 if ($this->use_add_widget)
  786.                     $result .= _("Add"'&nbsp;<input name="add_' $this->name 
  787.                              . '" size="38" /><br />';
  788.                 $result .= '<table width="100%" cellpadding="1" cellspacing="0" border="0" bgcolor="' $color[5'">';
  789.  
  790.                 $bgcolor 4;
  791.                 if (!isset($color[12]))
  792.                     $color[12'#EAEAEA';
  793.                 $index 0;
  794.  
  795.                 if (is_array($this->value))
  796.                     $selected $this->value;
  797.                 else
  798.                     $selected array($this->value);
  799.  
  800.                 foreach ($this->possible_values as $key => $value{
  801.  
  802.                     if ($bgcolor == 4$bgcolor 12;
  803.                     else $bgcolor 4;
  804.  
  805.                     $result .= '<tr bgcolor="' $color[$bgcolor'">'
  806.                              . '<td width="1%"><input type="checkbox" name="new_'
  807.                              . $this->name . '[' ($index++']" id="' $this->name
  808.                              . '_list_item_' $key '" value="'
  809.                              . sm_encode_html_special_chars($value);
  810.  
  811.                     // having a selected item in the edit list doesn't have
  812.                     // any meaning, but maybe someone will think of a way to
  813.                     // use it, so we might as well put the code in
  814.                     //
  815.                     foreach ($selected as $default{
  816.                         if ((string)$default == (string)$value{
  817.                             $result .= '" checked="checked';
  818.                             break;
  819.                         }
  820.                     }
  821.  
  822.                     $result .= '"></td>'
  823.                              . '<td><label for="' $this->name . '_list_item_' $key
  824.                              . '">' sm_encode_html_special_chars($value'</label></td>'
  825.                              . "</tr>\n";
  826.  
  827.                 }
  828.  
  829.                 $result .= '</table>';
  830.  
  831.                 if (!empty($this->possible_values&& $this->use_delete_widget)
  832.                     $result .= '<input type="checkbox" name="delete_' 
  833.                         . $this->name . '" id="delete_' $this->name 
  834.                         . '" value="1" />&nbsp;<label for="delete_' $this->name . '">'
  835.                         . _("Delete Selected"'</label>';
  836.  
  837.                 $result .= '</td></tr></table>';
  838.  
  839.                 break;
  840.  
  841.  
  842.             default:
  843.                 $result '<font color="' $color[2'">'
  844.                         . sprintf(_("Edit List Layout Type '%s' Not Found")$this->layout_type)
  845.                         . '</font>';
  846.         }
  847.  
  848.         return $result;
  849.  
  850.     }
  851.  
  852.     /**
  853.      * Creates an associative edit list
  854.      *
  855.      * Note that multiple layout types are supported for this widget.
  856.      * $this->layout_type must be one of the SMOPT_EDIT_LIST_LAYOUT_*
  857.      * constants.
  858.      *
  859.      * @return string html formated list of edit fields and
  860.      *                 their associated controls
  861.      */
  862.     function createWidget_EditListAssociative({
  863.  
  864.         switch ($this->size{
  865.             case SMOPT_SIZE_TINY:
  866.                 $height 3;
  867.                 break;
  868.             case SMOPT_SIZE_SMALL:
  869.                 $height 8;
  870.                 break;
  871.             case SMOPT_SIZE_MEDIUM:
  872.                 $height 15;
  873.                 break;
  874.             case SMOPT_SIZE_LARGE:
  875.                 $height 25;
  876.                 break;
  877.             case SMOPT_SIZE_HUGE:
  878.                 $height 40;
  879.                 break;
  880.             case SMOPT_SIZE_NORMAL:
  881.             default:
  882.                 $height 5;
  883.         }
  884.  
  885.  
  886.         // ensure correct format of current value(s)
  887.         //
  888.         if (empty($this->possible_values)) $this->possible_values = array();
  889.         if (!is_array($this->possible_values)) $this->possible_values = array($this->possible_values);
  890.  
  891.  
  892.         global $javascript_on$color;
  893.  
  894.         switch ($this->layout_type{
  895.             case SMOPT_EDIT_LIST_LAYOUT_SELECT:
  896.                 $result '';
  897.                 if ($this->use_add_widget{
  898. //FIXME implement poss_key_folders here? probably not worth the trouble, is there a use case?
  899.                     $result .= _("Add"'&nbsp;<input name="add_' $this->name 
  900.                              . '_key" size="22" /> ';
  901. // FIXME: shall we allow these "poss value folders" (folder list selection for edit list values) for NON-Associative EDIT_LIST widgets?
  902.                     if ($this->poss_value_folders{
  903.                         $result .= '<select name="add_' $this->name . '_value">';
  904.  
  905.                         /* Add each possible value to the select list. */
  906.                         foreach ($this->poss_value_folders as $real_value => $disp_value{
  907.  
  908.                             if is_array($disp_value) ) {
  909.                                 /* For folder list, we passed in the array of boxes.. */
  910.                                 $new_option sqimap_mailbox_option_list(000$disp_value);
  911.  
  912.                             else {
  913.                                 /* Start the next new option string. */
  914.                                 $new_option '<option value="' sm_encode_html_special_chars($real_value'"';
  915.  
  916.                                 /* Add the display value to our option string. */
  917.                                 $new_option .= '>' sm_encode_html_special_chars($disp_value"</option>\n";
  918.                             }
  919.                             /* And add the new option string to our select tag. */
  920.                             $result .= $new_option;
  921.                         }
  922.                         /* Close the select tag and return our happy result. */
  923.                         $result .= '</select>';
  924.                     }
  925.                     else
  926.                         $result .= '<input name="add_' $this->name
  927.                                  . '_value" size="12" /><br />';
  928.                 }
  929.                 $result .= '<select name="new_' $this->name
  930.                     . '[]" multiple="multiple" size="' $height '"'
  931. // FIXME: this can be fooled by having the delimiter " = " in a key value - in general, we may want to use a different delimiter other than " = "
  932.                     . ($javascript_on ' onchange="if (typeof(window.addinput_key_' $this->name . ') == \'undefined\') { var f = document.forms.length; var i = 0; var pos = -1; while( pos == -1 && i < f ) { var e = document.forms[i].elements.length; var j = 0; while( pos == -1 && j < e ) { if ( document.forms[i].elements[j].type == \'text\' && document.forms[i].elements[j].name == \'add_' $this->name . '_key\' ) { pos = j; j=e-1; i=f-1; } j++; } i++; } if( pos >= 0 ) { window.addinput_key_' $this->name . ' = document.forms[i-1].elements[pos]; } } if (typeof(window.addinput_value_' $this->name . ') == \'undefined\') { var f = document.forms.length; var i = 0; var pos = -1; while( pos == -1 && i < f ) { var e = document.forms[i].elements.length; var j = 0; while( pos == -1 && j < e ) { if ( document.forms[i].elements[j].type == \'text\' && document.forms[i].elements[j].name == \'add_' $this->name . '_value\' ) { pos = j; j=e-1; i=f-1; } j++; } i++; } if( pos >= 0 ) { window.addinput_value_' $this->name . ' = document.forms[i-1].elements[pos]; } } for (x = 0; x < this.length; x++) { if (this.options[x].selected) { pos = this.options[x].text.indexOf(\' = \'); if (pos > -1) { window.addinput_key_' $this->name . '.value = this.options[x].text.substr(0, pos); if (typeof(window.addinput_value_' $this->name . ') != \'undefined\') window.addinput_value_' $this->name . '.value = this.options[x].text.substr(pos + 3); } break; } }"' '')
  933. // NOTE: i=f-1; j=e-1 is in lieu of break 2
  934.                     . ' ' $this->script . ">\n";
  935.  
  936.  
  937.                 if (is_array($this->value))
  938.                     $selected $this->value;
  939.                 else
  940.                     $selected array($this->value);
  941.  
  942.  
  943.                 // Add each possible value to the select list.
  944.                 //
  945.                 foreach ($this->possible_values as $key => $value{
  946.  
  947.                     // Start the next new option string.
  948.                     //
  949.                     $result .= '<option value="' urlencode($key'"';
  950.  
  951.                     // having a selected item in the edit list doesn't have
  952.                     // any meaning, but maybe someone will think of a way to
  953.                     // use it, so we might as well put the code in
  954.                     //
  955.                     foreach ($selected as $default{
  956.                         if ((string)$default == (string)$key{
  957.                             $result .= ' selected="selected"';
  958.                             break;
  959.                         }
  960.                     }
  961.  
  962.                     // Add the display value to our option string.
  963.                     //
  964.                     $result .= '>' sm_encode_html_special_chars($key' = ';
  965.                     if ($this->poss_value_folders{
  966.                         foreach ($this->poss_value_folders as $real_value => $disp_value{
  967.                             if is_array($disp_value) ) {
  968.                                 foreach ($disp_value as $folder_info{
  969.                                     if ($value == $folder_info['unformatted']{
  970.                                         $result .= sm_encode_html_special_chars(str_replace('&nbsp;'''$folder_info['formatted']));
  971.                                         break 2;
  972.                                     }
  973.                                 }
  974.                             }
  975.                             else
  976.                                 if ($value == $disp_value{
  977.                                     $result .= sm_encode_html_special_chars($disp_value);
  978.                                     break;
  979.                                 }
  980.                         }
  981.                     }
  982.                     else
  983.                         $result .= sm_encode_html_special_chars($value);
  984.                     $result .= "</option>\n";
  985.  
  986.                 }
  987.  
  988.                 $result .= '</select>';
  989.                 if (!empty($this->possible_values&& $this->use_delete_widget)
  990.                     $result .= '<br /><input type="checkbox" name="delete_' 
  991.                              . $this->name . '" id="delete_' $this->name 
  992.                              . '" value="1" />&nbsp;<label for="delete_'
  993.                              . $this->name . '">' _("Delete Selected")
  994.                              . '</label>';
  995.  
  996.                 break;
  997.  
  998.  
  999.  
  1000.             case SMOPT_EDIT_LIST_LAYOUT_LIST:
  1001.                 $result '<table width="80%" cellpadding="1" cellspacing="0" border="0" bgcolor="'
  1002.                         . $color[0'"><tr><td>';
  1003.                 if ($this->use_add_widget{
  1004. //FIXME implement poss_key_folders here? probably not worth the trouble, is there a use case?
  1005.                     $result .= _("Add"'&nbsp;<input name="add_' $this->name 
  1006.                              . '_key" size="22" /> ';
  1007.                     if ($this->poss_value_folders{
  1008.                         $result .= '<select name="add_' $this->name . '_value">';
  1009.  
  1010.                         /* Add each possible value to the select list. */
  1011.                         foreach ($this->poss_value_folders as $real_value => $disp_value{
  1012.  
  1013.                             if is_array($disp_value) ) {
  1014.                                 /* For folder list, we passed in the array of boxes.. */
  1015.                                 $new_option sqimap_mailbox_option_list(000$disp_value);
  1016.  
  1017.                             else {
  1018.                                 /* Start the next new option string. */
  1019.                                 $new_option '<option value="' sm_encode_html_special_chars($real_value'"';
  1020.  
  1021.                                 /* Add the display value to our option string. */
  1022.                                 $new_option .= '>' sm_encode_html_special_chars($disp_value"</option>\n";
  1023.                             }
  1024.                             /* And add the new option string to our select tag. */
  1025.                             $result .= $new_option;
  1026.                         }
  1027.                         /* Close the select tag and return our happy result. */
  1028.                         $result .= '</select>';
  1029.                     }
  1030.                     else
  1031.                         $result .= '<input name="add_' $this->name
  1032.                                  . '_value" size="12" /><br />';
  1033.                 }
  1034.                 $result .= '<table width="100%" cellpadding="1" cellspacing="0" border="0" bgcolor="' $color[5'">';
  1035.  
  1036.                 $bgcolor 4;
  1037.                 if (!isset($color[12]))
  1038.                     $color[12'#EAEAEA';
  1039.  
  1040.                 if (is_array($this->value))
  1041.                     $selected $this->value;
  1042.                 else
  1043.                     $selected array($this->value);
  1044.  
  1045.                 foreach ($this->possible_values as $key => $value{
  1046.  
  1047.                     if ($bgcolor == 4$bgcolor 12;
  1048.                     else $bgcolor 4;
  1049.  
  1050.                     $result .= '<tr bgcolor="' $color[$bgcolor'">'
  1051.                              . '<td width="1%"><input type="checkbox" name="new_'
  1052.                              . $this->name . '[' urlencode($key']" id="'
  1053.                              . $this->name . '_list_item_' urlencode($key)
  1054.                              . '" value="' sm_encode_html_special_chars($value);
  1055.  
  1056.                     // having a selected item in the edit list doesn't have
  1057.                     // any meaning, but maybe someone will think of a way to
  1058.                     // use it, so we might as well put the code in
  1059.                     //
  1060.                     foreach ($selected as $default{
  1061.                         if ((string)$default == (string)$key{
  1062.                             $result .= '" checked="checked';
  1063.                             break;
  1064.                         }
  1065.                     }
  1066.  
  1067.                     $result .= '"></td>'
  1068.                              . '<td><label for="' $this->name . '_list_item_'
  1069.                              . urlencode($key'">'
  1070.                              . sm_encode_html_special_chars($key' = ';
  1071.                     if ($this->poss_value_folders{
  1072.                         foreach ($this->poss_value_folders as $real_value => $disp_value{
  1073.                             if is_array($disp_value) ) {
  1074.                                 foreach ($disp_value as $folder_info{
  1075.                                     if ($value == $folder_info['unformatted']{
  1076.                                         $result .= sm_encode_html_special_chars(str_replace('&nbsp;'''$folder_info['formatted']));
  1077.                                         break 2;
  1078.                                     }
  1079.                                 }
  1080.                             }
  1081.                             else
  1082.                                 if ($value == $disp_value{
  1083.                                     $result .= sm_encode_html_special_chars($disp_value);
  1084.                                     break;
  1085.                                 }
  1086.                         }
  1087.                     }
  1088.                     else
  1089.                         $result .= sm_encode_html_special_chars($value);
  1090.                     $result .= '</label></td>'
  1091.                              . "</tr>\n";
  1092.  
  1093.                 }
  1094.  
  1095.                 $result .= '</table>';
  1096.  
  1097.                 if (!empty($this->possible_values&& $this->use_delete_widget)
  1098.                     $result .= '<input type="checkbox" name="delete_' 
  1099.                         . $this->name . '" id="delete_' $this->name 
  1100.                         . '" value="1" />&nbsp;<label for="delete_' $this->name . '">'
  1101.                         . _("Delete Selected"'</label>';
  1102.  
  1103.                 $result .= '</td></tr></table>';
  1104.  
  1105.                 break;
  1106.  
  1107.  
  1108.             default:
  1109.                 $result '<font color="' $color[2'">'
  1110.                         . sprintf(_("Edit List Layout Type '%s' Not Found")$this->layout_type)
  1111.                         . '</font>';
  1112.         }
  1113.  
  1114.         return $result;
  1115.  
  1116.     }
  1117.  
  1118.     /**
  1119.      * Creates a submit button
  1120.      *
  1121.      * @return string html formated submit button widget
  1122.      *
  1123.      */
  1124.     function createWidget_Submit({
  1125.  
  1126.         $result "<input type=\"submit\" name=\"$this->name\" value=\""
  1127.                 . sm_encode_html_special_chars($this->comment)
  1128.                 . "\" $this->script />
  1129.                 . sm_encode_html_special_chars($this->trailing_text"\n";
  1130.  
  1131.         return $result;
  1132.  
  1133.     }
  1134.  
  1135.     function save({
  1136.         $function $this->save_function;
  1137.         $function($this);
  1138.     }
  1139.  
  1140.     function changed({
  1141.  
  1142.         // edit lists have a lot going on, so we'll always process them
  1143.         //
  1144.         if ($this->type == SMOPT_TYPE_EDIT_LIST
  1145.          || $this->type == SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE)
  1146.             return TRUE;
  1147.  
  1148.         return ($this->value != $this->new_value);
  1149.     }
  1150. }
  1151.  
  1152. function save_option($option{
  1153.  
  1154.     // Can't save the pref if we don't have the username
  1155.     //
  1156.     if !sqgetGlobalVar('username'$usernameSQ_SESSION ) ) {
  1157.         return;
  1158.     }
  1159.  
  1160.     // if the widget is a selection list, make sure the new
  1161.     // value is actually in the selection list and is not an
  1162.     // injection attack
  1163.     //
  1164.     if ($option->type == SMOPT_TYPE_STRLIST
  1165.      && !array_key_exists($option->new_value$option->possible_values))
  1166.         return;
  1167.  
  1168.  
  1169.     // all other widgets except TEXTAREAs should never be allowed to have newlines
  1170.     //
  1171.     else if ($option->type != SMOPT_TYPE_TEXTAREA)
  1172.         $option->new_value str_replace(array("\r""\n")''$option->new_value);
  1173.  
  1174.  
  1175.     global $data_dir;
  1176.  
  1177.     // edit lists: first add new elements to list, then
  1178.     // remove any selected ones (note that we must add
  1179.     // before deleting because the javascript that populates
  1180.     // the "add" textbox when selecting items in the list
  1181.     // (for deletion))
  1182.     //
  1183.     if ($option->type == SMOPT_TYPE_EDIT_LIST{
  1184.  
  1185.         if (empty($option->possible_values)) $option->possible_values array();
  1186.         if (!is_array($option->possible_values)) $option->possible_values array($option->possible_values);
  1187.  
  1188.         // add element if given
  1189.         //
  1190.         if ((isset($option->use_add_widget&& $option->use_add_widget)
  1191.          && sqGetGlobalVar('add_' $option->name$new_elementSQ_POST)) {
  1192.             $new_element trim($new_element);
  1193.             if (!empty($new_element)
  1194.              && !in_array($new_element$option->possible_values))
  1195.                 $option->possible_values[$new_element;
  1196.         }
  1197.  
  1198.         // delete selected elements if needed
  1199.         //
  1200.         if ((isset($option->use_delete_widget&& $option->use_delete_widget)
  1201.          && is_array($option->new_value)
  1202.          && sqGetGlobalVar('delete_' $option->name$ignoreSQ_POST))
  1203.             $option->possible_values array_diff($option->possible_values$option->new_value);
  1204.  
  1205.         // save full list (stored in "possible_values")
  1206.         //
  1207.         setPref($data_dir$username$option->nameserialize($option->possible_values));
  1208.  
  1209.     // associative edit lists are handled similar to
  1210.     // non-associative ones
  1211.     //
  1212.     else if ($option->type == SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE{
  1213.  
  1214.         if (empty($option->possible_values)) $option->possible_values array();
  1215.         if (!is_array($option->possible_values)) $option->possible_values array($option->possible_values);
  1216.  
  1217.         // add element if given
  1218.         //
  1219.         $new_element_key '';
  1220.         $new_element_value '';
  1221.         $retrieve_key sqGetGlobalVar('add_' $option->name '_key'$new_element_keySQ_POST);
  1222.         $retrieve_value sqGetGlobalVar('add_' $option->name '_value'$new_element_valueSQ_POST);
  1223.  
  1224.         if ((isset($option->use_add_widget&& $option->use_add_widget)
  1225.          && ($retrieve_key || $retrieve_value)) {
  1226.             $new_element_key trim($new_element_key);
  1227.             $new_element_value trim($new_element_value);
  1228.             if ($option->poss_value_folders && empty($new_element_key))
  1229.                 $new_element_value '';
  1230.             if (!empty($new_element_key|| !empty($new_element_value)) {
  1231.                 if (empty($new_element_key)) $new_element_key '0';
  1232.                 $option->possible_values[$new_element_key$new_element_value;
  1233.             }
  1234.         }
  1235.  
  1236.         // delete selected elements if needed
  1237.         //
  1238.         if ((isset($option->use_delete_widget&& $option->use_delete_widget)
  1239.          && is_array($option->new_value)
  1240.          && sqGetGlobalVar('delete_' $option->name$ignoreSQ_POST)) {
  1241.  
  1242.             if ($option->layout_type == SMOPT_EDIT_LIST_LAYOUT_SELECT{
  1243.                 foreach ($option->new_value as $key)
  1244.                     unset($option->possible_values[urldecode($key)]);
  1245.             }
  1246.             else
  1247.                 $option->possible_values array_diff($option->possible_values$option->new_value);
  1248.         }
  1249.  
  1250.         // save full list (stored in "possible_values")
  1251.         //
  1252.         setPref($data_dir$username$option->nameserialize($option->possible_values));
  1253.  
  1254.     // Certain option types need to be serialized because
  1255.     // they are not scalar
  1256.     //
  1257.     else if ($option->is_multiple_valued())
  1258.         setPref($data_dir$username$option->nameserialize($option->new_value));
  1259.  
  1260.     // Checkboxes, when unchecked, don't submit anything in
  1261.     // the POST, so set to SMPREF_OFF if not found
  1262.     //
  1263.     else if (($option->type == SMOPT_TYPE_BOOLEAN
  1264.            || $option->type == SMOPT_TYPE_BOOLEAN_CHECKBOX)
  1265.           && empty($option->new_value)) 
  1266.         setPref($data_dir$username$option->nameSMPREF_OFF);
  1267.  
  1268.     // For integer fields, make sure we only have digits...
  1269.     // We'll be nice and instead of just converting to an integer,
  1270.     // we'll physically remove each non-digit in the string.
  1271.     //
  1272.     else if ($option->type == SMOPT_TYPE_INTEGER{
  1273.         $option->new_value preg_replace('/[^0-9]/'''$option->new_value);
  1274.         setPref($data_dir$username$option->name$option->new_value);
  1275.     }
  1276.  
  1277.     else
  1278.         setPref($data_dir$username$option->name$option->new_value);
  1279.  
  1280.  
  1281.     // if a checkbox or multi select is zeroed/cleared out, it
  1282.     // needs to have an empty value pushed into its "new_value" slot
  1283.     //
  1284.     if (($option->type == SMOPT_TYPE_STRLIST_MULTI
  1285.       || $option->type == SMOPT_TYPE_BOOLEAN_CHECKBOX)
  1286.      && is_null($option->new_value))
  1287.         $option->new_value '';
  1288.  
  1289. }
  1290.  
  1291. function save_option_noop($option{
  1292.     /* Do nothing here... */
  1293. }
  1294.  
  1295. function create_optpage_element($optpage{
  1296.     return create_hidden_element('optpage'$optpage);
  1297. }
  1298.  
  1299. function create_optmode_element($optmode{
  1300.     return create_hidden_element('optmode'$optmode);
  1301. }
  1302.  
  1303. function create_hidden_element($name$value{
  1304.     $result '<input type="hidden" '
  1305.             . 'name="' $name '" '
  1306.             . 'value="' sm_encode_html_special_chars($value'" />';
  1307.     return ($result);
  1308. }
  1309.  
  1310. function create_option_groups($optgrps$optvals{
  1311.     /* Build a simple array with which to start. */
  1312.     $result array();
  1313.  
  1314.     /* Create option group for each option group name. */
  1315.     foreach ($optgrps as $grpkey => $grpname{
  1316.         $result[$grpkeyarray();
  1317.         $result[$grpkey]['name'$grpname;
  1318.         $result[$grpkey]['options'array();
  1319.     }
  1320.  
  1321.      /* Create a new SquirrelOption for each set of option values. */
  1322.     foreach ($optvals as $grpkey => $grpopts{
  1323.         foreach ($grpopts as $optset{
  1324.             /* Create a new option with all values given. */
  1325.             $next_option new SquirrelOption(
  1326.                 $optset,
  1327.                 $optset['name'],
  1328.                 $optset['caption'],
  1329.                 $optset['type'],
  1330.                 (isset($optset['refresh']$optset['refresh'SMOPT_REFRESH_NONE),
  1331.                 (isset($optset['initial_value']$optset['initial_value'''),
  1332.                 (isset($optset['posvals']$optset['posvals'''),
  1333.                 (isset($optset['htmlencoded']$optset['htmlencoded'false)
  1334.                 );
  1335.  
  1336.             /* If provided, set if the caption is allowed to wrap for this option. */
  1337.             if (isset($optset['caption_wrap'])) {
  1338.                 $next_option->setCaptionWrap($optset['caption_wrap']);
  1339.             }
  1340.  
  1341.             /* If provided, set the size for this option. */
  1342.             if (isset($optset['size'])) {
  1343.                 $next_option->setSize($optset['size']);
  1344.             }
  1345.  
  1346.             /* If provided, set the trailing_text for this option. */
  1347.             if (isset($optset['trailing_text'])) {
  1348.                 $next_option->setTrailingText($optset['trailing_text']);
  1349.             }
  1350.  
  1351.             /* If provided, set the yes_text for this option. */
  1352.             if (isset($optset['yes_text'])) {
  1353.                 $next_option->setYesText($optset['yes_text']);
  1354.             }
  1355.  
  1356.             /* If provided, set the no_text for this option. */
  1357.             if (isset($optset['no_text'])) {
  1358.                 $next_option->setNoText($optset['no_text']);
  1359.             }
  1360.  
  1361.             /* If provided, set the use_add_widget value for this option. */
  1362.             if (isset($optset['use_add_widget'])) {
  1363.                 $next_option->setUseAddWidget($optset['use_add_widget']);
  1364.             }
  1365.  
  1366.             /* If provided, set the use_delete_widget value for this option. */
  1367.             if (isset($optset['use_delete_widget'])) {
  1368.                 $next_option->setUseDeleteWidget($optset['use_delete_widget']);
  1369.             }
  1370.  
  1371.             /* If provided, set the poss_value_folders value for this option. */
  1372.             if (isset($optset['poss_value_folders'])) {
  1373.                 $next_option->setPossValueFolders($optset['poss_value_folders']);
  1374.             }
  1375.  
  1376.             /* If provided, set the layout type for this option. */
  1377.             if (isset($optset['layout_type'])) {
  1378.                 $next_option->setLayoutType($optset['layout_type']);
  1379.             }
  1380.  
  1381.             /* If provided, set the comment for this option. */
  1382.             if (isset($optset['comment'])) {
  1383.                 $next_option->setComment($optset['comment']);
  1384.             }
  1385.  
  1386.             /* If provided, set the save function for this option. */
  1387.             if (isset($optset['save'])) {
  1388.                 $next_option->setSaveFunction($optset['save']);
  1389.             }
  1390.  
  1391.             /* If provided, set the script for this option. */
  1392.             if (isset($optset['script'])) {
  1393.                 $next_option->setScript($optset['script']);
  1394.             }
  1395.  
  1396.             /* If provided, set the "post script" for this option. */
  1397.             if (isset($optset['post_script'])) {
  1398.                 $next_option->setPostScript($optset['post_script']);
  1399.             }
  1400.  
  1401.             /* Add this option to the option array. */
  1402.             $result[$grpkey]['options'][$next_option;
  1403.         }
  1404.     }
  1405.  
  1406.     /* Return our resulting array. */
  1407.     return ($result);
  1408. }
  1409.  
  1410. function print_option_groups($option_groups{
  1411.     /* Print each option group. */
  1412.     foreach ($option_groups as $next_optgrp{
  1413.         /* If it is not blank, print the name for this option group. */
  1414.         if ($next_optgrp['name'!= ''{
  1415.             echo html_tag'tr'"\n".
  1416.                         html_tag'td',
  1417.                             '<b>' $next_optgrp['name''</b>' ,
  1418.                         'center' ,'''valign="middle" colspan="2" nowrap' )
  1419.                     ."\n";
  1420.         }
  1421.  
  1422.         /* Print each option in this option group. */
  1423.         $hidden_options '';
  1424.         foreach ($next_optgrp['options'as $option{
  1425.             if ($option->type != SMOPT_TYPE_HIDDEN{
  1426.  
  1427.                 // although trailing_text will be a label for the checkbox,
  1428.                 // make the caption a label too - some widgets won't have
  1429.                 // trailing_text and having both as labels is perfectly fine
  1430.                 //
  1431.                 if ($option->type == SMOPT_TYPE_BOOLEAN_CHECKBOX
  1432.                  || $option->type == SMOPT_TYPE_BOOLEAN)
  1433.                     $option->caption '<label for="new_' $option->name '">'
  1434.                                      . $option->caption '</label>';
  1435.  
  1436.                 // text area trailing text just goes under the caption
  1437.                 //
  1438.                 if ($option->type == SMOPT_TYPE_TEXTAREA && !empty($option->trailing_text))
  1439.                     $option->caption .= '<br /><small>' $option->trailing_text '</small>';
  1440.  
  1441.                 global $color;
  1442.                 //$info_bgcolor = 0;
  1443.                 $info_bgcolor 4;
  1444.                 $info_width 80;
  1445.                 if ($option->type == SMOPT_TYPE_INFO)
  1446.                     echo html_tag('tr'"\n" html_tag('td'"\n" html_tag('table'"\n" html_tag('tr'"\n" html_tag('td'"\n" $option->createHTMLWidget()))''$color[$info_bgcolor]'width="' $info_width '%"')'center' ,'''colspan="2" valign="middle"')) ."\n";
  1447.                 else
  1448.                     echo html_tag'tr'"\n".
  1449.                                html_tag'td'$option->caption (!empty($option->caption':' '')'right' ,'''valign="middle"' ($option->caption_wrap '' ' style="white-space:nowrap"') ) .
  1450.                                html_tag'td'$option->createHTMLWidget()'left' )
  1451.                            ."\n";
  1452.             else {
  1453.                 $hidden_options .= $option->createHTMLWidget();
  1454.             }
  1455.         }
  1456.  
  1457.         /* Print an empty row after this option group. */
  1458.         echo html_tag'tr',
  1459.                    html_tag'td''&nbsp;' $hidden_options'left''''colspan="2"' )
  1460.                 "\n";
  1461.     }
  1462. }
  1463.  
  1464. function OptionSubmit$name {
  1465.         echo html_tag'tr',
  1466.                    html_tag'td''<input type="submit" value="' _("Submit"'" name="' $name '" />&nbsp;&nbsp;&nbsp;&nbsp;''right''''colspan="2"' )
  1467.                 "\n";
  1468. }

Documentation generated on Fri, 31 Oct 2014 04:21:31 +0100 by phpDocumentor 1.4.3