Form.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. <?php
  2. /**
  3. * Form helper class. Unless otherwise noted, all generated HTML will be made
  4. * safe using the [HTML::chars] method. This prevents against simple XSS
  5. * attacks that could otherwise be triggered by inserting HTML characters into
  6. * form fields.
  7. *
  8. * @package Kohana
  9. * @category Helpers
  10. * @author Kohana Team
  11. * @copyright (c) Kohana Team
  12. * @license https://koseven.ga/LICENSE.md
  13. */
  14. class Kohana_Form {
  15. /**
  16. * Generates an opening HTML form tag.
  17. *
  18. * // Form will submit back to the current page using POST
  19. * echo Form::open();
  20. *
  21. * // Form will submit to 'search' using GET
  22. * echo Form::open('search', array('method' => 'get'));
  23. *
  24. * // When "file" inputs are present, you must include the "enctype"
  25. * echo Form::open(NULL, array('enctype' => 'multipart/form-data'));
  26. *
  27. * @param mixed $action form action, defaults to the current request URI, or [Request] class to use
  28. * @param array $attributes html attributes
  29. * @return string
  30. * @uses Request
  31. * @uses URL::site
  32. * @uses HTML::attributes
  33. */
  34. public static function open($action = NULL, array $attributes = NULL)
  35. {
  36. if ($action instanceof Request)
  37. {
  38. // Use the current URI
  39. $action = $action->uri();
  40. }
  41. if ( ! $action)
  42. {
  43. // Allow empty form actions (submits back to the current url).
  44. $action = '';
  45. }
  46. elseif (strpos($action, '://') === FALSE AND strncmp($action, '//', 2))
  47. {
  48. // Make the URI absolute
  49. $action = URL::site($action);
  50. }
  51. // Add the form action to the attributes
  52. $attributes['action'] = $action;
  53. // Only accept the default character set
  54. $attributes['accept-charset'] = Kohana::$charset;
  55. if ( ! isset($attributes['method']))
  56. {
  57. // Use POST method
  58. $attributes['method'] = 'post';
  59. }
  60. return '<form'.HTML::attributes($attributes).'>';
  61. }
  62. /**
  63. * Creates the closing form tag.
  64. *
  65. * echo Form::close();
  66. *
  67. * @return string
  68. */
  69. public static function close()
  70. {
  71. return '</form>';
  72. }
  73. /**
  74. * Creates a form input. If no type is specified, a "text" type input will
  75. * be returned.
  76. *
  77. * echo Form::input('username', $username);
  78. *
  79. * @param string $name input name
  80. * @param string $value input value
  81. * @param array $attributes html attributes
  82. * @return string
  83. * @uses HTML::attributes
  84. */
  85. public static function input($name, $value = NULL, array $attributes = NULL)
  86. {
  87. // Set the input name
  88. $attributes['name'] = $name;
  89. // Set the input value
  90. $attributes['value'] = $value;
  91. if ( ! isset($attributes['type']))
  92. {
  93. // Default type is text
  94. $attributes['type'] = 'text';
  95. }
  96. return '<input'.HTML::attributes($attributes).' />';
  97. }
  98. /**
  99. * Creates a hidden form input.
  100. *
  101. * echo Form::hidden('csrf', $token);
  102. *
  103. * @param string $name input name
  104. * @param string $value input value
  105. * @param array $attributes html attributes
  106. * @return string
  107. * @uses Form::input
  108. */
  109. public static function hidden($name, $value = NULL, array $attributes = NULL)
  110. {
  111. $attributes['type'] = 'hidden';
  112. return Form::input($name, $value, $attributes);
  113. }
  114. /**
  115. * Creates a password form input.
  116. *
  117. * echo Form::password('password');
  118. *
  119. * @param string $name input name
  120. * @param string $value input value
  121. * @param array $attributes html attributes
  122. * @return string
  123. * @uses Form::input
  124. */
  125. public static function password($name, $value = NULL, array $attributes = NULL)
  126. {
  127. $attributes['type'] = 'password';
  128. return Form::input($name, $value, $attributes);
  129. }
  130. /**
  131. * Creates a file upload form input. No input value can be specified.
  132. *
  133. * echo Form::file('image');
  134. *
  135. * @param string $name input name
  136. * @param array $attributes html attributes
  137. * @return string
  138. * @uses Form::input
  139. */
  140. public static function file($name, array $attributes = NULL)
  141. {
  142. $attributes['type'] = 'file';
  143. return Form::input($name, NULL, $attributes);
  144. }
  145. /**
  146. * Creates a checkbox form input.
  147. *
  148. * echo Form::checkbox('remember_me', 1, (bool) $remember);
  149. *
  150. * @param string $name input name
  151. * @param string $value input value
  152. * @param boolean $checked checked status
  153. * @param array $attributes html attributes
  154. * @return string
  155. * @uses Form::input
  156. */
  157. public static function checkbox($name, $value = NULL, $checked = FALSE, array $attributes = NULL)
  158. {
  159. $attributes['type'] = 'checkbox';
  160. if ($checked === TRUE)
  161. {
  162. // Make the checkbox active
  163. $attributes[] = 'checked';
  164. }
  165. return Form::input($name, $value, $attributes);
  166. }
  167. /**
  168. * Creates a radio form input.
  169. *
  170. * echo Form::radio('like_cats', 1, $cats);
  171. * echo Form::radio('like_cats', 0, ! $cats);
  172. *
  173. * @param string $name input name
  174. * @param string $value input value
  175. * @param boolean $checked checked status
  176. * @param array $attributes html attributes
  177. * @return string
  178. * @uses Form::input
  179. */
  180. public static function radio($name, $value = NULL, $checked = FALSE, array $attributes = NULL)
  181. {
  182. $attributes['type'] = 'radio';
  183. if ($checked === TRUE)
  184. {
  185. // Make the radio active
  186. $attributes[] = 'checked';
  187. }
  188. return Form::input($name, $value, $attributes);
  189. }
  190. /**
  191. * Creates a textarea form input.
  192. *
  193. * echo Form::textarea('about', $about);
  194. *
  195. * @param string $name textarea name
  196. * @param string $body textarea body
  197. * @param array $attributes html attributes
  198. * @param boolean $double_encode encode existing HTML characters
  199. * @return string
  200. * @uses HTML::attributes
  201. * @uses HTML::chars
  202. */
  203. public static function textarea($name, $body = '', array $attributes = NULL, $double_encode = TRUE)
  204. {
  205. // Set the input name
  206. $attributes['name'] = $name;
  207. // Add default rows and cols attributes (required)
  208. $attributes += ['rows' => 10, 'cols' => 50];
  209. return '<textarea'.HTML::attributes($attributes).'>'.HTML::chars($body, $double_encode).'</textarea>';
  210. }
  211. /**
  212. * Creates a select form input.
  213. *
  214. * echo Form::select('country', $countries, $country);
  215. *
  216. * [!!] Support for multiple selected options was added in v3.0.7.
  217. *
  218. * @param string $name input name
  219. * @param array $options available options
  220. * @param mixed $selected selected option string, or an array of selected options
  221. * @param array $attributes html attributes
  222. * @return string
  223. * @uses HTML::attributes
  224. */
  225. public static function select($name, array $options = NULL, $selected = NULL, array $attributes = NULL)
  226. {
  227. // Set the input name
  228. $attributes['name'] = $name;
  229. if (is_array($selected))
  230. {
  231. // This is a multi-select, god save us!
  232. $attributes[] = 'multiple';
  233. }
  234. if ( ! is_array($selected))
  235. {
  236. if ($selected === NULL)
  237. {
  238. // Use an empty array
  239. $selected = [];
  240. }
  241. else
  242. {
  243. // Convert the selected options to an array
  244. $selected = [ (string) $selected];
  245. }
  246. }
  247. if (empty($options))
  248. {
  249. // There are no options
  250. $options = '';
  251. }
  252. else
  253. {
  254. foreach ($options as $value => $name)
  255. {
  256. if (is_array($name))
  257. {
  258. // Create a new optgroup
  259. $group = ['label' => $value];
  260. // Create a new list of options
  261. $_options = [];
  262. foreach ($name as $_value => $_name)
  263. {
  264. // Force value to be string
  265. $_value = (string) $_value;
  266. // Create a new attribute set for this option
  267. $option = ['value' => $_value];
  268. if (in_array($_value, $selected))
  269. {
  270. // This option is selected
  271. $option[] = 'selected';
  272. }
  273. // Change the option to the HTML string
  274. $_options[] = '<option'.HTML::attributes($option).'>'.HTML::chars($_name, FALSE).'</option>';
  275. }
  276. // Compile the options into a string
  277. $_options = "\n".implode("\n", $_options)."\n";
  278. $options[$value] = '<optgroup'.HTML::attributes($group).'>'.$_options.'</optgroup>';
  279. }
  280. else
  281. {
  282. // Force value to be string
  283. $value = (string) $value;
  284. // Create a new attribute set for this option
  285. $option = ['value' => $value];
  286. if (in_array($value, $selected))
  287. {
  288. // This option is selected
  289. $option[] = 'selected';
  290. }
  291. // Change the option to the HTML string
  292. $options[$value] = '<option'.HTML::attributes($option).'>'.HTML::chars($name, FALSE).'</option>';
  293. }
  294. }
  295. // Compile the options into a single string
  296. $options = "\n".implode("\n", $options)."\n";
  297. }
  298. return '<select'.HTML::attributes($attributes).'>'.$options.'</select>';
  299. }
  300. /**
  301. * Creates a submit form input.
  302. *
  303. * echo Form::submit(NULL, 'Login');
  304. *
  305. * @param string $name input name
  306. * @param string $value input value
  307. * @param array $attributes html attributes
  308. * @return string
  309. * @uses Form::input
  310. */
  311. public static function submit($name, $value, array $attributes = NULL)
  312. {
  313. $attributes['type'] = 'submit';
  314. return Form::input($name, $value, $attributes);
  315. }
  316. /**
  317. * Creates a image form input.
  318. *
  319. * echo Form::image(NULL, NULL, array('src' => 'media/img/login.png'));
  320. *
  321. * @param string $name input name
  322. * @param string $value input value
  323. * @param array $attributes html attributes
  324. * @param boolean $index add index file to URL?
  325. * @return string
  326. * @uses Form::input
  327. */
  328. public static function image($name, $value, array $attributes = NULL, $index = FALSE)
  329. {
  330. if ( ! empty($attributes['src']))
  331. {
  332. if (strpos($attributes['src'], '://') === FALSE AND strncmp($attributes['src'], '//', 2))
  333. {
  334. // Add the base URL
  335. $attributes['src'] = URL::base($index).$attributes['src'];
  336. }
  337. }
  338. $attributes['type'] = 'image';
  339. return Form::input($name, $value, $attributes);
  340. }
  341. /**
  342. * Creates a button form input. Note that the body of a button is NOT escaped,
  343. * to allow images and other HTML to be used.
  344. *
  345. * echo Form::button('save', 'Save Profile', array('type' => 'submit'));
  346. *
  347. * @param string $name input name
  348. * @param string $body input value
  349. * @param array $attributes html attributes
  350. * @return string
  351. * @uses HTML::attributes
  352. */
  353. public static function button($name, $body, array $attributes = NULL)
  354. {
  355. // Set the input name
  356. $attributes['name'] = $name;
  357. return '<button'.HTML::attributes($attributes).'>'.$body.'</button>';
  358. }
  359. /**
  360. * Creates a form label. Label text is not automatically translated.
  361. *
  362. * echo Form::label('username', 'Username');
  363. *
  364. * @param string $input target input
  365. * @param string $text label text
  366. * @param array $attributes html attributes
  367. * @return string
  368. * @uses HTML::attributes
  369. */
  370. public static function label($input, $text = NULL, array $attributes = NULL)
  371. {
  372. if ($text === NULL)
  373. {
  374. // Use the input name as the text
  375. $text = ucwords(preg_replace('/[\W_]+/', ' ', $input));
  376. }
  377. // Set the label target
  378. $attributes['for'] = $input;
  379. return '<label'.HTML::attributes($attributes).'>'.$text.'</label>';
  380. }
  381. }