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 14420 2014-01-01 20:33:20Z pdontthink $
  11.  * @package squirrelmail
  12.  * @subpackage prefs
  13.  */
  14.  
  15. /**
  16.  * SquirrelOption: An option for SquirrelMail.
  17.  *
  18.  * @package squirrelmail
  19.  * @subpackage prefs
  20.  */
  21. class SquirrelOption {
  22.     /**
  23.      * The original option configuration array
  24.      * @var array 
  25.      */
  26.     var $raw_option_array;
  27.     /**
  28.      * The name of this setting
  29.      * @var string 
  30.      */
  31.     var $name;
  32.     /**
  33.      * The text that prefaces setting on the preferences page
  34.      * @var string 
  35.      */
  36.     var $caption;
  37.     /**
  38.      * Whether or not the caption text is allowed to wrap
  39.      * @var boolean 
  40.      */
  41.     var $caption_wrap;
  42.     /**
  43.      * The type of INPUT element
  44.      *
  45.      * See SMOPT_TYPE_* defines
  46.      * @var integer 
  47.      */
  48.     var $type;
  49.     /**
  50.      * Indicates if a link should be shown to refresh part
  51.      * or all of the window
  52.      *
  53.      * See SMOPT_REFRESH_* defines
  54.      * @var integer 
  55.      */
  56.     var $refresh_level;
  57.     /**
  58.      * Specifies the size of certain input items
  59.      *
  60.      * See SMOPT_SIZE_* defines
  61.      * @var integer 
  62.      */
  63.     var $size;
  64.     /**
  65.      * Text that follows a text input or
  66.      * select list input on the preferences page
  67.      *
  68.      * useful for indicating units, meanings of special values, etc.
  69.      * @var string 
  70.      */
  71.     var $trailing_text;
  72.     /**
  73.      * Text that overrides the "Yes" label for boolean
  74.      * radio option widgets
  75.      *
  76.      * @var string 
  77.      */
  78.     var $yes_text;
  79.     /**
  80.      * Text that overrides the "No" label for boolean
  81.      * radio option widgets
  82.      *
  83.      * @var string 
  84.      */
  85.     var $no_text;
  86.     /**
  87.      * Some widgets support more than one layout type
  88.      *
  89.      * @var int 
  90.      */
  91.     var $layout_type;
  92.     /**
  93.      * Indicates if the Add widget should be included
  94.      * with edit lists.
  95.      *
  96.      * @var boolean 
  97.      */
  98.     var $use_add_widget;
  99.     /**
  100.      * Indicates if the Delete widget should be included
  101.      * with edit lists.
  102.      *
  103.      * @var boolean 
  104.      */
  105.     var $use_delete_widget;
  106.     /**
  107.      * associative array, treated the same as $possible_values
  108.      * (see its documentation below), but usually expected to
  109.      * have its first value contain a list of IMAP folders, an
  110.      * array itself in the format as passed back by
  111.      * sqimap_mailbox_list(). Used to display folder selector
  112.      * for possible values of an associative edit list option
  113.      * widget
  114.      *
  115.      * @since 1.5.2
  116.      * @var array 
  117.      */
  118.     var $poss_value_folders;
  119.     /**
  120.      * text displayed to the user
  121.      *
  122.      * Used with SMOPT_TYPE_COMMENT options
  123.      * @var string 
  124.      */
  125.     var $comment;
  126.     /**
  127.      * additional javascript or other widget attributes added to the
  128.      * user input; must be an array where keys are attribute names
  129.      * ("onclick", etc) and values are the attribute values.
  130.      * @var array 
  131.      */
  132.     var $aExtraAttribs;
  133.     /**
  134.      * script (usually Javascript) that will be placed after (outside of)
  135.      * the INPUT tag
  136.      * @var string 
  137.      */
  138.     var $post_script;
  139.  
  140.     /**
  141.      * The name of the Save Function for this option.
  142.      * @var string 
  143.      */
  144.     var $save_function;
  145.  
  146.     /* The various 'values' for this options. */
  147.     /**
  148.      * default/preselected value for this option
  149.      * @var mixed 
  150.      */
  151.     var $value;
  152.     /**
  153.      * new option value
  154.      * @var mixed 
  155.      */
  156.     var $new_value;
  157.     /**
  158.      * associative array, where each key is an actual input value
  159.      * and the corresponding value is what is displayed to the user
  160.      * for that list item in the drop-down list
  161.      * @var array 
  162.      */
  163.     var $possible_values;
  164.     /**
  165.      * disables html sanitizing.
  166.      *
  167.      * WARNING - don't use it, if user input is possible in option
  168.      * or use own sanitizing functions. Currently only works for SMOPT_TYPE_STRLIST.
  169.      * @var bool 
  170.      */
  171.     var $htmlencoded=false;
  172.     /**
  173.      * Controls folder list limits in SMOPT_TYPE_FLDRLIST and
  174.      * SMOPT_TYPE_FLDRLIST_MULTI widgets as well as the optional
  175.      * embedded folder lists provided for inputting values for
  176.      * the SMOPT_TYPE_EDIT_LIST and SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE
  177.      * :idgets.
  178.      * See $flag argument in sqimap_mailbox_option_list() function.
  179.      * @var string 
  180.      * @since 1.5.1
  181.      */
  182.     var $folder_filter='noselect';
  183.  
  184.     /**
  185.      * Constructor function
  186.      * @param array $raw_option_array 
  187.      * @param string $name 
  188.      * @param string $caption 
  189.      * @param integer $type 
  190.      * @param integer $refresh_level 
  191.      * @param mixed $initial_value 
  192.      * @param array $possible_values 
  193.      * @param bool $htmlencoded 
  194.      */
  195.     function SquirrelOption
  196.     ($raw_option_array$name$caption$type$refresh_level$initial_value ''$possible_values ''$htmlencoded false{
  197.         /* Set the basic stuff. */
  198.         $this->raw_option_array = $raw_option_array;
  199.         $this->name = $name;
  200.         $this->caption = $caption;
  201.         $this->caption_wrap = TRUE;
  202.         $this->type = $type;
  203.         $this->refresh_level = $refresh_level;
  204.         $this->possible_values = $possible_values;
  205.         $this->htmlencoded = $htmlencoded;
  206.         $this->size = SMOPT_SIZE_NORMAL;
  207.         $this->trailing_text = '';
  208.         $this->yes_text = '';
  209.         $this->no_text = '';
  210.         $this->comment = '';
  211.         $this->layout_type = 0;
  212.         $this->use_add_widget = TRUE;
  213.         $this->use_delete_widget = TRUE;
  214.         $this->poss_value_folders = '';
  215.         $this->aExtraAttribs = array();
  216.         $this->post_script = '';
  217.  
  218.         //Check for a current value.  
  219.         if (isset($GLOBALS[$name])) {
  220.             $this->value = $GLOBALS[$name];
  221.         else if (!empty($initial_value)) {
  222.             $this->value = $initial_value;
  223.         else {
  224.             $this->value = '';
  225.         }
  226.  
  227.         /* Check for a new value. */
  228.         if !sqgetGlobalVar("new_$name"$this->new_valueSQ_POST ) ) {
  229.             $this->new_value = NULL;
  230.         }
  231.  
  232.         /* Set the default save function. */
  233.         if ($type != SMOPT_TYPE_HIDDEN
  234.          && $type != SMOPT_TYPE_INFO
  235.          && $type != SMOPT_TYPE_COMMENT{
  236.             $this->save_function = SMOPT_SAVE_DEFAULT;
  237.         else {
  238.             $this->save_function = SMOPT_SAVE_NOOP;
  239.         }
  240.     }
  241.  
  242.     /** Convenience function that identifies which types of
  243.         widgets are stored as (serialized) array values. */
  244.     function is_multiple_valued({
  245.         return ($this->type == SMOPT_TYPE_FLDRLIST_MULTI
  246.              || $this->type == SMOPT_TYPE_STRLIST_MULTI
  247.              || $this->type == SMOPT_TYPE_EDIT_LIST
  248.              || $this->type == SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE);
  249.     }
  250.  
  251.     /**
  252.      * Set the value for this option.
  253.      * @param mixed $value 
  254.      */
  255.     function setValue($value{
  256.         $this->value = $value;
  257.     }
  258.  
  259.     /**
  260.      * Set the new value for this option.
  261.      * @param mixed $new_value 
  262.      */
  263.     function setNewValue($new_value{
  264.         $this->new_value = $new_value;
  265.     }
  266.  
  267.     /**
  268.      * Set whether the caption is allowed to wrap for this option.
  269.      * @param boolean $caption_wrap 
  270.      */
  271.     function setCaptionWrap($caption_wrap{
  272.         $this->caption_wrap = $caption_wrap;
  273.     }
  274.  
  275.     /**
  276.      * Set the size for this option.
  277.      * @param integer $size 
  278.      */
  279.     function setSize($size{
  280.         $this->size = $size;
  281.     }
  282.  
  283.     /**
  284.      * Set the trailing_text for this option.
  285.      * @param string $trailing_text 
  286.      */
  287.     function setTrailingText($trailing_text{
  288.         $this->trailing_text = $trailing_text;
  289.     }
  290.  
  291.     /**
  292.      * Set the yes_text for this option.
  293.      * @param string $yes_text 
  294.      */
  295.     function setYesText($yes_text{
  296.         $this->yes_text = $yes_text;
  297.     }
  298.  
  299.     /**
  300.      * Set the no_text for this option.
  301.      * @param string $no_text 
  302.      */
  303.     function setNoText($no_text{
  304.         $this->no_text = $no_text;
  305.     }
  306.  
  307.     /* Set the "use add widget" value for this option. */
  308.     function setUseAddWidget($use_add_widget{
  309.         $this->use_add_widget = $use_add_widget;
  310.     }
  311.  
  312.     /* Set the "use delete widget" value for this option. */
  313.     function setUseDeleteWidget($use_delete_widget{
  314.         $this->use_delete_widget = $use_delete_widget;
  315.     }
  316.  
  317.     /* Set the "poss value folders" value for this option.
  318.        See the associative edit list widget, which uses this
  319.        to offer folder list selection for the values */
  320.     function setPossValueFolders($poss_value_folders{
  321.         $this->poss_value_folders = $poss_value_folders;
  322.     }
  323.  
  324.     /**
  325.      * Set the layout type for this option.
  326.      * @param int $layout_type 
  327.      */
  328.     function setLayoutType($layout_type{
  329.         $this->layout_type = $layout_type;
  330.     }
  331.  
  332.     /**
  333.      * Set the comment for this option.
  334.      * @param string $comment 
  335.      */
  336.     function setComment($comment{
  337.         $this->comment = $comment;
  338.     }
  339.  
  340.     /**
  341.      * Set the extra attributes for this option.
  342.      * @param array $aExtraAttribs 
  343.      */
  344.     function setExtraAttributes($aExtraAttribs{
  345.         $this->aExtraAttribs = $aExtraAttribs;
  346.     }
  347.  
  348.     /**
  349.      * Set the "post script" for this option.
  350.      * @param string $post_script 
  351.      */
  352.     function setPostScript($post_script{
  353.         $this->post_script = $post_script;
  354.     }
  355.  
  356.     /**
  357.      * Set the save function for this option.
  358.      * @param string $save_function 
  359.      */
  360.     function setSaveFunction($save_function{
  361.         $this->save_function = $save_function;
  362.     }
  363.  
  364.     /**
  365.      * Set the folder_filter for this option.
  366.      * @param string $folder_filter 
  367.      * @since 1.5.1
  368.      */
  369.     function setFolderFilter($folder_filter{
  370.         $this->folder_filter = $folder_filter;
  371.     }
  372.  
  373.     /**
  374.      * Creates fields on option pages according to option type
  375.      *
  376.      * This is the function that calls all other createWidget* functions.
  377.      *
  378.      * @return string The formated option field
  379.      *
  380.      */
  381.     function createWidget({
  382.         global $color;
  383.  
  384.         // Use new value if available
  385.         if (!is_null($this->new_value)) {
  386.             $tempValue $this->value;
  387.             $this->value = $this->new_value;
  388.         }
  389.  
  390.         /* Get the widget for this option type. */
  391.         switch ($this->type{
  392.             case SMOPT_TYPE_PASSWORD:
  393.                 $result $this->createWidget_String(TRUE);
  394.                 break;
  395.             case SMOPT_TYPE_STRING:
  396.                 $result $this->createWidget_String();
  397.                 break;
  398.             case SMOPT_TYPE_STRLIST:
  399.                 $result $this->createWidget_StrList();
  400.                 break;
  401.             case SMOPT_TYPE_TEXTAREA:
  402.                 $result $this->createWidget_TextArea();
  403.                 break;
  404.             case SMOPT_TYPE_INTEGER:
  405.                 $result $this->createWidget_Integer();
  406.                 break;
  407.             case SMOPT_TYPE_FLOAT:
  408.                 $result $this->createWidget_Float();
  409.                 break;
  410.             case SMOPT_TYPE_BOOLEAN:
  411.                 $result $this->createWidget_Boolean();
  412.                 break;
  413.             case SMOPT_TYPE_BOOLEAN_CHECKBOX:
  414.                 $result $this->createWidget_Boolean(TRUE);
  415.                 break;
  416.             case SMOPT_TYPE_BOOLEAN_RADIO:
  417.                 $result $this->createWidget_Boolean(FALSE);
  418.                 break;
  419.             case SMOPT_TYPE_HIDDEN:
  420.                 $result $this->createWidget_Hidden();
  421.                 break;
  422.             case SMOPT_TYPE_COMMENT:
  423.                 $result $this->createWidget_Comment();
  424.                 break;
  425.             case SMOPT_TYPE_FLDRLIST:
  426.                 $result $this->createWidget_FolderList();
  427.                 break;
  428.             case SMOPT_TYPE_FLDRLIST_MULTI:
  429.                 $result $this->createWidget_FolderList(TRUE);
  430.                 break;
  431.             case SMOPT_TYPE_EDIT_LIST:
  432.                 $result $this->createWidget_EditList();
  433.                 break;
  434.             case SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE:
  435.                 $result $this->createWidget_EditListAssociative();
  436.                 break;
  437.             case SMOPT_TYPE_STRLIST_MULTI:
  438.                 $result $this->createWidget_StrList(TRUE);
  439.                 break;
  440.             case SMOPT_TYPE_STRLIST_RADIO:
  441.                 $result $this->createWidget_StrList(FALSETRUE);
  442.                 break;
  443.             case SMOPT_TYPE_SUBMIT:
  444.                 $result $this->createWidget_Submit();
  445.                 break;
  446.             case SMOPT_TYPE_INFO:
  447.                 $result $this->createWidget_Info();
  448.                 break;
  449.             default:
  450.                 error_box 
  451.                     sprintf(_("Option Type '%s' Not Found")$this->type)
  452.                     );
  453.         }
  454.  
  455.         /* Add the "post script" for this option. */
  456.         $result .= $this->post_script;
  457.  
  458.         // put correct value back if need be
  459.         if (!is_null($this->new_value)) {
  460.             $this->value = $tempValue;
  461.         }
  462.  
  463.         /* Now, return the created widget. */
  464.         return $result;
  465.     }
  466.  
  467.     /**
  468.      * Creates info block
  469.      * @return string html formated output
  470.      */
  471.     function createWidget_Info({
  472.         return sq_htmlspecialchars($this->value);
  473.     }
  474.  
  475.     /**
  476.      * Create string field
  477.      *
  478.      * @param boolean $password When TRUE, the text in the input
  479.      *                           widget will be obscured (OPTIONAL;
  480.      *                           default = FALSE).
  481.      *
  482.      * @return string html formated option field
  483.      *
  484.      */
  485.     function createWidget_String($password=FALSE{
  486.         switch ($this->size{
  487.             case SMOPT_SIZE_TINY:
  488.                 $width 5;
  489.                 break;
  490.             case SMOPT_SIZE_SMALL:
  491.                 $width 12;
  492.                 break;
  493.             case SMOPT_SIZE_LARGE:
  494.                 $width 38;
  495.                 break;
  496.             case SMOPT_SIZE_HUGE:
  497.                 $width 50;
  498.                 break;
  499.             case SMOPT_SIZE_NORMAL:
  500.             default:
  501.                 $width 25;
  502.         }
  503.  
  504. //TODO: might be better to have a separate template file for all widgets, because then the layout of the widget and the "trailing text" can be customized - they are still hard coded here
  505.         if ($password)
  506.             return addPwField('new_' $this->name$this->value$width0$this->aExtraAttribs' ' sm_encode_html_special_chars($this->trailing_text);
  507.         else
  508.             return addInput('new_' $this->name$this->value$width0$this->aExtraAttribs' ' sm_encode_html_special_chars($this->trailing_text);
  509.     }
  510.  
  511.     /**
  512.      * Create selection box or radio button group
  513.      *
  514.      * When $this->htmlencoded is TRUE, the keys and values in
  515.      * $this->possible_values are assumed to be display-safe.
  516.      * Use with care!
  517.      *
  518.      * Note that when building radio buttons instead of a select
  519.      * widget, if the "size" attribute is SMOPT_SIZE_TINY, the
  520.      * radio buttons will be output one after another without
  521.      * linebreaks between them.  Otherwise, each radio button
  522.      * goes on a line of its own.
  523.      *
  524.      * @param boolean $multiple_select When TRUE, the select widget
  525.      *                                  will allow multiple selections
  526.      *                                  (OPTIONAL; default is FALSE
  527.      *                                  (single select list))
  528.      * @param boolean $radio_buttons   When TRUE, the widget will
  529.      *                                  instead be built as a group
  530.      *                                  of radio buttons (and
  531.      *                                  $multiple_select will be
  532.      *                                  forced to FALSE) (OPTIONAL;
  533.      *                                  default is FALSE (select widget))
  534.      *
  535.      * @return string html formated selection box or radio buttons
  536.      *
  537.      */
  538.     function createWidget_StrList($multiple_select=FALSE$radio_buttons=FALSE{
  539. //FIXME: Currently, $this->htmlencoded is ignored here -- was removed when changing to template-based output; a fix is available as part of proposed centralized sanitizing patch
  540.  
  541.         // radio buttons instead of select widget?
  542.         //
  543.         if ($radio_buttons{
  544.  
  545.             global $br$nbsp;
  546.             $result '';
  547.             foreach ($this->possible_values as $real_value => $disp_value{
  548.                 $result .= addRadioBox('new_' $this->name($this->value == $real_value)$real_valuearray_merge(array('id' => 'new_' $this->name . '_' $real_value)$this->aExtraAttribs)) $nbsp create_label($disp_value'new_' $this->name . '_' $real_value);
  549.                 if ($this->size != SMOPT_SIZE_TINY)
  550.                     $result .= $br;
  551.             }
  552.  
  553.             return $result;
  554.         }
  555.  
  556.  
  557.         // everything below applies to select widgets
  558.         //
  559.         switch ($this->size{
  560. //FIXME: not sure about these sizes... seems like we could add another on the "large" side...
  561.             case SMOPT_SIZE_TINY:
  562.                 $height 3;
  563.                 break;
  564.             case SMOPT_SIZE_SMALL:
  565.                 $height 8;
  566.                 break;
  567.             case SMOPT_SIZE_LARGE:
  568.                 $height 15;
  569.                 break;
  570.             case SMOPT_SIZE_HUGE:
  571.                 $height 25;
  572.                 break;
  573.             case SMOPT_SIZE_NORMAL:
  574.             default:
  575.                 $height 5;
  576.         }
  577.  
  578.         return addSelect('new_' $this->name$this->possible_values$this->valueTRUE$this->aExtraAttribs$multiple_select$height!$this->htmlencodedsm_encode_html_special_chars($this->trailing_text);
  579.  
  580.     }
  581.  
  582.     /**
  583.      * Create folder selection box
  584.      *
  585.      * @param boolean $multiple_select When TRUE, the select widget
  586.      *                                  will allow multiple selections
  587.      *                                  (OPTIONAL; default is FALSE
  588.      *                                  (single select list))
  589.      *
  590.      * @return string html formated selection box
  591.      *
  592.      */
  593.     function createWidget_FolderList($multiple_select=FALSE{
  594.  
  595.         switch ($this->size{
  596. //FIXME: not sure about these sizes... seems like we could add another on the "large" side...
  597.             case SMOPT_SIZE_TINY:
  598.                 $height 3;
  599.                 break;
  600.             case SMOPT_SIZE_SMALL:
  601.                 $height 8;
  602.                 break;
  603.             case SMOPT_SIZE_LARGE:
  604.                 $height 15;
  605.                 break;
  606.             case SMOPT_SIZE_HUGE:
  607.                 $height 25;
  608.                 break;
  609.             case SMOPT_SIZE_NORMAL:
  610.             default:
  611.                 $height 5;
  612.         }
  613.  
  614.         // possible values might include a nested array of 
  615.         // possible values (list of folders)
  616.         //
  617.         $option_list array();
  618.         foreach ($this->possible_values as $value => $text{
  619.  
  620.             // list of folders (boxes array)
  621.             //
  622.             if (is_array($text)) {
  623.               $option_list array_merge($option_listsqimap_mailbox_option_array(00$text$this->folder_filter));
  624.  
  625.             // just one option here
  626.             //
  627.             else {
  628.               $option_list array_merge($option_listarray($value => $text));
  629.             }
  630.  
  631.         }
  632.         if (empty($option_list))
  633.             $option_list array('ignore' => _("unavailable"));
  634.  
  635.  
  636.         return addSelect('new_' $this->name$option_list$this->valueTRUE$this->aExtraAttribs$multiple_select$heightsm_encode_html_special_chars($this->trailing_text);
  637.  
  638.     }
  639.  
  640.     /**
  641.      * Creates textarea
  642.      * @return string html formated textarea field
  643.      */
  644.     function createWidget_TextArea({
  645.         switch ($this->size{
  646.             case SMOPT_SIZE_TINY:  $rows 3$cols =  10break;
  647.             case SMOPT_SIZE_SMALL$rows 4$cols =  30break;
  648.             case SMOPT_SIZE_LARGE$rows 10$cols =  60break;
  649.             case SMOPT_SIZE_HUGE:  $rows 20$cols =  80break;
  650.             case SMOPT_SIZE_NORMAL:
  651.             default$rows 5$cols =  50;
  652.         }
  653.         return addTextArea('new_' $this->name$this->value$cols$rows$this->aExtraAttribs);
  654.     }
  655.  
  656.     /**
  657.      * Creates field for integer
  658.      *
  659.      * Difference from createWidget_String is visible only when javascript is enabled
  660.      * @return string html formated option field
  661.      */
  662.     function createWidget_Integer({
  663.  
  664.         // add onChange javascript handler to a regular string widget
  665.         // which will strip out all non-numeric chars
  666.         if (checkForJavascript())
  667.            $this->aExtraAttribs['onchange''origVal=this.value; newVal=\'\'; '
  668.                     . 'for (i=0;i<origVal.length;i++) { if (origVal.charAt(i)>=\'0\' '
  669.                     . '&& origVal.charAt(i)<=\'9\') newVal += origVal.charAt(i); } '
  670.                     . 'this.value=newVal;';
  671.  
  672.         return $this->createWidget_String();
  673.     }
  674.  
  675.     /**
  676.      * Creates field for floating number
  677.      * Difference from createWidget_String is visible only when javascript is enabled
  678.      * @return string html formated option field
  679.      */
  680.     function createWidget_Float({
  681.  
  682.         // add onChange javascript handler to a regular string widget
  683.         // which will strip out all non-numeric (period also OK) chars
  684.         if (checkForJavascript())
  685.            $this->aExtraAttribs['onchange''origVal=this.value; newVal=\'\'; '
  686.                     . 'for (i=0;i<origVal.length;i++) { if ((origVal.charAt(i)>=\'0\' '
  687.                     . '&& origVal.charAt(i)<=\'9\') || origVal.charAt(i)==\'.\') '
  688.                     . 'newVal += origVal.charAt(i); } this.value=newVal;';
  689.  
  690.         return $this->createWidget_String();
  691.     }
  692.  
  693.     /**
  694.      * Create boolean widget
  695.      *
  696.      * When creating Yes/No radio buttons, the "yes_text"
  697.      * and "no_text" option attributes are used to override
  698.      * the typical "Yes" and "No" text.
  699.      *
  700.      * @param boolean $checkbox When TRUE, the widget will be
  701.      *                           constructed as a checkbox,
  702.      *                           otherwise it will be a set of
  703.      *                           Yes/No radio buttons (OPTIONAL;
  704.      *                           default is TRUE (checkbox)).
  705.      *
  706.      * @return string html formated boolean widget
  707.      *
  708.      */
  709.     function createWidget_Boolean($checkbox=TRUE{
  710.  
  711.         global $oTemplate$nbsp;
  712.  
  713.  
  714.         // checkbox...
  715.         //
  716.         if ($checkbox{
  717.             $result addCheckbox('new_' $this->name($this->value != SMPREF_NO)SMPREF_YESarray_merge(array('id' => 'new_' $this->name)$this->aExtraAttribs)) $nbsp create_label($this->trailing_text'new_' $this->name);
  718.         }
  719.  
  720.         // radio buttons...
  721.         //
  722.         else {
  723.  
  724.             /* Build the yes choice. */
  725.             $yes_option addRadioBox('new_' $this->name($this->value != SMPREF_NO)SMPREF_YESarray_merge(array('id' => 'new_' $this->name . '_yes')$this->aExtraAttribs)) $nbsp create_label((!empty($this->yes_text$this->yes_text : _("Yes"))'new_' $this->name . '_yes');
  726.  
  727.             /* Build the no choice. */
  728.             $no_option addRadioBox('new_' $this->name($this->value == SMPREF_NO)SMPREF_NOarray_merge(array('id' => 'new_' $this->name . '_no')$this->aExtraAttribs)) $nbsp create_label((!empty($this->no_text$this->no_text : _("No"))'new_' $this->name . '_no');
  729.  
  730.             /* Build the combined "boolean widget". */
  731.             $result "$yes_option$nbsp$nbsp$nbsp$nbsp$no_option";
  732.  
  733.         }
  734.  
  735.         return ($result);
  736.     }
  737.  
  738.     /**
  739.      * Creates hidden field
  740.      * @return string html formated hidden input field
  741.      */
  742.     function createWidget_Hidden({
  743.         return addHidden('new_' $this->name$this->value$this->aExtraAttribs);
  744.     }
  745.  
  746.     /**
  747.      * Creates comment
  748.      * @return string comment
  749.      */
  750.     function createWidget_Comment({
  751.         $result $this->comment;
  752.         return ($result);
  753.     }
  754.  
  755.     /**
  756.      * Creates a (non-associative) edit list
  757.      *
  758.      * Note that multiple layout types are supported for this widget.
  759.      * $this->layout_type must be one of the SMOPT_EDIT_LIST_LAYOUT_*
  760.      * constants.
  761.      *
  762.      * @return string html formated list of edit fields and
  763.      *                 their associated controls
  764.      */
  765.     function createWidget_EditList({
  766.  
  767.         global $oTemplate;
  768.  
  769.         switch ($this->size{
  770.             case SMOPT_SIZE_TINY:
  771.                 $height 3;
  772.                 break;
  773.             case SMOPT_SIZE_SMALL:
  774.                 $height 8;
  775.                 break;
  776.             case SMOPT_SIZE_MEDIUM:
  777.                 $height 15;
  778.                 break;
  779.             case SMOPT_SIZE_LARGE:
  780.                 $height 25;
  781.                 break;
  782.             case SMOPT_SIZE_HUGE:
  783.                 $height 40;
  784.                 break;
  785.             case SMOPT_SIZE_NORMAL:
  786.             default:
  787.                 $height 5;
  788.         }
  789.  
  790.         if (empty($this->possible_values)) $this->possible_values = array();
  791.         if (!is_array($this->possible_values)) $this->possible_values = array($this->possible_values);
  792.  
  793. //FIXME: $this->aExtraAttribs probably should only be used in one place
  794.         $oTemplate->assign('input_widget'addInput('add_' $this->name''380$this->aExtraAttribs));
  795.         $oTemplate->assign('use_input_widget'$this->use_add_widget);
  796.         $oTemplate->assign('use_delete_widget'$this->use_delete_widget);
  797.  
  798.         $oTemplate->assign('trailing_text'$this->trailing_text);
  799.         $oTemplate->assign('possible_values'$this->possible_values);
  800.         $oTemplate->assign('current_value'$this->value);
  801.         $oTemplate->assign('select_widget'addSelect('new_' $this->name$this->possible_values$this->valueFALSE!checkForJavascript($this->aExtraAttribs : array_merge(array('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; } }')$this->aExtraAttribs)TRUE$height));
  802. // NOTE: i=f-1; j=e-1 is in lieu of break 2
  803.         $oTemplate->assign('checkbox_widget'addCheckBox('delete_' $this->nameFALSESMPREF_YESarray_merge(array('id' => 'delete_' $this->name)$this->aExtraAttribs)));
  804.         $oTemplate->assign('name'$this->name);
  805.  
  806.         switch ($this->layout_type{
  807.             case SMOPT_EDIT_LIST_LAYOUT_SELECT:
  808.                 return $oTemplate->fetch('edit_list_widget.tpl');
  809.             case SMOPT_EDIT_LIST_LAYOUT_LIST:
  810.                 return $oTemplate->fetch('edit_list_widget_list_style.tpl');
  811.             default:
  812.                 error_box(sprintf(_("Edit List Layout Type '%s' Not Found")$this->layout_type));
  813.         }
  814.  
  815.     }
  816.  
  817.     /**
  818.      * Creates an associative edit list
  819.      *
  820.      * Note that multiple layout types are supported for this widget.
  821.      * $this->layout_type must be one of the SMOPT_EDIT_LIST_LAYOUT_*
  822.      * constants.
  823.      *
  824.      * @return string html formated list of edit fields and
  825.      *                 their associated controls
  826.      */
  827.     function createWidget_EditListAssociative({
  828.  
  829.         global $oTemplate;
  830.  
  831.         switch ($this->size{
  832.             case SMOPT_SIZE_TINY:
  833.                 $height 3;
  834.                 break;
  835.             case SMOPT_SIZE_SMALL:
  836.                 $height 8;
  837.                 break;
  838.             case SMOPT_SIZE_MEDIUM:
  839.                 $height 15;
  840.                 break;
  841.             case SMOPT_SIZE_LARGE:
  842.                 $height 25;
  843.                 break;
  844.             case SMOPT_SIZE_HUGE:
  845.                 $height 40;
  846.                 break;
  847.             case SMOPT_SIZE_NORMAL:
  848.             default:
  849.                 $height 5;
  850.         }
  851.  
  852.  
  853.         // ensure correct format of current value(s)
  854.         //
  855.         if (empty($this->possible_values)) $this->possible_values = array();
  856.         if (!is_array($this->possible_values)) $this->possible_values = array($this->possible_values);
  857.  
  858.  
  859.         $oTemplate->assign('name'$this->name);
  860.         $oTemplate->assign('current_value'$this->value);
  861.         $oTemplate->assign('possible_values'$this->possible_values);
  862.         $oTemplate->assign('poss_value_folders'$this->poss_value_folders);
  863.         $oTemplate->assign('folder_filter'$this->folder_filter);
  864.  
  865.         $oTemplate->assign('use_input_widget'$this->use_add_widget);
  866.         $oTemplate->assign('use_delete_widget'$this->use_delete_widget);
  867.  
  868.         $oTemplate->assign('checkbox_widget'addCheckBox('delete_' $this->nameFALSESMPREF_YESarray_merge(array('id' => 'delete_' $this->name)$this->aExtraAttribs)));
  869.  
  870. //FIXME: $this->aExtraAttribs probably should only be used in one place
  871.         $oTemplate->assign('input_key_widget'addInput('add_' $this->name . '_key'''220$this->aExtraAttribs));
  872.         $oTemplate->assign('input_value_widget'addInput('add_' $this->name . '_value'''120$this->aExtraAttribs));
  873.  
  874.         $oTemplate->assign('select_height'$height);
  875.  
  876.         $oTemplate->assign('aAttribs'$this->aExtraAttribs);
  877.  
  878.         $oTemplate->assign('trailing_text'$this->trailing_text);
  879.  
  880.         switch ($this->layout_type{
  881.             case SMOPT_EDIT_LIST_LAYOUT_SELECT:
  882.                 return $oTemplate->fetch('edit_list_associative_widget.tpl');
  883.             case SMOPT_EDIT_LIST_LAYOUT_LIST:
  884.                 return $oTemplate->fetch('edit_list_associative_widget_list_style.tpl');
  885.             default:
  886.                 error_box(sprintf(_("Associative Edit List Layout Type '%s' Not Found")$this->layout_type));
  887.         }
  888.  
  889.     }
  890.  
  891.     /**
  892.      * Creates a submit button
  893.      *
  894.      * @return string html formated submit button widget
  895.      *
  896.      */
  897.     function createWidget_Submit({
  898.  
  899.         return addSubmit($this->comment$this->name$this->aExtraAttribssm_encode_html_special_chars($this->trailing_text);
  900.  
  901.     }
  902.  
  903.     /**
  904.      *
  905.      */
  906.     function save({
  907.         $function $this->save_function;
  908.         $function($this);
  909.     }
  910.  
  911.     /**
  912.      *
  913.      */
  914.     function changed({
  915.  
  916.         // edit lists have a lot going on, so we'll always process them
  917.         //
  918.         if ($this->type == SMOPT_TYPE_EDIT_LIST
  919.          || $this->type == SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE)
  920.             return TRUE;
  921.  
  922.         return ($this->value != $this->new_value);
  923.     }
  924. /* End of SquirrelOption class*/
  925.  
  926. /**
  927.  * Saves the option value (this is the default save function
  928.  * unless overridden by the user)
  929.  *
  930.  * @param object $option object that holds option name and new_value
  931.  */
  932. function save_option($option{
  933.  
  934.     // Can't save the pref if we don't have the username
  935.     //
  936.     if !sqgetGlobalVar('username'$usernameSQ_SESSION ) ) {
  937.         return;
  938.     }
  939.  
  940.     // if the widget is a selection list, make sure the new
  941.     // value is actually in the selection list and is not an
  942.     // injection attack
  943.     //
  944.     if ($option->type == SMOPT_TYPE_STRLIST
  945.      && !array_key_exists($option->new_value$option->possible_values))
  946.         return;
  947.  
  948.  
  949.     // all other widgets except TEXTAREAs should never be allowed to have newlines
  950.     //
  951.     else if ($option->type != SMOPT_TYPE_TEXTAREA)
  952.         $option->new_value str_replace(array("\r""\n")''$option->new_value);
  953.  
  954.  
  955.     global $data_dir;
  956.  
  957.     // edit lists: first add new elements to list, then
  958.     // remove any selected ones (note that we must add
  959.     // before deleting because the javascript that populates
  960.     // the "add" textbox when selecting items in the list
  961.     // (for deletion))
  962.     //
  963.     if ($option->type == SMOPT_TYPE_EDIT_LIST{
  964.  
  965.         if (empty($option->possible_values)) $option->possible_values array();
  966.         if (!is_array($option->possible_values)) $option->possible_values array($option->possible_values);
  967.  
  968.         // add element if given
  969.         //
  970.         if ((isset($option->use_add_widget&& $option->use_add_widget)
  971.          && sqGetGlobalVar('add_' $option->name$new_elementSQ_POST)) {
  972.             $new_element trim($new_element);
  973.             if (!empty($new_element)
  974.              && !in_array($new_element$option->possible_values))
  975.                 $option->possible_values[$new_element;
  976.         }
  977.         
  978.         // delete selected elements if needed
  979.         //
  980.         if ((isset($option->use_delete_widget&& $option->use_delete_widget)
  981.          && is_array($option->new_value)
  982.          && sqGetGlobalVar('delete_' $option->name$ignoreSQ_POST))
  983.             $option->possible_values array_diff($option->possible_values$option->new_value);
  984.  
  985.         // save full list (stored in "possible_values")
  986.         //
  987.         setPref($data_dir$username$option->nameserialize($option->possible_values));
  988.  
  989.     // associative edit lists are handled similar to
  990.     // non-associative ones
  991.     //
  992.     else if ($option->type == SMOPT_TYPE_EDIT_LIST_ASSOCIATIVE{
  993.  
  994.         if (empty($option->possible_values)) $option->possible_values array();
  995.         if (!is_array($option->possible_values)) $option->possible_values array($option->possible_values);
  996.  
  997.         // add element if given
  998.         //
  999.         $new_element_key '';
  1000.         $new_element_value '';
  1001.         $retrieve_key sqGetGlobalVar('add_' $option->name '_key'$new_element_keySQ_POST);
  1002.         $retrieve_value sqGetGlobalVar('add_' $option->name '_value'$new_element_valueSQ_POST);
  1003.  
  1004.         if ((isset($option->use_add_widget&& $option->use_add_widget)
  1005.          && ($retrieve_key || $retrieve_value)) {
  1006.             $new_element_key trim($new_element_key);
  1007.             $new_element_value trim($new_element_value);
  1008.             if ($option->poss_value_folders && empty($new_element_key))
  1009.                 $new_element_value '';
  1010.             if (!empty($new_element_key|| !empty($new_element_value)) {
  1011.                 if (empty($new_element_key)) $new_element_key '0';
  1012.                 $option->possible_values[$new_element_key$new_element_value;
  1013.             }
  1014.         }
  1015.  
  1016.         // delete selected elements if needed
  1017.         //
  1018.         if ((isset($option->use_delete_widget&& $option->use_delete_widget)
  1019.          && is_array($option->new_value)
  1020.          && sqGetGlobalVar('delete_' $option->name$ignoreSQ_POST)) {
  1021.  
  1022.             if ($option->layout_type == SMOPT_EDIT_LIST_LAYOUT_SELECT{
  1023.                 foreach ($option->new_value as $key)
  1024.                     unset($option->possible_values[urldecode($key)]);
  1025.             }
  1026.             else
  1027.                 $option->possible_values array_diff($option->possible_values$option->new_value);
  1028.         }
  1029.  
  1030.         // save full list (stored in "possible_values")
  1031.         //
  1032.         setPref($data_dir$username$option->nameserialize($option->possible_values));
  1033.  
  1034.     // Certain option types need to be serialized because
  1035.     // they are not scalar
  1036.     //
  1037.     else if ($option->is_multiple_valued())
  1038.         setPref($data_dir$username$option->nameserialize($option->new_value));
  1039.  
  1040.     // Checkboxes, when unchecked, don't submit anything in
  1041.     // the POST, so set to SMPREF_OFF if not found
  1042.     //
  1043.     else if (($option->type == SMOPT_TYPE_BOOLEAN
  1044.            || $option->type == SMOPT_TYPE_BOOLEAN_CHECKBOX)
  1045.           && empty($option->new_value)) 
  1046.         setPref($data_dir$username$option->nameSMPREF_OFF);
  1047.  
  1048.     // For integer fields, make sure we only have digits...
  1049.     // We'll be nice and instead of just converting to an integer,
  1050.     // we'll physically remove each non-digit in the string.
  1051.     //
  1052.     else if ($option->type == SMOPT_TYPE_INTEGER{
  1053.         $option->new_value preg_replace('/[^0-9]/'''$option->new_value);
  1054.         setPref($data_dir$username$option->name$option->new_value);
  1055.     }
  1056.  
  1057.     else
  1058.         setPref($data_dir$username$option->name$option->new_value);
  1059.  
  1060.  
  1061.     // if a checkbox or multi select is zeroed/cleared out, it
  1062.     // needs to have an empty value pushed into its "new_value" slot
  1063.     //
  1064.     if (($option->type == SMOPT_TYPE_STRLIST_MULTI
  1065.       || $option->type == SMOPT_TYPE_BOOLEAN_CHECKBOX)
  1066.      && is_null($option->new_value))
  1067.         $option->new_value '';
  1068.  
  1069. }
  1070.  
  1071. /**
  1072.  * save function that does not save
  1073.  * @param object $option 
  1074.  */
  1075. function save_option_noop($option{
  1076.     /* Do nothing here... */
  1077. }
  1078.  
  1079. /**
  1080.  * Create hidden 'optpage' input field with value set by argument
  1081.  * @param string $optpage identification of option page
  1082.  * @return string html formated hidden input field
  1083.  */
  1084. function create_optpage_element($optpage{
  1085.     return addHidden('optpage'$optpage);
  1086. }
  1087.  
  1088. /**
  1089.  * Create hidden 'optmode' input field with value set by argument
  1090.  * @param string $optmode 
  1091.  * @return string html formated hidden input field
  1092.  */
  1093. function create_optmode_element($optmode{
  1094.     return addHidden('optmode'$optmode);
  1095. }
  1096.  
  1097. /**
  1098.  * @param array $optgrps 
  1099.  * @param array $optvals 
  1100.  * @return array 
  1101.  */
  1102. function create_option_groups($optgrps$optvals{
  1103.     /* Build a simple array with which to start. */
  1104.     $result array();
  1105.  
  1106.     /* Create option group for each option group name. */
  1107.     foreach ($optgrps as $grpkey => $grpname{
  1108.         $result[$grpkeyarray();
  1109.         $result[$grpkey]['name'$grpname;
  1110.         $result[$grpkey]['options'array();
  1111.     }
  1112.  
  1113.      /* Create a new SquirrelOption for each set of option values. */
  1114.     foreach ($optvals as $grpkey => $grpopts{
  1115.         foreach ($grpopts as $optset{
  1116.             /* Create a new option with all values given. */
  1117.             $next_option new SquirrelOption(
  1118.                     $optset,
  1119.                     $optset['name'],
  1120.                     $optset['caption'],
  1121.                     $optset['type'],
  1122.                     (isset($optset['refresh']$optset['refresh'SMOPT_REFRESH_NONE),
  1123.                     (isset($optset['initial_value']$optset['initial_value'''),
  1124.                     (isset($optset['posvals']$optset['posvals'''),
  1125.                     (isset($optset['htmlencoded']$optset['htmlencoded'false)
  1126.                     );
  1127.  
  1128.             /* If provided, set if the caption is allowed to wrap for this option. */
  1129.             if (isset($optset['caption_wrap'])) {
  1130.                 $next_option->setCaptionWrap($optset['caption_wrap']);
  1131.             }
  1132.  
  1133.             /* If provided, set the size for this option. */
  1134.             if (isset($optset['size'])) {
  1135.                 $next_option->setSize($optset['size']);
  1136.             }
  1137.  
  1138.             /* If provided, set the trailing_text for this option. */
  1139.             if (isset($optset['trailing_text'])) {
  1140.                 $next_option->setTrailingText($optset['trailing_text']);
  1141.             }
  1142.  
  1143.             /* If provided, set the yes_text for this option. */
  1144.             if (isset($optset['yes_text'])) {
  1145.                 $next_option->setYesText($optset['yes_text']);
  1146.             }
  1147.  
  1148.             /* If provided, set the no_text for this option. */
  1149.             if (isset($optset['no_text'])) {
  1150.                 $next_option->setNoText($optset['no_text']);
  1151.             }
  1152.  
  1153.             /* If provided, set the poss_value_folders value for this option. */
  1154.             if (isset($optset['poss_value_folders'])) {
  1155.                 $next_option->setPossValueFolders($optset['poss_value_folders']);
  1156.             }
  1157.  
  1158.             /* If provided, set the layout type for this option. */
  1159.             if (isset($optset['layout_type'])) {
  1160.                 $next_option->setLayoutType($optset['layout_type']);
  1161.             }
  1162.  
  1163.             /* If provided, set the use_add_widget value for this option. */
  1164.             if (isset($optset['use_add_widget'])) {
  1165.                 $next_option->setUseAddWidget($optset['use_add_widget']);
  1166.             }
  1167.  
  1168.             /* If provided, set the use_delete_widget value for this option. */
  1169.             if (isset($optset['use_delete_widget'])) {
  1170.                 $next_option->setUseDeleteWidget($optset['use_delete_widget']);
  1171.             }
  1172.  
  1173.             /* If provided, set the comment for this option. */
  1174.             if (isset($optset['comment'])) {
  1175.                 $next_option->setComment($optset['comment']);
  1176.             }
  1177.  
  1178.             /* If provided, set the save function for this option. */
  1179.             if (isset($optset['save'])) {
  1180.                 $next_option->setSaveFunction($optset['save']);
  1181.             }
  1182.  
  1183.             /* If provided, set the extra attributes for this option. */
  1184.             if (isset($optset['extra_attributes'])) {
  1185.                 $next_option->setExtraAttributes($optset['extra_attributes']);
  1186.             }
  1187.  
  1188.             /* If provided, set the "post script" for this option. */
  1189.             if (isset($optset['post_script'])) {
  1190.                 $next_option->setPostScript($optset['post_script']);
  1191.             }
  1192.  
  1193.             /* If provided, set the folder_filter for this option. */
  1194.             if (isset($optset['folder_filter'])) {
  1195.                 $next_option->setFolderFilter($optset['folder_filter']);
  1196.             }
  1197.  
  1198.             /* Add this option to the option array. */
  1199.             $result[$grpkey]['options'][$next_option;
  1200.         }
  1201.     }
  1202.  
  1203.     /* Return our resulting array. */
  1204.     return ($result);
  1205. }

Documentation generated on Wed, 30 Jul 2014 04:18:58 +0200 by phpDocumentor 1.4.3