| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * forms.php - html form functions |
| 5 | * |
| 6 | * Functions to build HTML forms in a safe and consistent manner. |
| 7 | * All attribute values are sanitized with htmlspecialchars(). |
| 8 | * |
| 9 | * Currently functions don't provide simple wrappers for file and |
| 10 | * image input fields, support only submit and reset buttons and use |
| 11 | * html input tags for buttons. |
| 12 | * |
| 13 | * Since 1.5.1: |
| 14 | * |
| 15 | * * all form functions should support id tags. Original |
| 16 | * idea by dugan <at> passwall.com. Tags can be used for Section 508 |
| 17 | * or WAI compliance. |
| 18 | * |
| 19 | * * input tag functions accept extra html attributes that can be submitted |
| 20 | * in $aAttribs array. |
| 21 | * |
| 22 | * * default css class attributes are added. |
| 23 | * |
| 24 | * @link http://www.section508.gov/ Section 508 |
| 25 | * @link http://www.w3.org/WAI/ Web Accessibility Initiative (WAI) |
| 26 | * @link http://www.w3.org/TR/html4/ W3.org HTML 4.01 form specs |
| 27 | * @copyright © 2004-2006 The SquirrelMail Project Team |
| 28 | * @license http://opensource.org/licenses/gpl-license.php GNU Public License |
| 29 | * @version $Id$ |
| 30 | * @package squirrelmail |
| 31 | * @subpackage forms |
| 32 | * @since 1.4.3 and 1.5.1 |
| 33 | */ |
| 34 | |
| 35 | /** |
| 36 | * Helper function to create form fields, not to be called directly, |
| 37 | * only by other functions below. |
| 38 | * |
| 39 | * Function used different syntax before 1.5.1 |
| 40 | * @param string $sType type of input field. Possible values (html 4.01 |
| 41 | * specs.): text, password, checkbox, radio, submit, reset, file, |
| 42 | * hidden, image, button. |
| 43 | * @param array $aAttribs (since 1.5.1) extra attributes. Array key is |
| 44 | * attribute name, array value is attribute value. Array keys must use |
| 45 | * lowercase. |
| 46 | * @return string html formated input field |
| 47 | * @deprecated use other functions that provide simple wrappers to this function |
| 48 | */ |
| 49 | function addInputField($sType, $aAttribs=array()) { |
| 50 | $sAttribs = ''; |
| 51 | // define unique identifier |
| 52 | if (! isset($aAttribs['id']) && isset($aAttribs['name']) && ! is_null($aAttribs['name'])) { |
| 53 | /** |
| 54 | * if 'id' is not set, set it to 'name' and replace brackets |
| 55 | * with underscores. 'name' might contain field name with squire |
| 56 | * brackets (array). Brackets are not allowed in id (validator.w3.org |
| 57 | * fails to validate document). According to html 4.01 manual cdata |
| 58 | * type description, 'name' attribute uses same type, but validator.w3.org |
| 59 | * does not barf on brackets in 'name' attributes. |
| 60 | */ |
| 61 | $aAttribs['id'] = strtr($aAttribs['name'],'[]','__'); |
| 62 | } |
| 63 | // create attribute string (do we have to sanitize keys?) |
| 64 | foreach ($aAttribs as $key => $value) { |
| 65 | $sAttribs.= ' ' . $key . (! is_null($value) ? '="'.htmlspecialchars($value).'"':''); |
| 66 | } |
| 67 | return '<input type="'.$sType.'"'.$sAttribs." />\n"; |
| 68 | } |
| 69 | |
| 70 | /** |
| 71 | * Password input field |
| 72 | * @param string $sName field name |
| 73 | * @param string $sValue initial password value |
| 74 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 75 | * @return string html formated password field |
| 76 | */ |
| 77 | function addPwField($sName, $sValue = null, $aAttribs=array()) { |
| 78 | $aAttribs['name'] = $sName; |
| 79 | $aAttribs['value'] = (! is_null($sValue) ? $sValue : ''); |
| 80 | // add default css |
| 81 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmpwfield'; |
| 82 | return addInputField('password',$aAttribs); |
| 83 | } |
| 84 | |
| 85 | /** |
| 86 | * Form checkbox |
| 87 | * @param string $sName field name |
| 88 | * @param boolean $bChecked controls if field is checked |
| 89 | * @param string $sValue |
| 90 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 91 | * @return string html formated checkbox field |
| 92 | */ |
| 93 | function addCheckBox($sName, $bChecked = false, $sValue = null, $aAttribs=array()) { |
| 94 | $aAttribs['name'] = $sName; |
| 95 | if ($bChecked) $aAttribs['checked'] = 'checked'; |
| 96 | if (! is_null($sValue)) $aAttribs['value'] = $sValue; |
| 97 | // add default css |
| 98 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmcheckbox'; |
| 99 | return addInputField('checkbox',$aAttribs); |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * Form radio box |
| 104 | * @param string $sName field name |
| 105 | * @param boolean $bChecked controls if field is selected |
| 106 | * @param string $sValue |
| 107 | * @param array $aAttribs (since 1.5.1) extra attributes. |
| 108 | * @return string html formated radio box |
| 109 | */ |
| 110 | function addRadioBox($sName, $bChecked = false, $sValue = null, $aAttribs=array()) { |
| 111 | $aAttribs['name'] = $sName; |
| 112 | if ($bChecked) $aAttribs['checked'] = 'checked'; |
| 113 | if (! is_null($sValue)) $aAttribs['value'] = $sValue; |
| 114 | if (! isset($aAttribs['id'])) $aAttribs['id'] = $sName . $sValue; |
| 115 | // add default css |
| 116 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmradiobox'; |
| 117 | return addInputField('radio', $aAttribs); |
| 118 | } |
| 119 | |
| 120 | /** |
| 121 | * A hidden form field. |
| 122 | * @param string $sName field name |
| 123 | * @param string $sValue field value |
| 124 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 125 | * @return html formated hidden form field |
| 126 | */ |
| 127 | function addHidden($sName, $sValue, $aAttribs=array()) { |
| 128 | $aAttribs['name'] = $sName; |
| 129 | $aAttribs['value'] = $sValue; |
| 130 | // add default css |
| 131 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmhiddenfield'; |
| 132 | return addInputField('hidden', $aAttribs); |
| 133 | } |
| 134 | |
| 135 | /** |
| 136 | * An input textbox. |
| 137 | * @param string $sName field name |
| 138 | * @param string $sValue initial field value |
| 139 | * @param integer $iSize field size (number of characters) |
| 140 | * @param integer $iMaxlength maximum number of characters the user may enter |
| 141 | * @param array $aAttribs (since 1.5.1) extra attributes - should be given |
| 142 | * in the form array('attribute_name' => 'attribute_value', ...) |
| 143 | * @return string html formated text input field |
| 144 | */ |
| 145 | function addInput($sName, $sValue = '', $iSize = 0, $iMaxlength = 0, $aAttribs=array()) { |
| 146 | $aAttribs['name'] = $sName; |
| 147 | $aAttribs['value'] = $sValue; |
| 148 | if ($iSize) $aAttribs['size'] = (int)$iSize; |
| 149 | if ($iMaxlength) $aAttribs['maxlength'] = (int)$iMaxlength; |
| 150 | // add default css |
| 151 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmtextfield'; |
| 152 | return addInputField('text', $aAttribs); |
| 153 | } |
| 154 | |
| 155 | /** |
| 156 | * Function to create a selectlist from an array. |
| 157 | * @param string $sName field name |
| 158 | * @param array $aValues field values array ( key => value ) -> <option value="key">value</option> |
| 159 | * @param mixed $default the key that will be selected |
| 160 | * @param boolean $bUsekeys use the keys of the array as option value or not |
| 161 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 162 | * @return string html formated selection box |
| 163 | * @todo add attributes argument for option tags and default css |
| 164 | */ |
| 165 | function addSelect($sName, $aValues, $default = null, $bUsekeys = false, $aAttribs = array()) { |
| 166 | // only one element |
| 167 | if(count($aValues) == 1) { |
| 168 | $k = key($aValues); $v = array_pop($aValues); |
| 169 | return addHidden($sName, ($bUsekeys ? $k:$v), $aAttribs). |
| 170 | htmlspecialchars($v) . "\n"; |
| 171 | } |
| 172 | |
| 173 | if (isset($aAttribs['id'])) { |
| 174 | $label_open = '<label for="'.htmlspecialchars($aAttribs['id']).'">'; |
| 175 | $label_close = '</label>'; |
| 176 | } else { |
| 177 | $label_open = ''; |
| 178 | $label_close = ''; |
| 179 | } |
| 180 | |
| 181 | // create attribute string for select tag |
| 182 | $sAttribs = ''; |
| 183 | foreach ($aAttribs as $key => $value) { |
| 184 | $sAttribs.= ' ' . $key . (! is_null($value) ? '="'.htmlspecialchars($value).'"':''); |
| 185 | } |
| 186 | |
| 187 | $ret = '<select name="'.htmlspecialchars($sName) . '"' . $sAttribs . ">\n"; |
| 188 | foreach ($aValues as $k => $v) { |
| 189 | if(!$bUsekeys) $k = $v; |
| 190 | $ret .= '<option value="' . |
| 191 | htmlspecialchars( $k ) . '"' . |
| 192 | (($default == $k) ? ' selected="selected"' : '') . |
| 193 | '>' . $label_open . htmlspecialchars($v) . $label_close ."</option>\n"; |
| 194 | } |
| 195 | $ret .= "</select>\n"; |
| 196 | |
| 197 | return $ret; |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * Form submission button |
| 202 | * Note the switched value/name parameters! |
| 203 | * @param string $sValue button name |
| 204 | * @param string $sName submitted key name |
| 205 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 206 | * @return string html formated submit input field |
| 207 | */ |
| 208 | function addSubmit($sValue, $sName = null, $aAttribs=array()) { |
| 209 | $aAttribs['value'] = $sValue; |
| 210 | if (! is_null($sName)) $aAttribs['name'] = $sName; |
| 211 | // add default css |
| 212 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmsubmitfield'; |
| 213 | return addInputField('submit', $aAttribs); |
| 214 | } |
| 215 | /** |
| 216 | * Form reset button |
| 217 | * @param string $sValue button name |
| 218 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 219 | * @return string html formated reset input field |
| 220 | */ |
| 221 | function addReset($sValue, $aAttribs=array()) { |
| 222 | $aAttribs['value'] = $sValue; |
| 223 | // add default css |
| 224 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmresetfield'; |
| 225 | return addInputField('reset', $aAttribs); |
| 226 | } |
| 227 | |
| 228 | /** |
| 229 | * Textarea form element. |
| 230 | * @param string $sName field name |
| 231 | * @param string $sText initial field value |
| 232 | * @param integer $iCols field width (number of chars) |
| 233 | * @param integer $iRows field height (number of character rows) |
| 234 | * @param array $aAttribs (since 1.5.1) extra attributes. function accepts string argument |
| 235 | * for backward compatibility. |
| 236 | * @return string html formated text area field |
| 237 | */ |
| 238 | function addTextArea($sName, $sText = '', $iCols = 40, $iRows = 10, $aAttribs = array()) { |
| 239 | $label_open = ''; |
| 240 | $label_close = ''; |
| 241 | if (is_array($aAttribs)) { |
| 242 | // maybe id can default to name? |
| 243 | if (isset($aAttribs['id'])) { |
| 244 | $label_open = '<label for="'.htmlspecialchars($aAttribs['id']).'">'; |
| 245 | $label_close = '</label>'; |
| 246 | } |
| 247 | // add default css |
| 248 | if (! isset($aAttribs['class'])) $aAttribs['class'] = 'sqmtextarea'; |
| 249 | // create attribute string (do we have to sanitize keys?) |
| 250 | $sAttribs = ''; |
| 251 | foreach ($aAttribs as $key => $value) { |
| 252 | $sAttribs.= ' ' . $key . (! is_null($value) ? '="'.htmlspecialchars($value).'"':''); |
| 253 | } |
| 254 | } elseif (is_string($aAttribs)) { |
| 255 | // backward compatibility mode. deprecated. |
| 256 | $sAttribs = ' ' . $aAttribs; |
| 257 | } else { |
| 258 | $sAttribs = ''; |
| 259 | } |
| 260 | return '<textarea name="'.htmlspecialchars($sName).'" '. |
| 261 | 'rows="'.(int)$iRows .'" cols="'.(int)$iCols.'"'. |
| 262 | $sAttribs . '>'. $label_open . htmlspecialchars($sText) . $label_close ."</textarea>\n"; |
| 263 | } |
| 264 | |
| 265 | /** |
| 266 | * Make a <form> start-tag. |
| 267 | * @param string $sAction form handler URL |
| 268 | * @param string $sMethod http method used to submit form data. 'get' or 'post' |
| 269 | * @param string $sName form name used for identification (used for backward |
| 270 | * compatibility). Use of id is recommended. |
| 271 | * @param string $sEnctype content type that is used to submit data. html 4.01 |
| 272 | * defaults to 'application/x-www-form-urlencoded'. Form with file field needs |
| 273 | * 'multipart/form-data' encoding type. |
| 274 | * @param string $sCharset charset that is used for submitted data |
| 275 | * @param array $aAttribs (since 1.5.1) extra attributes |
| 276 | * @return string html formated form start string |
| 277 | */ |
| 278 | function addForm($sAction, $sMethod = 'post', $sName = '', $sEnctype = '', $sCharset = '', $aAttribs = array()) { |
| 279 | // id tags |
| 280 | if (! isset($aAttribs['id']) && ! empty($sName)) |
| 281 | $aAttribs['id'] = $sName; |
| 282 | |
| 283 | if($sName) { |
| 284 | $sName = ' name="'.$sName.'"'; |
| 285 | } |
| 286 | if($sEnctype) { |
| 287 | $sEnctype = ' enctype="'.$sEnctype.'"'; |
| 288 | } |
| 289 | if($sCharset) { |
| 290 | $sCharset = ' accept-charset="'.htmlspecialchars($sCharset).'"'; |
| 291 | } |
| 292 | |
| 293 | // create attribute string (do we have to sanitize keys?) |
| 294 | $sAttribs = ''; |
| 295 | foreach ($aAttribs as $key => $value) { |
| 296 | $sAttribs.= ' ' . $key . (! is_null($value) ? '="'.htmlspecialchars($value).'"':''); |
| 297 | } |
| 298 | |
| 299 | return '<form action="'. $sAction .'" method="'. $sMethod .'"'. |
| 300 | $sEnctype . $sName . $sCharset . $sAttribs . ">\n"; |
| 301 | } |