1<?php 2namespace dokuwiki\Form; 3 4/** 5 * Class Form 6 * 7 * Represents the whole Form. This is what you work on, and add Elements to 8 * 9 * @package dokuwiki\Form 10 */ 11class Form extends Element { 12 13 /** 14 * @var array name value pairs for hidden values 15 */ 16 protected $hidden = array(); 17 18 /** 19 * @var Element[] the elements of the form 20 */ 21 protected $elements = array(); 22 23 /** 24 * Creates a new, empty form with some default attributes 25 * 26 * @param array $attributes 27 */ 28 public function __construct($attributes = array()) { 29 global $ID; 30 31 parent::__construct('form', $attributes); 32 33 // use the current URL as default action 34 if(!$this->attr('action')) { 35 $get = $_GET; 36 if(isset($get['id'])) unset($get['id']); 37 $self = wl($ID, $get, false, '&'); //attributes are escaped later 38 $this->attr('action', $self); 39 } 40 41 // post is default 42 if(!$this->attr('method')) { 43 $this->attr('method', 'post'); 44 } 45 46 // we like UTF-8 47 if(!$this->attr('accept-charset')) { 48 $this->attr('accept-charset', 'utf-8'); 49 } 50 51 // add the security token by default 52 $this->setHiddenField('sectok', getSecurityToken()); 53 54 // identify this as a new form based form in HTML 55 $this->addClass('doku_form'); 56 } 57 58 /** 59 * Sets a hidden field 60 * 61 * @param $name 62 * @param $value 63 * @return $this 64 */ 65 public function setHiddenField($name, $value) { 66 $this->hidden[$name] = $value; 67 return $this; 68 } 69 70 #region Element adding functions 71 72 /** 73 * Adds an element to the end of the form 74 * 75 * @param Element $element 76 * @param int $pos 0-based position in the form, -1 for at the end 77 * @return Element 78 */ 79 public function addElement(Element $element, $pos = -1) { 80 if(is_a($element, 'Doku_Form2')) throw new \InvalidArgumentException('You can\'t add a form to a form'); 81 if($pos < 0) { 82 $this->elements[] = $element; 83 } else { 84 array_splice($this->elements, $pos, 0, array($element)); 85 } 86 return $element; 87 } 88 89 /** 90 * Adds a text input field 91 * 92 * @param $name 93 * @param $label 94 * @param int $pos 95 * @return InputElement 96 */ 97 public function addTextInput($name, $label = '', $pos = -1) { 98 return $this->addElement(new InputElement('text', $name, $label), $pos); 99 } 100 101 /** 102 * Adds a password input field 103 * 104 * @param $name 105 * @param $label 106 * @param int $pos 107 * @return InputElement 108 */ 109 public function addPasswordInput($name, $label = '', $pos = -1) { 110 return $this->addElement(new InputElement('password', $name, $label), $pos); 111 } 112 113 /** 114 * Adds a radio button field 115 * 116 * @param $name 117 * @param $label 118 * @param int $pos 119 * @return CheckableElement 120 */ 121 public function addRadioButton($name, $label = '', $pos = -1) { 122 return $this->addElement(new CheckableElement('radio', $name, $label), $pos); 123 } 124 125 /** 126 * Adds a checkbox field 127 * 128 * @param $name 129 * @param $label 130 * @param int $pos 131 * @return CheckableElement 132 */ 133 public function addCheckbox($name, $label = '', $pos = -1) { 134 return $this->addElement(new CheckableElement('checkbox', $name, $label), $pos); 135 } 136 137 /** 138 * Adds a textarea field 139 * 140 * @param $name 141 * @param $label 142 * @param int $pos 143 * @return TextareaElement 144 */ 145 public function addTextarea($name, $label = '', $pos = -1) { 146 return $this->addElement(new TextareaElement($name, $label), $pos); 147 } 148 149 /** 150 * Add fixed HTML to the form 151 * 152 * @param $html 153 * @param int $pos 154 * @return HTMLElement 155 */ 156 public function addHTML($html, $pos = -1) { 157 return $this->addElement(new HTMLElement($html), $pos); 158 } 159 160 /** 161 * Add a closed HTML tag to the form 162 * 163 * @param $tag 164 * @param int $pos 165 * @return TagElement 166 */ 167 public function addTag($tag, $pos = -1) { 168 return $this->addElement(new TagElement($tag), $pos); 169 } 170 171 /** 172 * Add an open HTML tag to the form 173 * 174 * Be sure to close it again! 175 * 176 * @param $tag 177 * @param int $pos 178 * @return TagOpenElement 179 */ 180 public function addTagOpen($tag, $pos = -1) { 181 return $this->addElement(new TagOpenElement($tag), $pos); 182 } 183 184 /** 185 * Add a closing HTML tag to the form 186 * 187 * Be sure it had been opened before 188 * 189 * @param $tag 190 * @param int $pos 191 * @return TagCloseElement 192 */ 193 public function addTagClose($tag, $pos = -1) { 194 return $this->addElement(new TagCloseElement($tag), $pos); 195 } 196 197 198 /** 199 * Open a Fieldset 200 * 201 * @param $legend 202 * @param int $pos 203 * @return FieldsetOpenElement 204 */ 205 public function addFieldsetOpen($legend='', $pos = -1) { 206 return $this->addElement(new FieldsetOpenElement($legend), $pos); 207 } 208 209 /** 210 * Close a fieldset 211 * 212 * @param int $pos 213 * @return TagCloseElement 214 */ 215 public function addFieldsetClose($pos = -1) { 216 return $this->addElement(new FieldsetCloseElement(), $pos); 217 } 218 219 #endregion 220 221 protected function balanceFieldsets() { 222 //todo implement! 223 } 224 225 /** 226 * The HTML representation of the whole form 227 * 228 * @return string 229 */ 230 public function toHTML() { 231 $this->balanceFieldsets(); 232 233 $html = '<form ' . buildAttributes($this->attrs()) . '>' . DOKU_LF; 234 235 foreach($this->hidden as $name => $value) { 236 $html .= '<input type="hidden" name="' . $name . '" value="' . formText($value) . '" />' . DOKU_LF; 237 } 238 239 foreach($this->elements as $element) { 240 $html .= $element->toHTML() . DOKU_LF; 241 } 242 243 $html .= '</form>' . DOKU_LF; 244 245 return $html; 246 } 247} 248