You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1148 lines
36 KiB

  1. <?php
  2. /**
  3. * DokuWiki XHTML Form
  4. *
  5. * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6. * @author Tom N Harris <tnharris@whoopdedo.org>
  7. */
  8. // phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
  9. // phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
  10. /**
  11. * Class for creating simple HTML forms.
  12. *
  13. * The forms is built from a list of pseudo-tags (arrays with expected keys).
  14. * Every pseudo-tag must have the key '_elem' set to the name of the element.
  15. * When printed, the form class calls functions named 'form_$type' for each
  16. * element it contains.
  17. *
  18. * Standard practice is for non-attribute keys in a pseudo-element to start
  19. * with '_'. Other keys are HTML attributes that will be included in the element
  20. * tag. That way, the element output functions can pass the pseudo-element
  21. * directly to buildAttributes.
  22. *
  23. * See the form_make* functions later in this file.
  24. *
  25. * Please note that even though this class is technically deprecated (use dokuwiki\Form instead),
  26. * it is still widely used in the core and the related form events. Until those have been rewritten,
  27. * this will continue to be used
  28. *
  29. * @deprecated 2019-07-14
  30. * @author Tom N Harris <tnharris@whoopdedo.org>
  31. */
  32. class Doku_Form
  33. {
  34. // Form id attribute
  35. public $params = array();
  36. // Draw a border around form fields.
  37. // Adds <fieldset></fieldset> around the elements
  38. public $_infieldset = false;
  39. // Hidden form fields.
  40. public $_hidden = array();
  41. // Array of pseudo-tags
  42. public $_content = array();
  43. /**
  44. * Constructor
  45. *
  46. * Sets parameters and autoadds a security token. The old calling convention
  47. * with up to four parameters is deprecated, instead the first parameter
  48. * should be an array with parameters.
  49. *
  50. * @param mixed $params Parameters for the HTML form element; Using the deprecated
  51. * calling convention this is the ID attribute of the form
  52. * @param bool|string $action (optional, deprecated) submit URL, defaults to current page
  53. * @param bool|string $method (optional, deprecated) 'POST' or 'GET', default is POST
  54. * @param bool|string $enctype (optional, deprecated) Encoding type of the data
  55. *
  56. * @author Tom N Harris <tnharris@whoopdedo.org>
  57. */
  58. public function __construct($params, $action = false, $method = false, $enctype = false)
  59. {
  60. if (!is_array($params)) {
  61. $this->params = array('id' => $params);
  62. if ($action !== false) $this->params['action'] = $action;
  63. if ($method !== false) $this->params['method'] = strtolower($method);
  64. if ($enctype !== false) $this->params['enctype'] = $enctype;
  65. } else {
  66. $this->params = $params;
  67. }
  68. if (!isset($this->params['method'])) {
  69. $this->params['method'] = 'post';
  70. } else {
  71. $this->params['method'] = strtolower($this->params['method']);
  72. }
  73. if (!isset($this->params['action'])) {
  74. $this->params['action'] = '';
  75. }
  76. $this->addHidden('sectok', getSecurityToken());
  77. }
  78. /**
  79. * startFieldset
  80. *
  81. * Add <fieldset></fieldset> tags around fields.
  82. * Usually results in a border drawn around the form.
  83. *
  84. * @param string $legend Label that will be printed with the border.
  85. *
  86. * @author Tom N Harris <tnharris@whoopdedo.org>
  87. */
  88. public function startFieldset($legend)
  89. {
  90. if ($this->_infieldset) {
  91. $this->addElement(array('_elem' => 'closefieldset'));
  92. }
  93. $this->addElement(array('_elem' => 'openfieldset', '_legend' => $legend));
  94. $this->_infieldset = true;
  95. }
  96. /**
  97. * endFieldset
  98. *
  99. * @author Tom N Harris <tnharris@whoopdedo.org>
  100. */
  101. public function endFieldset()
  102. {
  103. if ($this->_infieldset) {
  104. $this->addElement(array('_elem' => 'closefieldset'));
  105. }
  106. $this->_infieldset = false;
  107. }
  108. /**
  109. * addHidden
  110. *
  111. * Adds a name/value pair as a hidden field.
  112. * The value of the field (but not the name) will be passed to
  113. * formText() before printing.
  114. *
  115. * @param string $name Field name.
  116. * @param string $value Field value. If null, remove a previously added field.
  117. *
  118. * @author Tom N Harris <tnharris@whoopdedo.org>
  119. */
  120. public function addHidden($name, $value)
  121. {
  122. if (is_null($value))
  123. unset($this->_hidden[$name]);
  124. else $this->_hidden[$name] = $value;
  125. }
  126. /**
  127. * addElement
  128. *
  129. * Appends a content element to the form.
  130. * The element can be either a pseudo-tag or string.
  131. * If string, it is printed without escaping special chars. *
  132. *
  133. * @param string|array $elem Pseudo-tag or string to add to the form.
  134. *
  135. * @author Tom N Harris <tnharris@whoopdedo.org>
  136. */
  137. public function addElement($elem)
  138. {
  139. $this->_content[] = $elem;
  140. }
  141. /**
  142. * insertElement
  143. *
  144. * Inserts a content element at a position.
  145. *
  146. * @param string $pos 0-based index where the element will be inserted.
  147. * @param string|array $elem Pseudo-tag or string to add to the form.
  148. *
  149. * @author Tom N Harris <tnharris@whoopdedo.org>
  150. */
  151. public function insertElement($pos, $elem)
  152. {
  153. array_splice($this->_content, $pos, 0, array($elem));
  154. }
  155. /**
  156. * replaceElement
  157. *
  158. * Replace with NULL to remove an element.
  159. *
  160. * @param int $pos 0-based index the element will be placed at.
  161. * @param string|array $elem Pseudo-tag or string to add to the form.
  162. *
  163. * @author Tom N Harris <tnharris@whoopdedo.org>
  164. */
  165. public function replaceElement($pos, $elem)
  166. {
  167. $rep = array();
  168. if (!is_null($elem)) $rep[] = $elem;
  169. array_splice($this->_content, $pos, 1, $rep);
  170. }
  171. /**
  172. * findElementByType
  173. *
  174. * Gets the position of the first of a type of element.
  175. *
  176. * @param string $type Element type to look for.
  177. * @return int|false position of element if found, otherwise false
  178. *
  179. * @author Tom N Harris <tnharris@whoopdedo.org>
  180. */
  181. public function findElementByType($type)
  182. {
  183. foreach ($this->_content as $pos => $elem) {
  184. if (is_array($elem) && $elem['_elem'] == $type)
  185. return $pos;
  186. }
  187. return false;
  188. }
  189. /**
  190. * findElementById
  191. *
  192. * Gets the position of the element with an ID attribute.
  193. *
  194. * @param string $id ID of the element to find.
  195. * @return int|false position of element if found, otherwise false
  196. *
  197. * @author Tom N Harris <tnharris@whoopdedo.org>
  198. */
  199. public function findElementById($id)
  200. {
  201. foreach ($this->_content as $pos => $elem) {
  202. if (is_array($elem) && isset($elem['id']) && $elem['id'] == $id)
  203. return $pos;
  204. }
  205. return false;
  206. }
  207. /**
  208. * findElementByAttribute
  209. *
  210. * Gets the position of the first element with a matching attribute value.
  211. *
  212. * @param string $name Attribute name.
  213. * @param string $value Attribute value.
  214. * @return int|false position of element if found, otherwise false
  215. *
  216. * @author Tom N Harris <tnharris@whoopdedo.org>
  217. */
  218. public function findElementByAttribute($name, $value)
  219. {
  220. foreach ($this->_content as $pos => $elem) {
  221. if (is_array($elem) && isset($elem[$name]) && $elem[$name] == $value)
  222. return $pos;
  223. }
  224. return false;
  225. }
  226. /**
  227. * getElementAt
  228. *
  229. * Returns a reference to the element at a position.
  230. * A position out-of-bounds will return either the
  231. * first (underflow) or last (overflow) element.
  232. *
  233. * @param int $pos 0-based index
  234. * @return array reference pseudo-element
  235. *
  236. * @author Tom N Harris <tnharris@whoopdedo.org>
  237. */
  238. public function &getElementAt($pos)
  239. {
  240. if ($pos < 0) $pos = count($this->_content) + $pos;
  241. if ($pos < 0) $pos = 0;
  242. if ($pos >= count($this->_content)) $pos = count($this->_content) - 1;
  243. return $this->_content[$pos];
  244. }
  245. /**
  246. * Return the assembled HTML for the form.
  247. *
  248. * Each element in the form will be passed to a function named
  249. * 'form_$type'. The function should return the HTML to be printed.
  250. *
  251. * @author Tom N Harris <tnharris@whoopdedo.org>
  252. *
  253. * @return string html of the form
  254. */
  255. public function getForm()
  256. {
  257. global $lang;
  258. $form = '';
  259. $this->params['accept-charset'] = $lang['encoding'];
  260. $form .= '<form ' . buildAttributes($this->params, false) . '><div class="no">' . DOKU_LF;
  261. if (!empty($this->_hidden)) {
  262. foreach ($this->_hidden as $name => $value)
  263. $form .= form_hidden(array('name' => $name, 'value' => $value));
  264. }
  265. foreach ($this->_content as $element) {
  266. if (is_array($element)) {
  267. $elem_type = $element['_elem'];
  268. if (function_exists('form_' . $elem_type)) {
  269. $form .= call_user_func('form_' . $elem_type, $element) . DOKU_LF;
  270. }
  271. } else {
  272. $form .= $element;
  273. }
  274. }
  275. if ($this->_infieldset) $form .= form_closefieldset() . DOKU_LF;
  276. $form .= '</div></form>' . DOKU_LF;
  277. return $form;
  278. }
  279. /**
  280. * Print the assembled form
  281. *
  282. * wraps around getForm()
  283. */
  284. public function printForm()
  285. {
  286. echo $this->getForm();
  287. }
  288. /**
  289. * Add a radio set
  290. *
  291. * This function adds a set of radio buttons to the form. If $_POST[$name]
  292. * is set, this radio is preselected, else the first radio button.
  293. *
  294. * @param string $name The HTML field name
  295. * @param array $entries An array of entries $value => $caption
  296. *
  297. * @author Adrian Lang <lang@cosmocode.de>
  298. */
  299. public function addRadioSet($name, $entries)
  300. {
  301. global $INPUT;
  302. $value = (array_key_exists($INPUT->post->str($name), $entries)) ?
  303. $INPUT->str($name) : key($entries);
  304. foreach ($entries as $val => $cap) {
  305. $data = ($value === $val) ? array('checked' => 'checked') : array();
  306. $this->addElement(form_makeRadioField($name, $val, $cap, '', '', $data));
  307. }
  308. }
  309. }
  310. /**
  311. * form_makeTag
  312. *
  313. * Create a form element for a non-specific empty tag.
  314. *
  315. * @param string $tag Tag name.
  316. * @param array $attrs Optional attributes.
  317. * @return array pseudo-tag
  318. *
  319. * @author Tom N Harris <tnharris@whoopdedo.org>
  320. */
  321. function form_makeTag($tag, $attrs = array())
  322. {
  323. $elem = array('_elem' => 'tag', '_tag' => $tag);
  324. return array_merge($elem, $attrs);
  325. }
  326. /**
  327. * form_makeOpenTag
  328. *
  329. * Create a form element for a non-specific opening tag.
  330. * Remember to put a matching close tag after this as well.
  331. *
  332. * @param string $tag Tag name.
  333. * @param array $attrs Optional attributes.
  334. * @return array pseudo-tag
  335. *
  336. * @author Tom N Harris <tnharris@whoopdedo.org>
  337. */
  338. function form_makeOpenTag($tag, $attrs = array())
  339. {
  340. $elem = array('_elem' => 'opentag', '_tag' => $tag);
  341. return array_merge($elem, $attrs);
  342. }
  343. /**
  344. * form_makeCloseTag
  345. *
  346. * Create a form element for a non-specific closing tag.
  347. * Careless use of this will result in invalid XHTML.
  348. *
  349. * @param string $tag Tag name.
  350. * @return array pseudo-tag
  351. *
  352. * @author Tom N Harris <tnharris@whoopdedo.org>
  353. */
  354. function form_makeCloseTag($tag)
  355. {
  356. return array('_elem' => 'closetag', '_tag' => $tag);
  357. }
  358. /**
  359. * form_makeWikiText
  360. *
  361. * Create a form element for a textarea containing wiki text.
  362. * Only one wikitext element is allowed on a page. It will have
  363. * a name of 'wikitext' and id 'wiki__text'. The text will
  364. * be passed to formText() before printing.
  365. *
  366. * @param string $text Text to fill the field with.
  367. * @param array $attrs Optional attributes.
  368. * @return array pseudo-tag
  369. *
  370. * @author Tom N Harris <tnharris@whoopdedo.org>
  371. */
  372. function form_makeWikiText($text, $attrs = array())
  373. {
  374. $elem = array('_elem' => 'wikitext', '_text' => $text,
  375. 'class' => 'edit', 'cols' => '80', 'rows' => '10');
  376. return array_merge($elem, $attrs);
  377. }
  378. /**
  379. * form_makeButton
  380. *
  381. * Create a form element for an action button.
  382. * A title will automatically be generated using the value and
  383. * accesskey attributes, unless you provide one.
  384. *
  385. * @param string $type Type attribute. 'submit' or 'cancel'
  386. * @param string $act Wiki action of the button, will be used as the do= parameter
  387. * @param string $value (optional) Displayed label. Uses $act if not provided.
  388. * @param array $attrs Optional attributes.
  389. * @return array pseudo-tag
  390. *
  391. * @author Tom N Harris <tnharris@whoopdedo.org>
  392. */
  393. function form_makeButton($type, $act, $value = '', $attrs = array())
  394. {
  395. if ($value == '') $value = $act;
  396. $elem = array('_elem' => 'button', 'type' => $type, '_action' => $act,
  397. 'value' => $value);
  398. if (!empty($attrs['accesskey']) && empty($attrs['title'])) {
  399. $attrs['title'] = $value . ' [' . strtoupper($attrs['accesskey']) . ']';
  400. }
  401. return array_merge($elem, $attrs);
  402. }
  403. /**
  404. * form_makeField
  405. *
  406. * Create a form element for a labelled input element.
  407. * The label text will be printed before the input.
  408. *
  409. * @param string $type Type attribute of input.
  410. * @param string $name Name attribute of the input.
  411. * @param string $value (optional) Default value.
  412. * @param string $class Class attribute of the label. If this is 'block',
  413. * then a line break will be added after the field.
  414. * @param string $label Label that will be printed before the input.
  415. * @param string $id ID attribute of the input. If set, the label will
  416. * reference it with a 'for' attribute.
  417. * @param array $attrs Optional attributes.
  418. * @return array pseudo-tag
  419. *
  420. * @author Tom N Harris <tnharris@whoopdedo.org>
  421. */
  422. function form_makeField($type, $name, $value = '', $label = null, $id = '', $class = '', $attrs = array())
  423. {
  424. if (is_null($label)) $label = $name;
  425. $elem = array('_elem' => 'field', '_text' => $label, '_class' => $class,
  426. 'type' => $type, 'id' => $id, 'name' => $name, 'value' => $value);
  427. return array_merge($elem, $attrs);
  428. }
  429. /**
  430. * form_makeFieldRight
  431. *
  432. * Create a form element for a labelled input element.
  433. * The label text will be printed after the input.
  434. *
  435. * @see form_makeField
  436. * @author Tom N Harris <tnharris@whoopdedo.org>
  437. *
  438. * @param string $type
  439. * @param string $name
  440. * @param string $value
  441. * @param null|string $label
  442. * @param string $id
  443. * @param string $class
  444. * @param array $attrs
  445. *
  446. * @return array
  447. */
  448. function form_makeFieldRight($type, $name, $value = '', $label = null, $id = '', $class = '', $attrs = array())
  449. {
  450. if (is_null($label)) $label = $name;
  451. $elem = array('_elem' => 'fieldright', '_text' => $label, '_class' => $class,
  452. 'type' => $type, 'id' => $id, 'name' => $name, 'value' => $value);
  453. return array_merge($elem, $attrs);
  454. }
  455. /**
  456. * form_makeTextField
  457. *
  458. * Create a form element for a text input element with label.
  459. *
  460. * @see form_makeField
  461. * @author Tom N Harris <tnharris@whoopdedo.org>
  462. *
  463. * @param string $name
  464. * @param string $value
  465. * @param null|string $label
  466. * @param string $id
  467. * @param string $class
  468. * @param array $attrs
  469. *
  470. * @return array
  471. */
  472. function form_makeTextField($name, $value = '', $label = null, $id = '', $class = '', $attrs = array())
  473. {
  474. if (is_null($label)) $label = $name;
  475. $elem = array('_elem' => 'textfield', '_text' => $label, '_class' => $class,
  476. 'id' => $id, 'name' => $name, 'value' => $value, 'class' => 'edit');
  477. return array_merge($elem, $attrs);
  478. }
  479. /**
  480. * form_makePasswordField
  481. *
  482. * Create a form element for a password input element with label.
  483. * Password elements have no default value, for obvious reasons.
  484. *
  485. * @see form_makeField
  486. * @author Tom N Harris <tnharris@whoopdedo.org>
  487. *
  488. * @param string $name
  489. * @param null|string $label
  490. * @param string $id
  491. * @param string $class
  492. * @param array $attrs
  493. *
  494. * @return array
  495. */
  496. function form_makePasswordField($name, $label = null, $id = '', $class = '', $attrs = array())
  497. {
  498. if (is_null($label)) $label = $name;
  499. $elem = array('_elem' => 'passwordfield', '_text' => $label, '_class' => $class,
  500. 'id' => $id, 'name' => $name, 'class' => 'edit');
  501. return array_merge($elem, $attrs);
  502. }
  503. /**
  504. * form_makeFileField
  505. *
  506. * Create a form element for a file input element with label
  507. *
  508. * @see form_makeField
  509. * @author Michael Klier <chi@chimeric.de>
  510. *
  511. * @param string $name
  512. * @param null|string $label
  513. * @param string $id
  514. * @param string $class
  515. * @param array $attrs
  516. *
  517. * @return array
  518. */
  519. function form_makeFileField($name, $label = null, $id = '', $class = '', $attrs = array())
  520. {
  521. if (is_null($label)) $label = $name;
  522. $elem = array('_elem' => 'filefield', '_text' => $label, '_class' => $class,
  523. 'id' => $id, 'name' => $name, 'class' => 'edit');
  524. return array_merge($elem, $attrs);
  525. }
  526. /**
  527. * form_makeCheckboxField
  528. *
  529. * Create a form element for a checkbox input element with label.
  530. * If $value is an array, a hidden field with the same name and the value
  531. * $value[1] is constructed as well.
  532. *
  533. * @see form_makeFieldRight
  534. * @author Tom N Harris <tnharris@whoopdedo.org>
  535. *
  536. * @param string $name
  537. * @param string $value
  538. * @param null|string $label
  539. * @param string $id
  540. * @param string $class
  541. * @param array $attrs
  542. *
  543. * @return array
  544. */
  545. function form_makeCheckboxField($name, $value = '1', $label = null, $id = '', $class = '', $attrs = array())
  546. {
  547. if (is_null($label)) $label = $name;
  548. if (is_null($value) || $value == '') $value = '0';
  549. $elem = array('_elem' => 'checkboxfield', '_text' => $label, '_class' => $class,
  550. 'id' => $id, 'name' => $name, 'value' => $value);
  551. return array_merge($elem, $attrs);
  552. }
  553. /**
  554. * form_makeRadioField
  555. *
  556. * Create a form element for a radio button input element with label.
  557. *
  558. * @see form_makeFieldRight
  559. * @author Tom N Harris <tnharris@whoopdedo.org>
  560. *
  561. * @param string $name
  562. * @param string $value
  563. * @param null|string $label
  564. * @param string $id
  565. * @param string $class
  566. * @param array $attrs
  567. *
  568. * @return array
  569. */
  570. function form_makeRadioField($name, $value = '1', $label = null, $id = '', $class = '', $attrs = array())
  571. {
  572. if (is_null($label)) $label = $name;
  573. if (is_null($value) || $value == '') $value = '0';
  574. $elem = array('_elem' => 'radiofield', '_text' => $label, '_class' => $class,
  575. 'id' => $id, 'name' => $name, 'value' => $value);
  576. return array_merge($elem, $attrs);
  577. }
  578. /**
  579. * form_makeMenuField
  580. *
  581. * Create a form element for a drop-down menu with label.
  582. * The list of values can be strings, arrays of (value,text),
  583. * or an associative array with the values as keys and labels as values.
  584. * An item is selected by supplying its value or integer index.
  585. * If the list of values is an associative array, the selected item must be
  586. * a string.
  587. *
  588. * @author Tom N Harris <tnharris@whoopdedo.org>
  589. *
  590. * @param string $name Name attribute of the input.
  591. * @param string[]|array[] $values The list of values can be strings, arrays of (value,text),
  592. * or an associative array with the values as keys and labels as values.
  593. * @param string|int $selected default selected value, string or index number
  594. * @param string $class Class attribute of the label. If this is 'block',
  595. * then a line break will be added after the field.
  596. * @param string $label Label that will be printed before the input.
  597. * @param string $id ID attribute of the input. If set, the label will
  598. * reference it with a 'for' attribute.
  599. * @param array $attrs Optional attributes.
  600. * @return array pseudo-tag
  601. */
  602. function form_makeMenuField($name, $values, $selected = '', $label = null, $id = '', $class = '', $attrs = array())
  603. {
  604. if (is_null($label)) $label = $name;
  605. $options = array();
  606. reset($values);
  607. // FIXME: php doesn't know the difference between a string and an integer
  608. if (is_string(key($values))) {
  609. foreach ($values as $val => $text) {
  610. $options[] = array($val, $text, (!is_null($selected) && $val == $selected));
  611. }
  612. } else {
  613. if (is_integer($selected)) $selected = $values[$selected];
  614. foreach ($values as $val) {
  615. if (is_array($val))
  616. @list($val, $text) = $val;
  617. else $text = null;
  618. $options[] = array($val, $text, $val === $selected);
  619. }
  620. }
  621. $elem = array('_elem' => 'menufield', '_options' => $options, '_text' => $label, '_class' => $class,
  622. 'id' => $id, 'name' => $name);
  623. return array_merge($elem, $attrs);
  624. }
  625. /**
  626. * form_makeListboxField
  627. *
  628. * Create a form element for a list box with label.
  629. * The list of values can be strings, arrays of (value,text),
  630. * or an associative array with the values as keys and labels as values.
  631. * Items are selected by supplying its value or an array of values.
  632. *
  633. * @author Tom N Harris <tnharris@whoopdedo.org>
  634. *
  635. * @param string $name Name attribute of the input.
  636. * @param string[]|array[] $values The list of values can be strings, arrays of (value,text),
  637. * or an associative array with the values as keys and labels as values.
  638. * @param array|string $selected value or array of values of the items that need to be selected
  639. * @param string $class Class attribute of the label. If this is 'block',
  640. * then a line break will be added after the field.
  641. * @param string $label Label that will be printed before the input.
  642. * @param string $id ID attribute of the input. If set, the label will
  643. * reference it with a 'for' attribute.
  644. * @param array $attrs Optional attributes.
  645. * @return array pseudo-tag
  646. */
  647. function form_makeListboxField($name, $values, $selected = '', $label = null, $id = '', $class = '', $attrs = array())
  648. {
  649. if (is_null($label)) $label = $name;
  650. $options = array();
  651. reset($values);
  652. if (is_null($selected) || $selected == '') {
  653. $selected = array();
  654. } elseif (!is_array($selected)) {
  655. $selected = array($selected);
  656. }
  657. // FIXME: php doesn't know the difference between a string and an integer
  658. if (is_string(key($values))) {
  659. foreach ($values as $val => $text) {
  660. $options[] = array($val, $text, in_array($val, $selected));
  661. }
  662. } else {
  663. foreach ($values as $val) {
  664. $disabled = false;
  665. if (is_array($val)) {
  666. @list($val, $text, $disabled) = $val;
  667. } else {
  668. $text = null;
  669. }
  670. $options[] = array($val, $text, in_array($val, $selected), $disabled);
  671. }
  672. }
  673. $elem = array('_elem' => 'listboxfield', '_options' => $options, '_text' => $label, '_class' => $class,
  674. 'id' => $id, 'name' => $name);
  675. return array_merge($elem, $attrs);
  676. }
  677. /**
  678. * form_tag
  679. *
  680. * Print the HTML for a generic empty tag.
  681. * Requires '_tag' key with name of the tag.
  682. * Attributes are passed to buildAttributes()
  683. *
  684. * @author Tom N Harris <tnharris@whoopdedo.org>
  685. *
  686. * @param array $attrs attributes
  687. * @return string html of tag
  688. */
  689. function form_tag($attrs)
  690. {
  691. return '<' . $attrs['_tag'] . ' ' . buildAttributes($attrs, true) . '/>';
  692. }
  693. /**
  694. * form_opentag
  695. *
  696. * Print the HTML for a generic opening tag.
  697. * Requires '_tag' key with name of the tag.
  698. * Attributes are passed to buildAttributes()
  699. *
  700. * @author Tom N Harris <tnharris@whoopdedo.org>
  701. *
  702. * @param array $attrs attributes
  703. * @return string html of tag
  704. */
  705. function form_opentag($attrs)
  706. {
  707. return '<' . $attrs['_tag'] . ' ' . buildAttributes($attrs, true) . '>';
  708. }
  709. /**
  710. * form_closetag
  711. *
  712. * Print the HTML for a generic closing tag.
  713. * Requires '_tag' key with name of the tag.
  714. * There are no attributes.
  715. *
  716. * @author Tom N Harris <tnharris@whoopdedo.org>
  717. *
  718. * @param array $attrs attributes
  719. * @return string html of tag
  720. */
  721. function form_closetag($attrs)
  722. {
  723. return '</' . $attrs['_tag'] . '>';
  724. }
  725. /**
  726. * form_openfieldset
  727. *
  728. * Print the HTML for an opening fieldset tag.
  729. * Uses the '_legend' key.
  730. * Attributes are passed to buildAttributes()
  731. *
  732. * @author Tom N Harris <tnharris@whoopdedo.org>
  733. *
  734. * @param array $attrs attributes
  735. * @return string html
  736. */
  737. function form_openfieldset($attrs)
  738. {
  739. $s = '<fieldset ' . buildAttributes($attrs, true) . '>';
  740. if (!is_null($attrs['_legend'])) $s .= '<legend>' . $attrs['_legend'] . '</legend>';
  741. return $s;
  742. }
  743. /**
  744. * form_closefieldset
  745. *
  746. * Print the HTML for a closing fieldset tag.
  747. * There are no attributes.
  748. *
  749. * @author Tom N Harris <tnharris@whoopdedo.org>
  750. *
  751. * @return string html
  752. */
  753. function form_closefieldset()
  754. {
  755. return '</fieldset>';
  756. }
  757. /**
  758. * form_hidden
  759. *
  760. * Print the HTML for a hidden input element.
  761. * Uses only 'name' and 'value' attributes.
  762. * Value is passed to formText()
  763. *
  764. * @author Tom N Harris <tnharris@whoopdedo.org>
  765. *
  766. * @param array $attrs attributes
  767. * @return string html
  768. */
  769. function form_hidden($attrs)
  770. {
  771. return '<input type="hidden" name="' . $attrs['name'] . '" value="' . formText($attrs['value']) . '" />';
  772. }
  773. /**
  774. * form_wikitext
  775. *
  776. * Print the HTML for the wiki textarea.
  777. * Requires '_text' with default text of the field.
  778. * Text will be passed to formText(), attributes to buildAttributes()
  779. *
  780. * @author Tom N Harris <tnharris@whoopdedo.org>
  781. *
  782. * @param array $attrs attributes
  783. * @return string html
  784. */
  785. function form_wikitext($attrs)
  786. {
  787. // mandatory attributes
  788. unset($attrs['name']);
  789. unset($attrs['id']);
  790. return '<textarea name="wikitext" id="wiki__text" dir="auto" '
  791. . buildAttributes($attrs, true) . '>' . DOKU_LF
  792. . formText($attrs['_text'])
  793. . '</textarea>';
  794. }
  795. /**
  796. * form_button
  797. *
  798. * Print the HTML for a form button.
  799. * If '_action' is set, the button name will be "do[_action]".
  800. * Other attributes are passed to buildAttributes()
  801. *
  802. * @author Tom N Harris <tnharris@whoopdedo.org>
  803. *
  804. * @param array $attrs attributes
  805. * @return string html
  806. */
  807. function form_button($attrs)
  808. {
  809. $p = (!empty($attrs['_action'])) ? 'name="do[' . $attrs['_action'] . ']" ' : '';
  810. $value = $attrs['value'];
  811. unset($attrs['value']);
  812. return '<button ' . $p . buildAttributes($attrs, true) . '>' . $value . '</button>';
  813. }
  814. /**
  815. * form_field
  816. *
  817. * Print the HTML for a form input field.
  818. * _class : class attribute used on the label tag
  819. * _text : Text to display before the input. Not escaped.
  820. * Other attributes are passed to buildAttributes() for the input tag.
  821. *
  822. * @author Tom N Harris <tnharris@whoopdedo.org>
  823. *
  824. * @param array $attrs attributes
  825. * @return string html
  826. */
  827. function form_field($attrs)
  828. {
  829. $s = '<label';
  830. if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"';
  831. if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"';
  832. $s .= '><span>' . $attrs['_text'] . '</span>';
  833. $s .= ' <input ' . buildAttributes($attrs, true) . ' /></label>';
  834. if (preg_match('/(^| )block($| )/', $attrs['_class']))
  835. $s .= '<br />';
  836. return $s;
  837. }
  838. /**
  839. * form_fieldright
  840. *
  841. * Print the HTML for a form input field. (right-aligned)
  842. * _class : class attribute used on the label tag
  843. * _text : Text to display after the input. Not escaped.
  844. * Other attributes are passed to buildAttributes() for the input tag.
  845. *
  846. * @author Tom N Harris <tnharris@whoopdedo.org>
  847. *
  848. * @param array $attrs attributes
  849. * @return string html
  850. */
  851. function form_fieldright($attrs)
  852. {
  853. $s = '<label';
  854. if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"';
  855. if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"';
  856. $s .= '><input ' . buildAttributes($attrs, true) . ' />';
  857. $s .= ' <span>' . $attrs['_text'] . '</span></label>';
  858. if (preg_match('/(^| )block($| )/', $attrs['_class']))
  859. $s .= '<br />';
  860. return $s;
  861. }
  862. /**
  863. * form_textfield
  864. *
  865. * Print the HTML for a text input field.
  866. * _class : class attribute used on the label tag
  867. * _text : Text to display before the input. Not escaped.
  868. * Other attributes are passed to buildAttributes() for the input tag.
  869. *
  870. * @author Tom N Harris <tnharris@whoopdedo.org>
  871. *
  872. * @param array $attrs attributes
  873. * @return string html
  874. */
  875. function form_textfield($attrs)
  876. {
  877. // mandatory attributes
  878. unset($attrs['type']);
  879. $s = '<label';
  880. if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"';
  881. if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"';
  882. $s .= '><span>' . $attrs['_text'] . '</span> ';
  883. $s .= '<input type="text" ' . buildAttributes($attrs, true) . ' /></label>';
  884. if (preg_match('/(^| )block($| )/', $attrs['_class']))
  885. $s .= '<br />';
  886. return $s;
  887. }
  888. /**
  889. * form_passwordfield
  890. *
  891. * Print the HTML for a password input field.
  892. * _class : class attribute used on the label tag
  893. * _text : Text to display before the input. Not escaped.
  894. * Other attributes are passed to buildAttributes() for the input tag.
  895. *
  896. * @author Tom N Harris <tnharris@whoopdedo.org>
  897. *
  898. * @param array $attrs attributes
  899. * @return string html
  900. */
  901. function form_passwordfield($attrs)
  902. {
  903. // mandatory attributes
  904. unset($attrs['type']);
  905. $s = '<label';
  906. if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"';
  907. if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"';
  908. $s .= '><span>' . $attrs['_text'] . '</span> ';
  909. $s .= '<input type="password" ' . buildAttributes($attrs, true) . ' /></label>';
  910. if (preg_match('/(^| )block($| )/', $attrs['_class']))
  911. $s .= '<br />';
  912. return $s;
  913. }
  914. /**
  915. * form_filefield
  916. *
  917. * Print the HTML for a file input field.
  918. * _class : class attribute used on the label tag
  919. * _text : Text to display before the input. Not escaped
  920. * _maxlength : Allowed size in byte
  921. * _accept : Accepted mime-type
  922. * Other attributes are passed to buildAttributes() for the input tag
  923. *
  924. * @author Michael Klier <chi@chimeric.de>
  925. *
  926. * @param array $attrs attributes
  927. * @return string html
  928. */
  929. function form_filefield($attrs)
  930. {
  931. $s = '<label';
  932. if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"';
  933. if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"';
  934. $s .= '><span>' . $attrs['_text'] . '</span> ';
  935. $s .= '<input type="file" ' . buildAttributes($attrs, true);
  936. if (!empty($attrs['_maxlength'])) $s .= ' maxlength="' . $attrs['_maxlength'] . '"';
  937. if (!empty($attrs['_accept'])) $s .= ' accept="' . $attrs['_accept'] . '"';
  938. $s .= ' /></label>';
  939. if (preg_match('/(^| )block($| )/', $attrs['_class']))
  940. $s .= '<br />';
  941. return $s;
  942. }
  943. /**
  944. * form_checkboxfield
  945. *
  946. * Print the HTML for a checkbox input field.
  947. * _class : class attribute used on the label tag
  948. * _text : Text to display after the input. Not escaped.
  949. * Other attributes are passed to buildAttributes() for the input tag.
  950. * If value is an array, a hidden field with the same name and the value
  951. * $attrs['value'][1] is constructed as well.
  952. *
  953. * @author Tom N Harris <tnharris@whoopdedo.org>
  954. *
  955. * @param array $attrs attributes
  956. * @return string html
  957. */
  958. function form_checkboxfield($attrs)
  959. {
  960. // mandatory attributes
  961. unset($attrs['type']);
  962. $s = '<label';
  963. if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"';
  964. if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"';
  965. $s .= '>';
  966. if (is_array($attrs['value'])) {
  967. echo '<input type="hidden" name="' . hsc($attrs['name']) . '"'
  968. . ' value="' . hsc($attrs['value'][1]) . '" />';
  969. $attrs['value'] = $attrs['value'][0];
  970. }
  971. $s .= '<input type="checkbox" ' . buildAttributes($attrs, true) . ' />';
  972. $s .= ' <span>' . $attrs['_text'] . '</span></label>';
  973. if (preg_match('/(^| )block($| )/', $attrs['_class']))
  974. $s .= '<br />';
  975. return $s;
  976. }
  977. /**
  978. * form_radiofield
  979. *
  980. * Print the HTML for a radio button input field.
  981. * _class : class attribute used on the label tag
  982. * _text : Text to display after the input. Not escaped.
  983. * Other attributes are passed to buildAttributes() for the input tag.
  984. *
  985. * @author Tom N Harris <tnharris@whoopdedo.org>
  986. *
  987. * @param array $attrs attributes
  988. * @return string html
  989. */
  990. function form_radiofield($attrs)
  991. {
  992. // mandatory attributes
  993. unset($attrs['type']);
  994. $s = '<label';
  995. if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"';
  996. if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"';
  997. $s .= '><input type="radio" ' . buildAttributes($attrs, true) . ' />';
  998. $s .= ' <span>' . $attrs['_text'] . '</span></label>';
  999. if (preg_match('/(^| )block($| )/', $attrs['_class']))
  1000. $s .= '<br />';
  1001. return $s;
  1002. }
  1003. /**
  1004. * form_menufield
  1005. *
  1006. * Print the HTML for a drop-down menu.
  1007. * _options : Array of (value,text,selected) for the menu.
  1008. * Text can be omitted. Text and value are passed to formText()
  1009. * Only one item can be selected.
  1010. * _class : class attribute used on the label tag
  1011. * _text : Text to display before the menu. Not escaped.
  1012. * Other attributes are passed to buildAttributes() for the input tag.
  1013. *
  1014. * @author Tom N Harris <tnharris@whoopdedo.org>
  1015. *
  1016. * @param array $attrs attributes
  1017. * @return string html
  1018. */
  1019. function form_menufield($attrs)
  1020. {
  1021. $attrs['size'] = '1';
  1022. $s = '<label';
  1023. if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"';
  1024. if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"';
  1025. $s .= '><span>' . $attrs['_text'] . '</span>';
  1026. $s .= ' <select ' . buildAttributes($attrs, true) . '>' . DOKU_LF;
  1027. if (!empty($attrs['_options'])) {
  1028. $selected = false;
  1029. $cnt = count($attrs['_options']);
  1030. for ($n = 0; $n < $cnt; $n++) {
  1031. @list($value,$text,$select) = $attrs['_options'][$n];
  1032. $p = '';
  1033. if (!is_null($text))
  1034. $p .= ' value="' . formText($value) . '"';
  1035. else $text = $value;
  1036. if (!empty($select) && !$selected) {
  1037. $p .= ' selected="selected"';
  1038. $selected = true;
  1039. }
  1040. $s .= '<option' . $p . '>' . formText($text) . '</option>';
  1041. }
  1042. } else {
  1043. $s .= '<option></option>';
  1044. }
  1045. $s .= DOKU_LF . '</select></label>';
  1046. if (preg_match('/(^| )block($| )/', $attrs['_class']))
  1047. $s .= '<br />';
  1048. return $s;
  1049. }
  1050. /**
  1051. * form_listboxfield
  1052. *
  1053. * Print the HTML for a list box.
  1054. * _options : Array of (value,text,selected) for the list.
  1055. * Text can be omitted. Text and value are passed to formText()
  1056. * _class : class attribute used on the label tag
  1057. * _text : Text to display before the menu. Not escaped.
  1058. * Other attributes are passed to buildAttributes() for the input tag.
  1059. *
  1060. * @author Tom N Harris <tnharris@whoopdedo.org>
  1061. *
  1062. * @param array $attrs attributes
  1063. * @return string html
  1064. */
  1065. function form_listboxfield($attrs)
  1066. {
  1067. $s = '<label';
  1068. if ($attrs['_class']) $s .= ' class="' . $attrs['_class'] . '"';
  1069. if (!empty($attrs['id'])) $s .= ' for="' . $attrs['id'] . '"';
  1070. $s .= '><span>' . $attrs['_text'] . '</span> ';
  1071. $s .= '<select ' . buildAttributes($attrs, true) . '>' . DOKU_LF;
  1072. if (!empty($attrs['_options'])) {
  1073. foreach ($attrs['_options'] as $opt) {
  1074. @list($value, $text, $select, $disabled) = $opt;
  1075. $p = '';
  1076. if (is_null($text)) $text = $value;
  1077. $p .= ' value="' . formText($value) . '"';
  1078. if (!empty($select)) $p .= ' selected="selected"';
  1079. if ($disabled) $p .= ' disabled="disabled"';
  1080. $s .= '<option' . $p . '>' . formText($text) . '</option>';
  1081. }
  1082. } else {
  1083. $s .= '<option></option>';
  1084. }
  1085. $s .= DOKU_LF . '</select></label>';
  1086. if (preg_match('/(^| )block($| )/', $attrs['_class']))
  1087. $s .= '<br />';
  1088. return $s;
  1089. }