| 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 htmlspecialchars(). |
| 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-2007 The SquirrelMail Project Team |
| 29 | * @license http://opensource.org/licenses/gpl-license.php GNU Public License |
| 30 | * @version $Id$ |
| 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 htmlspecialchars()... 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] = htmlspecialchars($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 array $aAttribs (since 1.5.1) extra attributes |
| 80 | * @return string html formated password field |
| 81 | */ |
| 82 | function addPwField($sName, $sValue = null, $aAttribs=array()) { |
| 83 | $aAttribs['name'] = $sName; |
| 84 | $aAttribs['value'] = (! is_null($sValue) ? $sValue : ''); |
| 85 | // add default css |
| 86 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmpwfield'; |
| 87 | return addInputField('password',$aAttribs); |
| 88 | } |
| 89 | |
| 90 | /** |
| 91 | * Form checkbox |
| 92 | * @param string $sName field name |
| 93 | * @param boolean $bChecked controls if field is checked |
| 94 | * @param string $sValue |
| 95 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 96 | * @return string html formated checkbox field |
| 97 | */ |
| 98 | function addCheckBox($sName, $bChecked = false, $sValue = null, $aAttribs=array()) { |
| 99 | $aAttribs['name'] = $sName; |
| 100 | if ($bChecked) $aAttribs['checked'] = 'checked'; |
| 101 | if (! is_null($sValue)) $aAttribs['value'] = $sValue; |
| 102 | // add default css |
| 103 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmcheckbox'; |
| 104 | return addInputField('checkbox',$aAttribs); |
| 105 | } |
| 106 | |
| 107 | /** |
| 108 | * Form radio box |
| 109 | * @param string $sName field name |
| 110 | * @param boolean $bChecked controls if field is selected |
| 111 | * @param string $sValue |
| 112 | * @param array $aAttribs (since 1.5.1) extra attributes. |
| 113 | * @return string html formated radio box |
| 114 | */ |
| 115 | function addRadioBox($sName, $bChecked = false, $sValue = null, $aAttribs=array()) { |
| 116 | $aAttribs['name'] = $sName; |
| 117 | if ($bChecked) $aAttribs['checked'] = 'checked'; |
| 118 | if (! is_null($sValue)) $aAttribs['value'] = $sValue; |
| 119 | if (! isset($aAttribs['id'])) $aAttribs['id'] = $sName . $sValue; |
| 120 | // add default css |
| 121 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmradiobox'; |
| 122 | return addInputField('radio', $aAttribs); |
| 123 | } |
| 124 | |
| 125 | /** |
| 126 | * A hidden form field. |
| 127 | * @param string $sName field name |
| 128 | * @param string $sValue field value |
| 129 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 130 | * @return html formated hidden form field |
| 131 | */ |
| 132 | function addHidden($sName, $sValue, $aAttribs=array()) { |
| 133 | $aAttribs['name'] = $sName; |
| 134 | $aAttribs['value'] = $sValue; |
| 135 | // add default css |
| 136 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmhiddenfield'; |
| 137 | return addInputField('hidden', $aAttribs); |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * An input textbox. |
| 142 | * @param string $sName field name |
| 143 | * @param string $sValue initial field value |
| 144 | * @param integer $iSize field size (number of characters) |
| 145 | * @param integer $iMaxlength maximum number of characters the user may enter |
| 146 | * @param array $aAttribs (since 1.5.1) extra attributes - should be given |
| 147 | * in the form array('attribute_name' => 'attribute_value', ...) |
| 148 | * @return string html formated text input field |
| 149 | */ |
| 150 | function addInput($sName, $sValue = '', $iSize = 0, $iMaxlength = 0, $aAttribs=array()) { |
| 151 | $aAttribs['name'] = $sName; |
| 152 | $aAttribs['value'] = $sValue; |
| 153 | if ($iSize) $aAttribs['size'] = (int)$iSize; |
| 154 | if ($iMaxlength) $aAttribs['maxlength'] = (int)$iMaxlength; |
| 155 | // add default css |
| 156 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmtextfield'; |
| 157 | return addInputField('text', $aAttribs); |
| 158 | } |
| 159 | |
| 160 | /** |
| 161 | * Function to create a selectlist from an array. |
| 162 | * @param string $sName Field name |
| 163 | * @param array $aValues Field values array(key => value) results in: |
| 164 | * <option value="key">value</option>, |
| 165 | * although if $bUsekeys is FALSE, then it changes to: |
| 166 | * <option value="value">value</option> |
| 167 | * @param mixed $default The key(s) that will be selected (it is OK to pass |
| 168 | * in an array here in the case of multiple select lists) |
| 169 | * @param boolean $bUsekeys Use the keys of the array as option value or not |
| 170 | * @param array $aAttribs (since 1.5.1) Extra attributes |
| 171 | * @param boolean $bMultiple When TRUE, a multiple select list will be shown |
| 172 | * (OPTIONAL; default is FALSE (single select list)) |
| 173 | * |
| 174 | * @return string html formated selection box |
| 175 | * @todo add attributes argument for option tags and default css |
| 176 | */ |
| 177 | function addSelect($sName, $aValues, $default = null, $bUsekeys = false, $aAttribs = array(), $bMultiple = FALSE) { |
| 178 | // only one element |
| 179 | if(count($aValues) == 1) { |
| 180 | $k = key($aValues); $v = array_pop($aValues); |
| 181 | return addHidden($sName, ($bUsekeys ? $k:$v), $aAttribs). |
| 182 | htmlspecialchars($v) . "\n"; |
| 183 | } |
| 184 | |
| 185 | |
| 186 | // make sure $default is an array, since multiple select lists |
| 187 | // need the chance to have more than one default... |
| 188 | // |
| 189 | if (!is_array($default)) |
| 190 | $default = array($default); |
| 191 | |
| 192 | |
| 193 | global $oTemplate; |
| 194 | |
| 195 | //FIXME: all the values in the $aAttribs list and $sName and both the keys and values in $aValues used to go thru htmlspecialchars()... 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] = htmlspecialchars($value); $sName = htmlspecialchars($sName); $aNewValues = array(); foreach ($aValues as $key => $value) $aNewValues[htmlspecialchars($key)] = htmlspecialchars($value); $aValues = $aNewValues; And probably this too because it has to be matched to a value that has already been sanitized: $default = htmlspecialchars($default); (oops, watch out for when $default is an array! (multiple select lists)) |
| 196 | $oTemplate->assign('aAttribs', $aAttribs); |
| 197 | $oTemplate->assign('aValues', $aValues); |
| 198 | $oTemplate->assign('bUsekeys', $bUsekeys); |
| 199 | $oTemplate->assign('default', $default); |
| 200 | $oTemplate->assign('name', $sName); |
| 201 | $oTemplate->assign('multiple', $bMultiple); |
| 202 | |
| 203 | return $oTemplate->fetch('select.tpl'); |
| 204 | } |
| 205 | |
| 206 | /** |
| 207 | * Normal button |
| 208 | * |
| 209 | * Note the switched value/name parameters! |
| 210 | * Note also that regular buttons are not very useful unless |
| 211 | * used with onclick handlers, thus are only really appropriate |
| 212 | * if you use them after having checked if JavaScript is turned |
| 213 | * on by doing this: if (checkForJavascript()) ... |
| 214 | * |
| 215 | * @param string $sValue button name |
| 216 | * @param string $sName key name |
| 217 | * @param array $aAttribs extra attributes |
| 218 | * |
| 219 | * @return string html formated submit input field |
| 220 | * |
| 221 | * @since 1.5.2 |
| 222 | */ |
| 223 | function addButton($sValue, $sName = null, $aAttribs=array()) { |
| 224 | $aAttribs['value'] = $sValue; |
| 225 | if (! is_null($sName)) $aAttribs['name'] = $sName; |
| 226 | // add default css |
| 227 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmsubmitfield'; |
| 228 | return addInputField('button', $aAttribs); |
| 229 | } |
| 230 | |
| 231 | /** |
| 232 | * Form submission button |
| 233 | * Note the switched value/name parameters! |
| 234 | * @param string $sValue button name |
| 235 | * @param string $sName submitted key name |
| 236 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 237 | * @return string html formated submit input field |
| 238 | */ |
| 239 | function addSubmit($sValue, $sName = null, $aAttribs=array()) { |
| 240 | $aAttribs['value'] = $sValue; |
| 241 | if (! is_null($sName)) $aAttribs['name'] = $sName; |
| 242 | // add default css |
| 243 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmsubmitfield'; |
| 244 | return addInputField('submit', $aAttribs); |
| 245 | } |
| 246 | |
| 247 | /** |
| 248 | * Form reset button |
| 249 | * @param string $sValue button name |
| 250 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 251 | * @return string html formated reset input field |
| 252 | */ |
| 253 | function addReset($sValue, $aAttribs=array()) { |
| 254 | $aAttribs['value'] = $sValue; |
| 255 | // add default css |
| 256 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmresetfield'; |
| 257 | return addInputField('reset', $aAttribs); |
| 258 | } |
| 259 | |
| 260 | /** |
| 261 | * Textarea form element. |
| 262 | * |
| 263 | * @param string $sName field name |
| 264 | * @param string $sText initial field value (OPTIONAL; default empty) |
| 265 | * @param integer $iCols field width (number of chars) (OPTIONAL; default 40) |
| 266 | * @param integer $iRows field height (number of character rows) (OPTIONAL; default 10) |
| 267 | * @param array $aAttribs (since 1.5.1) extra attributes (OPTIONAL; default empty) |
| 268 | * |
| 269 | * @return string html formated text area field |
| 270 | * |
| 271 | */ |
| 272 | function addTextArea($sName, $sText = '', $iCols = 40, $iRows = 10, $aAttribs = array()) { |
| 273 | |
| 274 | // no longer accept string arguments for attribs; print |
| 275 | // backtrace to help people fix their code |
| 276 | //FIXME: throw error instead? |
| 277 | if (!is_array($aAttribs)) { |
| 278 | echo '$aAttribs argument to addTextArea() must be an array<br /><pre>'; |
| 279 | debug_print_backtrace(); |
| 280 | echo '</pre><br />'; |
| 281 | exit; |
| 282 | } |
| 283 | |
| 284 | // add default css |
| 285 | else if (!isset($aAttribs['class'])) $aAttribs['class'] = 'sqmtextarea'; |
| 286 | |
| 287 | global $oTemplate; |
| 288 | |
| 289 | //FIXME: all the values in the $aAttribs list as well as $sName and $sText used to go thru htmlspecialchars()... 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] = htmlspecialchars($value); $sName = htmlspecialchars($sName); $sText = htmlspecialchars($sText); |
| 290 | $oTemplate->assign('aAttribs', $aAttribs); |
| 291 | $oTemplate->assign('name', $sName); |
| 292 | $oTemplate->assign('text', $sText); |
| 293 | $oTemplate->assign('cols', (int)$iCols); |
| 294 | $oTemplate->assign('rows', (int)$iRows); |
| 295 | |
| 296 | return $oTemplate->fetch('textarea.tpl'); |
| 297 | } |
| 298 | |
| 299 | /** |
| 300 | * Make a <form> start-tag. |
| 301 | * |
| 302 | * @param string $sAction form handler URL |
| 303 | * @param string $sMethod http method used to submit form data. 'get' or 'post' |
| 304 | * @param string $sName form name used for identification (used for backward |
| 305 | * compatibility). Use of id is recommended instead. |
| 306 | * @param string $sEnctype content type that is used to submit data. html 4.01 |
| 307 | * defaults to 'application/x-www-form-urlencoded'. Form |
| 308 | * with file field needs 'multipart/form-data' encoding type. |
| 309 | * @param string $sCharset charset that is used for submitted data |
| 310 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 311 | * |
| 312 | * @return string html formated form start string |
| 313 | * |
| 314 | */ |
| 315 | function addForm($sAction, $sMethod = 'post', $sName = '', $sEnctype = '', $sCharset = '', $aAttribs = array()) { |
| 316 | |
| 317 | global $oTemplate; |
| 318 | |
| 319 | //FIXME: all the values in the $aAttribs list as well as $charset used to go thru htmlspecialchars()... 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] = htmlspecialchars($value); $sCharset = htmlspecialchars($sCharset); |
| 320 | $oTemplate->assign('aAttribs', $aAttribs); |
| 321 | $oTemplate->assign('name', $sName); |
| 322 | $oTemplate->assign('method', $sMethod); |
| 323 | $oTemplate->assign('action', $sAction); |
| 324 | $oTemplate->assign('enctype', $sEnctype); |
| 325 | $oTemplate->assign('charset', $sCharset); |
| 326 | |
| 327 | return $oTemplate->fetch('form.tpl'); |
| 328 | } |
| 329 | |