112a4e4d1SAndreas Gohr<?php 212a4e4d1SAndreas Gohrnamespace dokuwiki\Form; 312a4e4d1SAndreas Gohr 412a4e4d1SAndreas Gohr/** 512a4e4d1SAndreas Gohr * Class Form 612a4e4d1SAndreas Gohr * 712a4e4d1SAndreas Gohr * Represents the whole Form. This is what you work on, and add Elements to 812a4e4d1SAndreas Gohr * 912a4e4d1SAndreas Gohr * @package dokuwiki\Form 1012a4e4d1SAndreas Gohr */ 1112a4e4d1SAndreas Gohrclass Form extends Element { 1212a4e4d1SAndreas Gohr 1312a4e4d1SAndreas Gohr /** 1412a4e4d1SAndreas Gohr * @var array name value pairs for hidden values 1512a4e4d1SAndreas Gohr */ 1612a4e4d1SAndreas Gohr protected $hidden = array(); 1712a4e4d1SAndreas Gohr 1812a4e4d1SAndreas Gohr /** 1912a4e4d1SAndreas Gohr * @var Element[] the elements of the form 2012a4e4d1SAndreas Gohr */ 2112a4e4d1SAndreas Gohr protected $elements = array(); 2212a4e4d1SAndreas Gohr 2312a4e4d1SAndreas Gohr /** 2412a4e4d1SAndreas Gohr * Creates a new, empty form with some default attributes 2512a4e4d1SAndreas Gohr * 2612a4e4d1SAndreas Gohr * @param array $attributes 2712a4e4d1SAndreas Gohr */ 2812a4e4d1SAndreas Gohr public function __construct($attributes = array()) { 2912a4e4d1SAndreas Gohr global $ID; 3012a4e4d1SAndreas Gohr 3112a4e4d1SAndreas Gohr parent::__construct('form', $attributes); 3212a4e4d1SAndreas Gohr 3312a4e4d1SAndreas Gohr // use the current URL as default action 3412a4e4d1SAndreas Gohr if(!$this->attr('action')) { 3512a4e4d1SAndreas Gohr $get = $_GET; 3612a4e4d1SAndreas Gohr if(isset($get['id'])) unset($get['id']); 376d0ceaf9SAndreas Gohr $self = wl($ID, $get, false, '&'); //attributes are escaped later 3812a4e4d1SAndreas Gohr $this->attr('action', $self); 3912a4e4d1SAndreas Gohr } 4012a4e4d1SAndreas Gohr 4112a4e4d1SAndreas Gohr // post is default 4212a4e4d1SAndreas Gohr if(!$this->attr('method')) { 4312a4e4d1SAndreas Gohr $this->attr('method', 'post'); 4412a4e4d1SAndreas Gohr } 4512a4e4d1SAndreas Gohr 4612a4e4d1SAndreas Gohr // we like UTF-8 4712a4e4d1SAndreas Gohr if(!$this->attr('accept-charset')) { 4812a4e4d1SAndreas Gohr $this->attr('accept-charset', 'utf-8'); 4912a4e4d1SAndreas Gohr } 5012a4e4d1SAndreas Gohr 5112a4e4d1SAndreas Gohr // add the security token by default 5212a4e4d1SAndreas Gohr $this->setHiddenField('sectok', getSecurityToken()); 5312a4e4d1SAndreas Gohr 546d0ceaf9SAndreas Gohr // identify this as a new form based form in HTML 556d0ceaf9SAndreas Gohr $this->addClass('doku_form'); 5612a4e4d1SAndreas Gohr } 5712a4e4d1SAndreas Gohr 5812a4e4d1SAndreas Gohr /** 5912a4e4d1SAndreas Gohr * Sets a hidden field 6012a4e4d1SAndreas Gohr * 6112a4e4d1SAndreas Gohr * @param $name 6212a4e4d1SAndreas Gohr * @param $value 6312a4e4d1SAndreas Gohr * @return $this 6412a4e4d1SAndreas Gohr */ 6512a4e4d1SAndreas Gohr public function setHiddenField($name, $value) { 6612a4e4d1SAndreas Gohr $this->hidden[$name] = $value; 6712a4e4d1SAndreas Gohr return $this; 6812a4e4d1SAndreas Gohr } 6912a4e4d1SAndreas Gohr 70*64744a10SAndreas Gohr #region Element adding functions 71*64744a10SAndreas Gohr 7212a4e4d1SAndreas Gohr /** 7312a4e4d1SAndreas Gohr * Adds an element to the end of the form 7412a4e4d1SAndreas Gohr * 7512a4e4d1SAndreas Gohr * @param Element $element 7612a4e4d1SAndreas Gohr * @param int $pos 0-based position in the form, -1 for at the end 7712a4e4d1SAndreas Gohr * @return Element 7812a4e4d1SAndreas Gohr */ 7912a4e4d1SAndreas Gohr public function addElement(Element $element, $pos = -1) { 8012a4e4d1SAndreas Gohr if(is_a($element, 'Doku_Form2')) throw new \InvalidArgumentException('You can\'t add a form to a form'); 8112a4e4d1SAndreas Gohr if($pos < 0) { 8212a4e4d1SAndreas Gohr $this->elements[] = $element; 8312a4e4d1SAndreas Gohr } else { 8412a4e4d1SAndreas Gohr array_splice($this->elements, $pos, 0, array($element)); 8512a4e4d1SAndreas Gohr } 8612a4e4d1SAndreas Gohr return $element; 8712a4e4d1SAndreas Gohr } 8812a4e4d1SAndreas Gohr 8912a4e4d1SAndreas Gohr /** 9012a4e4d1SAndreas Gohr * Adds a text input field 9112a4e4d1SAndreas Gohr * 9212a4e4d1SAndreas Gohr * @param $name 9312a4e4d1SAndreas Gohr * @param $label 9412a4e4d1SAndreas Gohr * @param int $pos 9512a4e4d1SAndreas Gohr * @return InputElement 9612a4e4d1SAndreas Gohr */ 97de19515fSAndreas Gohr public function addTextInput($name, $label = '', $pos = -1) { 9812a4e4d1SAndreas Gohr return $this->addElement(new InputElement('text', $name, $label), $pos); 9912a4e4d1SAndreas Gohr } 10012a4e4d1SAndreas Gohr 10112a4e4d1SAndreas Gohr /** 10212a4e4d1SAndreas Gohr * Adds a password input field 10312a4e4d1SAndreas Gohr * 10412a4e4d1SAndreas Gohr * @param $name 10512a4e4d1SAndreas Gohr * @param $label 10612a4e4d1SAndreas Gohr * @param int $pos 10712a4e4d1SAndreas Gohr * @return InputElement 10812a4e4d1SAndreas Gohr */ 109de19515fSAndreas Gohr public function addPasswordInput($name, $label = '', $pos = -1) { 11012a4e4d1SAndreas Gohr return $this->addElement(new InputElement('password', $name, $label), $pos); 11112a4e4d1SAndreas Gohr } 11212a4e4d1SAndreas Gohr 11312a4e4d1SAndreas Gohr /** 11412a4e4d1SAndreas Gohr * Adds a radio button field 11512a4e4d1SAndreas Gohr * 11612a4e4d1SAndreas Gohr * @param $name 11712a4e4d1SAndreas Gohr * @param $label 11812a4e4d1SAndreas Gohr * @param int $pos 11912a4e4d1SAndreas Gohr * @return CheckableElement 12012a4e4d1SAndreas Gohr */ 121de19515fSAndreas Gohr public function addRadioButton($name, $label = '', $pos = -1) { 12212a4e4d1SAndreas Gohr return $this->addElement(new CheckableElement('radio', $name, $label), $pos); 12312a4e4d1SAndreas Gohr } 12412a4e4d1SAndreas Gohr 12512a4e4d1SAndreas Gohr /** 12612a4e4d1SAndreas Gohr * Adds a checkbox field 12712a4e4d1SAndreas Gohr * 12812a4e4d1SAndreas Gohr * @param $name 12912a4e4d1SAndreas Gohr * @param $label 13012a4e4d1SAndreas Gohr * @param int $pos 13112a4e4d1SAndreas Gohr * @return CheckableElement 13212a4e4d1SAndreas Gohr */ 133de19515fSAndreas Gohr public function addCheckbox($name, $label = '', $pos = -1) { 13412a4e4d1SAndreas Gohr return $this->addElement(new CheckableElement('checkbox', $name, $label), $pos); 13512a4e4d1SAndreas Gohr } 13612a4e4d1SAndreas Gohr 13712a4e4d1SAndreas Gohr /** 13812a4e4d1SAndreas Gohr * Adds a textarea field 13912a4e4d1SAndreas Gohr * 14012a4e4d1SAndreas Gohr * @param $name 14112a4e4d1SAndreas Gohr * @param $label 14212a4e4d1SAndreas Gohr * @param int $pos 14312a4e4d1SAndreas Gohr * @return TextareaElement 14412a4e4d1SAndreas Gohr */ 145de19515fSAndreas Gohr public function addTextarea($name, $label = '', $pos = -1) { 14612a4e4d1SAndreas Gohr return $this->addElement(new TextareaElement($name, $label), $pos); 14712a4e4d1SAndreas Gohr } 14812a4e4d1SAndreas Gohr 14912a4e4d1SAndreas Gohr /** 150de19515fSAndreas Gohr * Add fixed HTML to the form 151de19515fSAndreas Gohr * 152de19515fSAndreas Gohr * @param $html 153de19515fSAndreas Gohr * @param int $pos 154*64744a10SAndreas Gohr * @return HTMLElement 155de19515fSAndreas Gohr */ 156de19515fSAndreas Gohr public function addHTML($html, $pos = -1) { 157de19515fSAndreas Gohr return $this->addElement(new HTMLElement($html), $pos); 158de19515fSAndreas Gohr } 159de19515fSAndreas Gohr 160*64744a10SAndreas Gohr /** 161*64744a10SAndreas Gohr * Add a closed HTML tag to the form 162*64744a10SAndreas Gohr * 163*64744a10SAndreas Gohr * @param $tag 164*64744a10SAndreas Gohr * @param int $pos 165*64744a10SAndreas Gohr * @return TagElement 166*64744a10SAndreas Gohr */ 167*64744a10SAndreas Gohr public function addTag($tag, $pos = -1) { 168*64744a10SAndreas Gohr return $this->addElement(new TagElement($tag), $pos); 169*64744a10SAndreas Gohr } 170*64744a10SAndreas Gohr 171*64744a10SAndreas Gohr /** 172*64744a10SAndreas Gohr * Add an open HTML tag to the form 173*64744a10SAndreas Gohr * 174*64744a10SAndreas Gohr * Be sure to close it again! 175*64744a10SAndreas Gohr * 176*64744a10SAndreas Gohr * @param $tag 177*64744a10SAndreas Gohr * @param int $pos 178*64744a10SAndreas Gohr * @return TagOpenElement 179*64744a10SAndreas Gohr */ 180*64744a10SAndreas Gohr public function addTagOpen($tag, $pos = -1) { 181*64744a10SAndreas Gohr return $this->addElement(new TagOpenElement($tag), $pos); 182*64744a10SAndreas Gohr } 183*64744a10SAndreas Gohr 184*64744a10SAndreas Gohr /** 185*64744a10SAndreas Gohr * Add a closing HTML tag to the form 186*64744a10SAndreas Gohr * 187*64744a10SAndreas Gohr * Be sure it had been opened before 188*64744a10SAndreas Gohr * 189*64744a10SAndreas Gohr * @param $tag 190*64744a10SAndreas Gohr * @param int $pos 191*64744a10SAndreas Gohr * @return TagCloseElement 192*64744a10SAndreas Gohr */ 193*64744a10SAndreas Gohr public function addTagClose($tag, $pos = -1) { 194*64744a10SAndreas Gohr return $this->addElement(new TagCloseElement($tag), $pos); 195*64744a10SAndreas Gohr } 196*64744a10SAndreas Gohr 197*64744a10SAndreas Gohr 198*64744a10SAndreas Gohr /** 199*64744a10SAndreas Gohr * Open a Fieldset 200*64744a10SAndreas Gohr * 201*64744a10SAndreas Gohr * @param $legend 202*64744a10SAndreas Gohr * @param int $pos 203*64744a10SAndreas Gohr * @return FieldsetOpenElement 204*64744a10SAndreas Gohr */ 205*64744a10SAndreas Gohr public function addFieldsetOpen($legend='', $pos = -1) { 206*64744a10SAndreas Gohr return $this->addElement(new FieldsetOpenElement($legend), $pos); 207*64744a10SAndreas Gohr } 208*64744a10SAndreas Gohr 209*64744a10SAndreas Gohr /** 210*64744a10SAndreas Gohr * Close a fieldset 211*64744a10SAndreas Gohr * 212*64744a10SAndreas Gohr * @param int $pos 213*64744a10SAndreas Gohr * @return TagCloseElement 214*64744a10SAndreas Gohr */ 215*64744a10SAndreas Gohr public function addFieldsetClose($pos = -1) { 216*64744a10SAndreas Gohr return $this->addElement(new FieldsetCloseElement(), $pos); 217*64744a10SAndreas Gohr } 218*64744a10SAndreas Gohr 219*64744a10SAndreas Gohr #endregion 220*64744a10SAndreas Gohr 221de19515fSAndreas Gohr protected function balanceFieldsets() { 222de19515fSAndreas Gohr //todo implement! 223de19515fSAndreas Gohr } 224de19515fSAndreas Gohr 225de19515fSAndreas Gohr /** 22612a4e4d1SAndreas Gohr * The HTML representation of the whole form 22712a4e4d1SAndreas Gohr * 22812a4e4d1SAndreas Gohr * @return string 22912a4e4d1SAndreas Gohr */ 23012a4e4d1SAndreas Gohr public function toHTML() { 231de19515fSAndreas Gohr $this->balanceFieldsets(); 232de19515fSAndreas Gohr 23312a4e4d1SAndreas Gohr $html = '<form ' . buildAttributes($this->attrs()) . '>' . DOKU_LF; 23412a4e4d1SAndreas Gohr 23512a4e4d1SAndreas Gohr foreach($this->hidden as $name => $value) { 23612a4e4d1SAndreas Gohr $html .= '<input type="hidden" name="' . $name . '" value="' . formText($value) . '" />' . DOKU_LF; 23712a4e4d1SAndreas Gohr } 23812a4e4d1SAndreas Gohr 23912a4e4d1SAndreas Gohr foreach($this->elements as $element) { 24012a4e4d1SAndreas Gohr $html .= $element->toHTML() . DOKU_LF; 24112a4e4d1SAndreas Gohr } 24212a4e4d1SAndreas Gohr 24312a4e4d1SAndreas Gohr $html .= '</form>' . DOKU_LF; 24412a4e4d1SAndreas Gohr 24512a4e4d1SAndreas Gohr return $html; 24612a4e4d1SAndreas Gohr } 24712a4e4d1SAndreas Gohr} 248