Source for file forms.php

Documentation is available at forms.php

  1. <?php
  2.  
  3. /**
  4.  * forms.php - html form functions
  5.  *
  6.  * Functions to build forms in a safe and consistent manner.
  7.  * All attribute values are sanitized with sm_encode_html_special_chars().
  8. //FIXME: I think the Template class might be better place to sanitize inside assign() method
  9.  *
  10.  * Currently functions don't provide simple wrappers for file and
  11.  * image input fields, support only submit and reset buttons and use
  12.  * html input tags for buttons.
  13.  *
  14.  * Since 1.5.1:
  15.  *
  16.  *  * all form functions should support id tags. Original
  17.  *  idea by dugan <at> passwall.com. Tags can be used for Section 508
  18.  *  or WAI compliance.
  19.  *
  20.  *  * input tag functions accept extra html attributes that can be submitted
  21.  *  in $aAttribs array.
  22.  *
  23.  *  * default css class attributes are added.
  24.  *
  25.  * @link http://www.section508.gov/ Section 508
  26.  * @link http://www.w3.org/WAI/ Web Accessibility Initiative (WAI)
  27.  * @link http://www.w3.org/TR/html4/ W3.org HTML 4.01 form specs
  28.  * @copyright 2004-2020 The SquirrelMail Project Team
  29.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  30.  * @version $Id: forms.php 14845 2020-01-07 08:09:34Z pdontthink $
  31.  * @package squirrelmail
  32.  * @subpackage forms
  33.  * @since 1.4.3 and 1.5.1
  34.  */
  35.  
  36. /**
  37.  * Helper function to create form fields, not to be called directly,
  38.  * only by other functions below.
  39.  * 
  40.  * Function used different syntax before 1.5.1
  41.  * @param string $sType type of input field. Possible values (html 4.01
  42.  *   specs.): text, password, checkbox, radio, submit, reset, file,
  43.  *   hidden, image, button.
  44.  * @param array $aAttribs (since 1.5.1) extra attributes. Array key is
  45.  *   attribute name, array value is attribute value. Array keys must use
  46.  *   lowercase.
  47.  * @return string html formated input field
  48.  * @deprecated use other functions that provide simple wrappers to this function
  49.  */
  50. function addInputField($sType$aAttribs=array()) {
  51.     $sAttribs '';
  52.     // define unique identifier
  53.     if (isset($aAttribs['id']&& isset($aAttribs['name']&& is_null($aAttribs['name'])) {
  54.         /**
  55.          * if 'id' is not set, set it to 'name' and replace brackets 
  56.          * with underscores. 'name' might contain field name with squire
  57.          * brackets (array). Brackets are not allowed in id (validator.w3.org
  58.          * fails to validate document). According to html 4.01 manual cdata 
  59.          * type description, 'name' attribute uses same type, but validator.w3.org 
  60.          * does not barf on brackets in 'name' attributes.
  61.          */
  62.         $aAttribs['id'strtr($aAttribs['name'],'[]','__');
  63.     }
  64.  
  65.     global $oTemplate;
  66.  
  67.     $oTemplate->assign('type'$sType);
  68. //FIXME: all the values in the $aAttribs list used to go thru sm_encode_html_special_chars()... I would propose that most everything that is assigned to the template should go thru that *in the template class* on its way between here and the actual template file.  Otherwise we have to do something like:  foreach ($aAttribs as $key => $value) $aAttribs[$key] = sm_encode_html_special_chars($value);
  69.     $oTemplate->assign('aAttribs'$aAttribs);
  70.  
  71.     return $oTemplate->fetch('input.tpl');
  72.  
  73. }
  74.  
  75. /**
  76.  * Password input field
  77.  * @param string $sName field name
  78.  * @param string $sValue initial password value
  79.  * @param integer $iSize field size (number of characters)
  80.  * @param integer $iMaxlength maximum number of characters the user may enter
  81.  * @param array $aAttribs (since 1.5.1) extra attributes - should be given
  82.  *                         in the form array('attribute_name' => 'attribute_value', ...)
  83.  * @return string html formated password field
  84.  */
  85. function addPwField($sName$sValue ''$iSize 0$iMaxlength 0$aAttribs=array()) {
  86.     $aAttribs['name']  $sName;
  87.     $aAttribs['value'$sValue;
  88.     if ($iSize$aAttribs['size'= (int)$iSize;
  89.     if ($iMaxlength$aAttribs['maxlength'= (int)$iMaxlength;
  90.     // add default css
  91.     if (isset($aAttribs['class'])) $aAttribs['class''sqmpwfield';
  92.     return addInputField('password',$aAttribs);
  93. }
  94.  
  95. /**
  96.  * Form checkbox
  97.  * @param string $sName field name
  98.  * @param boolean $bChecked controls if field is checked
  99.  * @param string $sValue 
  100.  * @param array $aAttribs (since 1.5.1) extra attributes
  101.  * @return string html formated checkbox field
  102.  */
  103. function addCheckBox($sName$bChecked false$sValue null$aAttribs=array()) {
  104.     $aAttribs['name'$sName;
  105.     if ($bChecked$aAttribs['checked''checked';
  106.     if (is_null($sValue)) $aAttribs['value'$sValue;
  107.     // add default css
  108.     if (isset($aAttribs['class'])) $aAttribs['class''sqmcheckbox';
  109.     return addInputField('checkbox',$aAttribs);
  110. }
  111.  
  112. /**
  113.  * Form radio box
  114.  * @param string $sName field name
  115.  * @param boolean $bChecked controls if field is selected
  116.  * @param string $sValue 
  117.  * @param array $aAttribs (since 1.5.1) extra attributes.
  118.  * @return string html formated radio box
  119.  */
  120. function addRadioBox($sName$bChecked false$sValue null$aAttribs=array()) {
  121.     $aAttribs['name'$sName;
  122.     if ($bChecked$aAttribs['checked''checked';
  123.     if (is_null($sValue)) $aAttribs['value'$sValue;
  124.     if (isset($aAttribs['id'])) $aAttribs['id'$sName $sValue;
  125.     // add default css
  126.     if (isset($aAttribs['class'])) $aAttribs['class''sqmradiobox';
  127.     return addInputField('radio'$aAttribs);
  128. }
  129.  
  130. /**
  131.  * A hidden form field.
  132.  * @param string $sName field name
  133.  * @param string $sValue field value
  134.  * @param array $aAttribs (since 1.5.1) extra attributes
  135.  * @return html formated hidden form field
  136.  */
  137. function addHidden($sName$sValue$aAttribs=array()) {
  138.     $aAttribs['name'$sName;
  139.     $aAttribs['value'$sValue;
  140.     // add default css
  141.     if (isset($aAttribs['class'])) $aAttribs['class''sqmhiddenfield';
  142.     return addInputField('hidden'$aAttribs);
  143. }
  144.  
  145. /**
  146.  * An input textbox.
  147.  * @param string $sName field name
  148.  * @param string $sValue initial field value
  149.  * @param integer $iSize field size (number of characters)
  150.  * @param integer $iMaxlength maximum number of characters the user may enter
  151.  * @param array $aAttribs (since 1.5.1) extra attributes - should be given
  152.  *                         in the form array('attribute_name' => 'attribute_value', ...)
  153.  * @return string html formated text input field
  154.  */
  155. function addInput($sName$sValue ''$iSize 0$iMaxlength 0$aAttribs=array()) {
  156.     $aAttribs['name'$sName;
  157.     $aAttribs['value'$sValue;
  158.     if ($iSize$aAttribs['size'= (int)$iSize;
  159.     if ($iMaxlength$aAttribs['maxlength'= (int)$iMaxlength;
  160.     // add default css
  161.     if (isset($aAttribs['class'])) $aAttribs['class''sqmtextfield';
  162.     return addInputField('text'$aAttribs);
  163. }
  164.  
  165. /**
  166.  * Function to create a selectlist from an array.
  167.  * @param string  $sName     Field name
  168.  * @param array   $aValues   Field values array(key => value) results in:
  169.  *                            <option value="key">value</option>,
  170.  *                            although if $bUsekeys is FALSE, then it changes to:
  171.  *                            <option value="value">value</option>
  172.  * @param mixed   $default   The key(s) that will be selected (it is OK to pass
  173.  *                            in an array here in the case of multiple select lists)
  174.  * @param boolean $bUsekeys  Use the keys of the array as option value or not
  175.  * @param array   $aAttribs  (since 1.5.1) Extra attributes
  176.  * @param boolean $bMultiple When TRUE, a multiple select list will be shown
  177.  *                            (OPTIONAL; default is FALSE (single select list))
  178.  * @param int     $iSize     Desired height of multiple select boxes
  179.  *                            (OPTIONAL; default is SMOPT_SIZE_NORMAL)
  180.  *                            (only applicable when $bMultiple is TRUE)
  181.  *
  182.  * @return string html formated selection box
  183.  * @todo add attributes argument for option tags and default css
  184.  */
  185. function addSelect($sName$aValues$default null$bUsekeys false$aAttribs array()$bMultiple FALSE$iSize SMOPT_SIZE_NORMAL{
  186.     // only one element
  187.     if (!$bMultiple && count($aValues== 1{
  188.         $k key($aValues)$v array_pop($aValues);
  189.         return addHidden($sName($bUsekeys $k $v)$aAttribs)
  190.              . sm_encode_html_special_chars($v);
  191.     }
  192.  
  193.     if (isset($aAttribs['id'])) $aAttribs['id'$sName;
  194.  
  195.     // make sure $default is an array, since multiple select lists
  196.     // need the chance to have more than one default... 
  197.     //
  198.     if (!is_array($default))
  199.        $default array($default);
  200.  
  201.  
  202.     global $oTemplate;
  203.  
  204. //FIXME: all the values in the $aAttribs list and $sName and both the keys and values in $aValues used to go thru sm_encode_html_special_chars()... I would propose that most everything that is assigned to the template should go thru that *in the template class* on its way between here and the actual template file.  Otherwise we have to do something like:  foreach ($aAttribs as $key => $value) $aAttribs[$key] = sm_encode_html_special_chars($value); $sName = sm_encode_html_special_chars($sName); $aNewValues = array(); foreach ($aValues as $key => $value) $aNewValues[sm_encode_html_special_chars($key)] = sm_encode_html_special_chars($value); $aValues = $aNewValues;   And probably this too because it has to be matched to a value that has already been sanitized: $default = sm_encode_html_special_chars($default);  (oops, watch out for when $default is an array! (multiple select lists))
  205.     $oTemplate->assign('aAttribs'$aAttribs);
  206.     $oTemplate->assign('aValues'$aValues);
  207.     $oTemplate->assign('bUsekeys'$bUsekeys);
  208.     $oTemplate->assign('default'$default);
  209.     $oTemplate->assign('name'$sName);
  210.     $oTemplate->assign('multiple'$bMultiple);
  211.     $oTemplate->assign('size'$iSize);
  212.  
  213.     return $oTemplate->fetch('select.tpl');
  214. }
  215.  
  216. /**
  217.  * Normal button
  218.  *
  219.  * Note the switched value/name parameters!
  220.  * Note also that regular buttons are not very useful unless
  221.  * used with onclick handlers, thus are only really appropriate
  222.  * if you use them after having checked if JavaScript is turned
  223.  * on by doing this:  if (checkForJavascript()) ...
  224.  *
  225.  * @param string $sValue button name
  226.  * @param string $sName key name
  227.  * @param array $aAttribs extra attributes
  228.  *
  229.  * @return string html formated submit input field
  230.  *
  231.  * @since 1.5.2
  232.  */
  233. function addButton($sValue$sName null$aAttribs=array()) {
  234.     $aAttribs['value'$sValue;
  235.     if (is_null($sName)) $aAttribs['name'$sName;
  236.     // add default css
  237.     if (isset($aAttribs['class'])) $aAttribs['class''sqmsubmitfield';
  238.     return addInputField('button'$aAttribs);
  239. }
  240.  
  241. /**
  242.  * Form submission button
  243.  * Note the switched value/name parameters!
  244.  * @param string $sValue button name
  245.  * @param string $sName submitted key name
  246.  * @param array $aAttribs (since 1.5.1) extra attributes
  247.  * @return string html formated submit input field
  248.  */
  249. function addSubmit($sValue$sName null$aAttribs=array()) {
  250.     $aAttribs['value'$sValue;
  251.     if (is_null($sName)) $aAttribs['name'$sName;
  252.     // add default css
  253.     if (isset($aAttribs['class'])) $aAttribs['class''sqmsubmitfield';
  254.     return addInputField('submit'$aAttribs);
  255. }
  256.  
  257. /**
  258.  * Form reset button
  259.  * @param string $sValue button name
  260.  * @param array $aAttribs (since 1.5.1) extra attributes
  261.  * @return string html formated reset input field
  262.  */
  263. function addReset($sValue$aAttribs=array()) {
  264.     $aAttribs['value'$sValue;
  265.     // add default css
  266.     if (isset($aAttribs['class'])) $aAttribs['class''sqmresetfield';
  267.     return addInputField('reset'$aAttribs);
  268. }
  269.  
  270. /**
  271.  * Textarea form element.
  272.  *
  273.  * @param string  $sName    field name
  274.  * @param string  $sText    initial field value (OPTIONAL; default empty)
  275.  * @param integer $iCols    field width (number of chars) (OPTIONAL; default 40)
  276.  * @param integer $iRows    field height (number of character rows) (OPTIONAL; default 10)
  277.  * @param array   $aAttribs (since 1.5.1) extra attributes (OPTIONAL; default empty)
  278.  *
  279.  * @return string html formated text area field
  280.  *
  281.  */
  282. function addTextArea($sName$sText ''$iCols 40$iRows 10$aAttribs array()) {
  283.  
  284.     // no longer accept string arguments for attribs; print 
  285.     // backtrace to help people fix their code
  286.     //FIXME: throw error instead?
  287.     if (!is_array($aAttribs)) {
  288.         echo '$aAttribs argument to addTextArea() must be an array<br /><pre>';
  289.         debug_print_backtrace();
  290.         echo '</pre><br />';
  291.         exit;
  292.     }
  293.  
  294.     // add default css
  295.     else if (!isset($aAttribs['class'])) $aAttribs['class''sqmtextarea';
  296.     
  297.     if empty$aAttribs['id') ) {
  298.         $aAttribs['id'strtr($sName,'[]','__');
  299.     }
  300.  
  301.     global $oTemplate;
  302.  
  303. //FIXME: all the values in the $aAttribs list as well as $sName and $sText used to go thru sm_encode_html_special_chars()... I would propose that most everything that is assigned to the template should go thru that *in the template class* on its way between here and the actual template file.  Otherwise we have to do something like:  foreach ($aAttribs as $key => $value) $aAttribs[$key] = sm_encode_html_special_chars($value); $sName = sm_encode_html_special_chars($sName); $sText = sm_encode_html_special_chars($sText);
  304.     $oTemplate->assign('aAttribs'$aAttribs);
  305.     $oTemplate->assign('name'$sName);
  306.     $oTemplate->assign('text'$sText);
  307.     $oTemplate->assign('cols'(int)$iCols);
  308.     $oTemplate->assign('rows'(int)$iRows);
  309.  
  310.     return $oTemplate->fetch('textarea.tpl');
  311. }
  312.  
  313. /**
  314.  * Make a <form> start-tag.
  315.  *
  316.  * @param string  $sAction   form handler URL
  317.  * @param string  $sMethod   http method used to submit form data. 'get' or 'post'
  318.  * @param string  $sName     form name used for identification (used for backward
  319.  *                            compatibility). Use of id is recommended instead.
  320.  * @param string  $sEnctype  content type that is used to submit data. html 4.01
  321.  *                            defaults to 'application/x-www-form-urlencoded'. Form
  322.  *                            with file field needs 'multipart/form-data' encoding type.
  323.  * @param string  $sCharset  charset that is used for submitted data
  324.  * @param array   $aAttribs  (since 1.5.1) extra attributes
  325.  * @param boolean $bAddToken (since 1.5.2) When given as a string or as boolean TRUE,
  326.  *                            a hidden input is also added to the form containing a
  327.  *                            security token.  When given as TRUE, the input name is
  328.  *                            "smtoken"; otherwise the name is the string that is
  329.  *                            given for this parameter.  When FALSE, no hidden token
  330.  *                            input field is added.  (OPTIONAL; default not used)
  331.  *
  332.  * @return string html formated form start string
  333.  *
  334.  */
  335. function addForm($sAction$sMethod 'post'$sName ''$sEnctype ''$sCharset ''$aAttribs array()$bAddToken FALSE{
  336.  
  337.     global $oTemplate;
  338.  
  339. //FIXME: all the values in the $aAttribs list as well as $charset used to go thru sm_encode_html_special_chars()... I would propose that most everything that is assigned to the template should go thru that *in the template class* on its way between here and the actual template file.  Otherwise we have to do something like:  foreach ($aAttribs as $key => $value) $aAttribs[$key] = sm_encode_html_special_chars($value); $sCharset = sm_encode_html_special_chars($sCharset);
  340.     $oTemplate->assign('aAttribs'$aAttribs);
  341.     $oTemplate->assign('name'$sName);
  342.     $oTemplate->assign('method'$sMethod);
  343.     $oTemplate->assign('action'$sAction);
  344.     $oTemplate->assign('enctype'$sEnctype);
  345.     $oTemplate->assign('charset'$sCharset);
  346.  
  347.     $sForm $oTemplate->fetch('form.tpl');
  348.  
  349.     if ($bAddToken{
  350.         $sForm .= addHidden((is_string($bAddToken$bAddToken 'smtoken'),
  351.                             sm_generate_security_token());
  352.     }
  353.  
  354.     return $sForm;
  355. }
  356.  
  357. /**
  358.   * Creates unique widget names
  359.   *
  360.   * Names are formatted as such: "send1", "send2", "send3", etc.,
  361.   * where "send" in this example is what was given for $base_name
  362.   *
  363.   * @param string  $base_name    The name upon which to base the
  364.   *                               returned widget name.
  365.   * @param boolean $return_count When TRUE, this function will
  366.   *                               return the last number used to
  367.   *                               create a widget name for $base_name
  368.   *                               (OPTIONAL; default = FALSE).
  369.   *
  370.   * @return mixed When $return_output is FALSE, a string containing
  371.   *                the unique widget name; otherwise an integer with
  372.   *                the last number used to create the last widget
  373.   *                name for the given $base_name (where 0 (zero) means
  374.   *                that no such widgets have been created yet).
  375.   *
  376.   * @since 1.5.2
  377.   *
  378.   */
  379. function unique_widget_name($base_name$return_count=FALSE)
  380. {
  381.    static $counts array();
  382.  
  383.    if (!isset($counts[$base_name]))
  384.       $counts[$base_name0;
  385.  
  386.    if ($return_count)
  387.       return $counts[$base_name];
  388.  
  389.    ++$counts[$base_name];
  390.    return $base_name $counts[$base_name];
  391. }

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