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

Documentation generated on Mon, 13 Jan 2020 04:25:04 +0100 by phpDocumentor 1.4.3