112a4e4d1SAndreas Gohr<?php 29d01c1d9SSatoshi Sahara 312a4e4d1SAndreas Gohrnamespace dokuwiki\Form; 412a4e4d1SAndreas Gohr 512a4e4d1SAndreas Gohr/** 612a4e4d1SAndreas Gohr * Class Form 712a4e4d1SAndreas Gohr * 812a4e4d1SAndreas Gohr * Represents the whole Form. This is what you work on, and add Elements to 912a4e4d1SAndreas Gohr * 1012a4e4d1SAndreas Gohr * @package dokuwiki\Form 1112a4e4d1SAndreas Gohr */ 129d01c1d9SSatoshi Saharaclass Form extends Element 139d01c1d9SSatoshi Sahara{ 1412a4e4d1SAndreas Gohr /** 1512a4e4d1SAndreas Gohr * @var array name value pairs for hidden values 1612a4e4d1SAndreas Gohr */ 1712a4e4d1SAndreas Gohr protected $hidden = array(); 1812a4e4d1SAndreas Gohr 1912a4e4d1SAndreas Gohr /** 2012a4e4d1SAndreas Gohr * @var Element[] the elements of the form 2112a4e4d1SAndreas Gohr */ 2212a4e4d1SAndreas Gohr protected $elements = array(); 2312a4e4d1SAndreas Gohr 2412a4e4d1SAndreas Gohr /** 2512a4e4d1SAndreas Gohr * Creates a new, empty form with some default attributes 2612a4e4d1SAndreas Gohr * 2712a4e4d1SAndreas Gohr * @param array $attributes 287fa270bcSMichael Große * @param bool $unsafe if true, then the security token is ommited 2912a4e4d1SAndreas Gohr */ 309d01c1d9SSatoshi Sahara public function __construct($attributes = array(), $unsafe = false) 319d01c1d9SSatoshi Sahara { 3212a4e4d1SAndreas Gohr global $ID; 3312a4e4d1SAndreas Gohr 3412a4e4d1SAndreas Gohr parent::__construct('form', $attributes); 3512a4e4d1SAndreas Gohr 3612a4e4d1SAndreas Gohr // use the current URL as default action 3712a4e4d1SAndreas Gohr if (!$this->attr('action')) { 3812a4e4d1SAndreas Gohr $get = $_GET; 3912a4e4d1SAndreas Gohr if (isset($get['id'])) unset($get['id']); 406d0ceaf9SAndreas Gohr $self = wl($ID, $get, false, '&'); //attributes are escaped later 4112a4e4d1SAndreas Gohr $this->attr('action', $self); 4212a4e4d1SAndreas Gohr } 4312a4e4d1SAndreas Gohr 4412a4e4d1SAndreas Gohr // post is default 4512a4e4d1SAndreas Gohr if (!$this->attr('method')) { 4612a4e4d1SAndreas Gohr $this->attr('method', 'post'); 4712a4e4d1SAndreas Gohr } 4812a4e4d1SAndreas Gohr 4912a4e4d1SAndreas Gohr // we like UTF-8 5012a4e4d1SAndreas Gohr if (!$this->attr('accept-charset')) { 5112a4e4d1SAndreas Gohr $this->attr('accept-charset', 'utf-8'); 5212a4e4d1SAndreas Gohr } 5312a4e4d1SAndreas Gohr 5412a4e4d1SAndreas Gohr // add the security token by default 557fa270bcSMichael Große if (!$unsafe) { 5612a4e4d1SAndreas Gohr $this->setHiddenField('sectok', getSecurityToken()); 577fa270bcSMichael Große } 5812a4e4d1SAndreas Gohr 596d0ceaf9SAndreas Gohr // identify this as a new form based form in HTML 606d0ceaf9SAndreas Gohr $this->addClass('doku_form'); 6112a4e4d1SAndreas Gohr } 6212a4e4d1SAndreas Gohr 6312a4e4d1SAndreas Gohr /** 6412a4e4d1SAndreas Gohr * Sets a hidden field 6512a4e4d1SAndreas Gohr * 667ec97767SGerrit Uitslag * @param string $name 677ec97767SGerrit Uitslag * @param string $value 6812a4e4d1SAndreas Gohr * @return $this 6912a4e4d1SAndreas Gohr */ 709d01c1d9SSatoshi Sahara public function setHiddenField($name, $value) 719d01c1d9SSatoshi Sahara { 7212a4e4d1SAndreas Gohr $this->hidden[$name] = $value; 7312a4e4d1SAndreas Gohr return $this; 7412a4e4d1SAndreas Gohr } 7512a4e4d1SAndreas Gohr 76ef0c211bSAndreas Gohr #region element query function 7764744a10SAndreas Gohr 7812a4e4d1SAndreas Gohr /** 79ef0c211bSAndreas Gohr * Returns the numbers of elements in the form 80ef0c211bSAndreas Gohr * 81ef0c211bSAndreas Gohr * @return int 82ef0c211bSAndreas Gohr */ 839d01c1d9SSatoshi Sahara public function elementCount() 849d01c1d9SSatoshi Sahara { 85ef0c211bSAndreas Gohr return count($this->elements); 86ef0c211bSAndreas Gohr } 87ef0c211bSAndreas Gohr 88ef0c211bSAndreas Gohr /** 895facb9bcSMichael Große * Get the position of the element in the form or false if it is not in the form 905facb9bcSMichael Große * 9164159a61SAndreas Gohr * Warning: This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates 9264159a61SAndreas Gohr * to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the 9364159a61SAndreas Gohr * return value of this function. 945facb9bcSMichael Große * 955facb9bcSMichael Große * @param Element $element 965facb9bcSMichael Große * 975facb9bcSMichael Große * @return false|int 985facb9bcSMichael Große */ 995facb9bcSMichael Große public function getElementPosition(Element $element) 1005facb9bcSMichael Große { 1015facb9bcSMichael Große return array_search($element, $this->elements, true); 1025facb9bcSMichael Große } 1035facb9bcSMichael Große 1045facb9bcSMichael Große /** 105ef0c211bSAndreas Gohr * Returns a reference to the element at a position. 106ef0c211bSAndreas Gohr * A position out-of-bounds will return either the 107ef0c211bSAndreas Gohr * first (underflow) or last (overflow) element. 108ef0c211bSAndreas Gohr * 1097ec97767SGerrit Uitslag * @param int $pos 110ef0c211bSAndreas Gohr * @return Element 111ef0c211bSAndreas Gohr */ 1129d01c1d9SSatoshi Sahara public function getElementAt($pos) 1139d01c1d9SSatoshi Sahara { 114ef0c211bSAndreas Gohr if ($pos < 0) $pos = count($this->elements) + $pos; 115ef0c211bSAndreas Gohr if ($pos < 0) $pos = 0; 116ef0c211bSAndreas Gohr if ($pos >= count($this->elements)) $pos = count($this->elements) - 1; 117ef0c211bSAndreas Gohr return $this->elements[$pos]; 118ef0c211bSAndreas Gohr } 119ef0c211bSAndreas Gohr 120ef0c211bSAndreas Gohr /** 121ef0c211bSAndreas Gohr * Gets the position of the first of a type of element 122ef0c211bSAndreas Gohr * 123ef0c211bSAndreas Gohr * @param string $type Element type to look for. 124ef0c211bSAndreas Gohr * @param int $offset search from this position onward 125ef0c211bSAndreas Gohr * @return false|int position of element if found, otherwise false 126ef0c211bSAndreas Gohr */ 1279d01c1d9SSatoshi Sahara public function findPositionByType($type, $offset = 0) 1289d01c1d9SSatoshi Sahara { 129ef0c211bSAndreas Gohr $len = $this->elementCount(); 130ef0c211bSAndreas Gohr for ($pos = $offset; $pos < $len; $pos++) { 131ef0c211bSAndreas Gohr if ($this->elements[$pos]->getType() == $type) { 132ef0c211bSAndreas Gohr return $pos; 133ef0c211bSAndreas Gohr } 134ef0c211bSAndreas Gohr } 135ef0c211bSAndreas Gohr return false; 136ef0c211bSAndreas Gohr } 137ef0c211bSAndreas Gohr 138ef0c211bSAndreas Gohr /** 139ef0c211bSAndreas Gohr * Gets the position of the first element matching the attribute 140ef0c211bSAndreas Gohr * 141ef0c211bSAndreas Gohr * @param string $name Name of the attribute 142ef0c211bSAndreas Gohr * @param string $value Value the attribute should have 143ef0c211bSAndreas Gohr * @param int $offset search from this position onward 144ef0c211bSAndreas Gohr * @return false|int position of element if found, otherwise false 145ef0c211bSAndreas Gohr */ 1469d01c1d9SSatoshi Sahara public function findPositionByAttribute($name, $value, $offset = 0) 1479d01c1d9SSatoshi Sahara { 148ef0c211bSAndreas Gohr $len = $this->elementCount(); 149ef0c211bSAndreas Gohr for ($pos = $offset; $pos < $len; $pos++) { 150ef0c211bSAndreas Gohr if ($this->elements[$pos]->attr($name) == $value) { 151ef0c211bSAndreas Gohr return $pos; 152ef0c211bSAndreas Gohr } 153ef0c211bSAndreas Gohr } 154ef0c211bSAndreas Gohr return false; 155ef0c211bSAndreas Gohr } 156ef0c211bSAndreas Gohr 157ef0c211bSAndreas Gohr #endregion 158ef0c211bSAndreas Gohr 159ef0c211bSAndreas Gohr #region Element positioning functions 160ef0c211bSAndreas Gohr 161ef0c211bSAndreas Gohr /** 162ef0c211bSAndreas Gohr * Adds or inserts an element to the form 16312a4e4d1SAndreas Gohr * 16412a4e4d1SAndreas Gohr * @param Element $element 16512a4e4d1SAndreas Gohr * @param int $pos 0-based position in the form, -1 for at the end 16612a4e4d1SAndreas Gohr * @return Element 16712a4e4d1SAndreas Gohr */ 1689d01c1d9SSatoshi Sahara public function addElement(Element $element, $pos = -1) 1699d01c1d9SSatoshi Sahara { 17064159a61SAndreas Gohr if (is_a($element, '\dokuwiki\Form\Form')) throw new \InvalidArgumentException( 17164159a61SAndreas Gohr 'You can\'t add a form to a form' 17264159a61SAndreas Gohr ); 17312a4e4d1SAndreas Gohr if ($pos < 0) { 17412a4e4d1SAndreas Gohr $this->elements[] = $element; 17512a4e4d1SAndreas Gohr } else { 17612a4e4d1SAndreas Gohr array_splice($this->elements, $pos, 0, array($element)); 17712a4e4d1SAndreas Gohr } 17812a4e4d1SAndreas Gohr return $element; 17912a4e4d1SAndreas Gohr } 18012a4e4d1SAndreas Gohr 18112a4e4d1SAndreas Gohr /** 182ef0c211bSAndreas Gohr * Replaces an existing element with a new one 183ef0c211bSAndreas Gohr * 184ef0c211bSAndreas Gohr * @param Element $element the new element 1857ec97767SGerrit Uitslag * @param int $pos 0-based position of the element to replace 186ef0c211bSAndreas Gohr */ 1879d01c1d9SSatoshi Sahara public function replaceElement(Element $element, $pos) 1889d01c1d9SSatoshi Sahara { 18964159a61SAndreas Gohr if (is_a($element, '\dokuwiki\Form\Form')) throw new \InvalidArgumentException( 19064159a61SAndreas Gohr 'You can\'t add a form to a form' 19164159a61SAndreas Gohr ); 192ef0c211bSAndreas Gohr array_splice($this->elements, $pos, 1, array($element)); 193ef0c211bSAndreas Gohr } 194ef0c211bSAndreas Gohr 195ef0c211bSAndreas Gohr /** 196ef0c211bSAndreas Gohr * Remove an element from the form completely 197ef0c211bSAndreas Gohr * 1987ec97767SGerrit Uitslag * @param int $pos 0-based position of the element to remove 199ef0c211bSAndreas Gohr */ 2009d01c1d9SSatoshi Sahara public function removeElement($pos) 2019d01c1d9SSatoshi Sahara { 202ef0c211bSAndreas Gohr array_splice($this->elements, $pos, 1); 203ef0c211bSAndreas Gohr } 204ef0c211bSAndreas Gohr 205ef0c211bSAndreas Gohr #endregion 206ef0c211bSAndreas Gohr 207ef0c211bSAndreas Gohr #region Element adding functions 208ef0c211bSAndreas Gohr 209ef0c211bSAndreas Gohr /** 21012a4e4d1SAndreas Gohr * Adds a text input field 21112a4e4d1SAndreas Gohr * 2127ec97767SGerrit Uitslag * @param string $name 2137ec97767SGerrit Uitslag * @param string $label 21412a4e4d1SAndreas Gohr * @param int $pos 21512a4e4d1SAndreas Gohr * @return InputElement 21612a4e4d1SAndreas Gohr */ 2179d01c1d9SSatoshi Sahara public function addTextInput($name, $label = '', $pos = -1) 2189d01c1d9SSatoshi Sahara { 21912a4e4d1SAndreas Gohr return $this->addElement(new InputElement('text', $name, $label), $pos); 22012a4e4d1SAndreas Gohr } 22112a4e4d1SAndreas Gohr 22212a4e4d1SAndreas Gohr /** 22312a4e4d1SAndreas Gohr * Adds a password input field 22412a4e4d1SAndreas Gohr * 2257ec97767SGerrit Uitslag * @param string $name 2267ec97767SGerrit Uitslag * @param string $label 22712a4e4d1SAndreas Gohr * @param int $pos 22812a4e4d1SAndreas Gohr * @return InputElement 22912a4e4d1SAndreas Gohr */ 2309d01c1d9SSatoshi Sahara public function addPasswordInput($name, $label = '', $pos = -1) 2319d01c1d9SSatoshi Sahara { 23212a4e4d1SAndreas Gohr return $this->addElement(new InputElement('password', $name, $label), $pos); 23312a4e4d1SAndreas Gohr } 23412a4e4d1SAndreas Gohr 23512a4e4d1SAndreas Gohr /** 23612a4e4d1SAndreas Gohr * Adds a radio button field 23712a4e4d1SAndreas Gohr * 2387ec97767SGerrit Uitslag * @param string $name 2397ec97767SGerrit Uitslag * @param string $label 24012a4e4d1SAndreas Gohr * @param int $pos 24112a4e4d1SAndreas Gohr * @return CheckableElement 24212a4e4d1SAndreas Gohr */ 2439d01c1d9SSatoshi Sahara public function addRadioButton($name, $label = '', $pos = -1) 2449d01c1d9SSatoshi Sahara { 24512a4e4d1SAndreas Gohr return $this->addElement(new CheckableElement('radio', $name, $label), $pos); 24612a4e4d1SAndreas Gohr } 24712a4e4d1SAndreas Gohr 24812a4e4d1SAndreas Gohr /** 24912a4e4d1SAndreas Gohr * Adds a checkbox field 25012a4e4d1SAndreas Gohr * 2517ec97767SGerrit Uitslag * @param string $name 2527ec97767SGerrit Uitslag * @param string $label 25312a4e4d1SAndreas Gohr * @param int $pos 25412a4e4d1SAndreas Gohr * @return CheckableElement 25512a4e4d1SAndreas Gohr */ 2569d01c1d9SSatoshi Sahara public function addCheckbox($name, $label = '', $pos = -1) 2579d01c1d9SSatoshi Sahara { 25812a4e4d1SAndreas Gohr return $this->addElement(new CheckableElement('checkbox', $name, $label), $pos); 25912a4e4d1SAndreas Gohr } 26012a4e4d1SAndreas Gohr 26112a4e4d1SAndreas Gohr /** 2628638ead5SAndreas Gohr * Adds a dropdown field 2638638ead5SAndreas Gohr * 2647ec97767SGerrit Uitslag * @param string $name 2658638ead5SAndreas Gohr * @param array $options 2668638ead5SAndreas Gohr * @param string $label 2678638ead5SAndreas Gohr * @param int $pos 2688638ead5SAndreas Gohr * @return DropdownElement 2698638ead5SAndreas Gohr */ 2709d01c1d9SSatoshi Sahara public function addDropdown($name, $options, $label = '', $pos = -1) 2719d01c1d9SSatoshi Sahara { 2728638ead5SAndreas Gohr return $this->addElement(new DropdownElement($name, $options, $label), $pos); 2738638ead5SAndreas Gohr } 2748638ead5SAndreas Gohr 2758638ead5SAndreas Gohr /** 27612a4e4d1SAndreas Gohr * Adds a textarea field 27712a4e4d1SAndreas Gohr * 2787ec97767SGerrit Uitslag * @param string $name 2797ec97767SGerrit Uitslag * @param string $label 28012a4e4d1SAndreas Gohr * @param int $pos 28112a4e4d1SAndreas Gohr * @return TextareaElement 28212a4e4d1SAndreas Gohr */ 2839d01c1d9SSatoshi Sahara public function addTextarea($name, $label = '', $pos = -1) 2849d01c1d9SSatoshi Sahara { 28512a4e4d1SAndreas Gohr return $this->addElement(new TextareaElement($name, $label), $pos); 28612a4e4d1SAndreas Gohr } 28712a4e4d1SAndreas Gohr 28812a4e4d1SAndreas Gohr /** 2898f0df229SAndreas Gohr * Adds a simple button, escapes the content for you 2908f0df229SAndreas Gohr * 2918f0df229SAndreas Gohr * @param string $name 2928f0df229SAndreas Gohr * @param string $content 2938f0df229SAndreas Gohr * @param int $pos 2948f0df229SAndreas Gohr * @return Element 2958f0df229SAndreas Gohr */ 2969d01c1d9SSatoshi Sahara public function addButton($name, $content, $pos = -1) 2979d01c1d9SSatoshi Sahara { 2988f0df229SAndreas Gohr return $this->addElement(new ButtonElement($name, hsc($content)), $pos); 2998f0df229SAndreas Gohr } 3008f0df229SAndreas Gohr 3018f0df229SAndreas Gohr /** 3028f0df229SAndreas Gohr * Adds a simple button, allows HTML for content 3038f0df229SAndreas Gohr * 3048f0df229SAndreas Gohr * @param string $name 3058f0df229SAndreas Gohr * @param string $html 3068f0df229SAndreas Gohr * @param int $pos 3078f0df229SAndreas Gohr * @return Element 3088f0df229SAndreas Gohr */ 3099d01c1d9SSatoshi Sahara public function addButtonHTML($name, $html, $pos = -1) 3109d01c1d9SSatoshi Sahara { 3118f0df229SAndreas Gohr return $this->addElement(new ButtonElement($name, $html), $pos); 3128f0df229SAndreas Gohr } 3138f0df229SAndreas Gohr 3148f0df229SAndreas Gohr /** 315a453c16bSAndreas Gohr * Adds a label referencing another input element, escapes the label for you 316a453c16bSAndreas Gohr * 3177ec97767SGerrit Uitslag * @param string $label 318a453c16bSAndreas Gohr * @param string $for 319a453c16bSAndreas Gohr * @param int $pos 320a453c16bSAndreas Gohr * @return Element 321a453c16bSAndreas Gohr */ 3229d01c1d9SSatoshi Sahara public function addLabel($label, $for='', $pos = -1) 3239d01c1d9SSatoshi Sahara { 324a453c16bSAndreas Gohr return $this->addLabelHTML(hsc($label), $for, $pos); 325a453c16bSAndreas Gohr } 326a453c16bSAndreas Gohr 327a453c16bSAndreas Gohr /** 328a453c16bSAndreas Gohr * Adds a label referencing another input element, allows HTML for content 329a453c16bSAndreas Gohr * 330a453c16bSAndreas Gohr * @param string $content 331a453c16bSAndreas Gohr * @param string|Element $for 332a453c16bSAndreas Gohr * @param int $pos 333a453c16bSAndreas Gohr * @return Element 334a453c16bSAndreas Gohr */ 3359d01c1d9SSatoshi Sahara public function addLabelHTML($content, $for='', $pos = -1) 3369d01c1d9SSatoshi Sahara { 337a453c16bSAndreas Gohr $element = new LabelElement(hsc($content)); 338a453c16bSAndreas Gohr 339a453c16bSAndreas Gohr if (is_a($for, '\dokuwiki\Form\Element')) { 340a453c16bSAndreas Gohr /** @var Element $for */ 341a453c16bSAndreas Gohr $for = $for->id(); 342a453c16bSAndreas Gohr } 343a453c16bSAndreas Gohr $for = (string) $for; 344a453c16bSAndreas Gohr if ($for !== '') { 345a453c16bSAndreas Gohr $element->attr('for', $for); 346a453c16bSAndreas Gohr } 347a453c16bSAndreas Gohr 348a453c16bSAndreas Gohr return $this->addElement($element, $pos); 349a453c16bSAndreas Gohr } 350a453c16bSAndreas Gohr 351a453c16bSAndreas Gohr /** 352de19515fSAndreas Gohr * Add fixed HTML to the form 353de19515fSAndreas Gohr * 3547ec97767SGerrit Uitslag * @param string $html 355de19515fSAndreas Gohr * @param int $pos 35664744a10SAndreas Gohr * @return HTMLElement 357de19515fSAndreas Gohr */ 3589d01c1d9SSatoshi Sahara public function addHTML($html, $pos = -1) 3599d01c1d9SSatoshi Sahara { 360de19515fSAndreas Gohr return $this->addElement(new HTMLElement($html), $pos); 361de19515fSAndreas Gohr } 362de19515fSAndreas Gohr 36364744a10SAndreas Gohr /** 36464744a10SAndreas Gohr * Add a closed HTML tag to the form 36564744a10SAndreas Gohr * 3667ec97767SGerrit Uitslag * @param string $tag 36764744a10SAndreas Gohr * @param int $pos 36864744a10SAndreas Gohr * @return TagElement 36964744a10SAndreas Gohr */ 3709d01c1d9SSatoshi Sahara public function addTag($tag, $pos = -1) 3719d01c1d9SSatoshi Sahara { 37264744a10SAndreas Gohr return $this->addElement(new TagElement($tag), $pos); 37364744a10SAndreas Gohr } 37464744a10SAndreas Gohr 37564744a10SAndreas Gohr /** 37664744a10SAndreas Gohr * Add an open HTML tag to the form 37764744a10SAndreas Gohr * 37864744a10SAndreas Gohr * Be sure to close it again! 37964744a10SAndreas Gohr * 3807ec97767SGerrit Uitslag * @param string $tag 38164744a10SAndreas Gohr * @param int $pos 38264744a10SAndreas Gohr * @return TagOpenElement 38364744a10SAndreas Gohr */ 3849d01c1d9SSatoshi Sahara public function addTagOpen($tag, $pos = -1) 3859d01c1d9SSatoshi Sahara { 38664744a10SAndreas Gohr return $this->addElement(new TagOpenElement($tag), $pos); 38764744a10SAndreas Gohr } 38864744a10SAndreas Gohr 38964744a10SAndreas Gohr /** 39064744a10SAndreas Gohr * Add a closing HTML tag to the form 39164744a10SAndreas Gohr * 39264744a10SAndreas Gohr * Be sure it had been opened before 39364744a10SAndreas Gohr * 3947ec97767SGerrit Uitslag * @param string $tag 39564744a10SAndreas Gohr * @param int $pos 39664744a10SAndreas Gohr * @return TagCloseElement 39764744a10SAndreas Gohr */ 3989d01c1d9SSatoshi Sahara public function addTagClose($tag, $pos = -1) 3999d01c1d9SSatoshi Sahara { 40064744a10SAndreas Gohr return $this->addElement(new TagCloseElement($tag), $pos); 40164744a10SAndreas Gohr } 40264744a10SAndreas Gohr 40364744a10SAndreas Gohr /** 40464744a10SAndreas Gohr * Open a Fieldset 40564744a10SAndreas Gohr * 4067ec97767SGerrit Uitslag * @param string $legend 40764744a10SAndreas Gohr * @param int $pos 40864744a10SAndreas Gohr * @return FieldsetOpenElement 40964744a10SAndreas Gohr */ 4109d01c1d9SSatoshi Sahara public function addFieldsetOpen($legend = '', $pos = -1) 4119d01c1d9SSatoshi Sahara { 41264744a10SAndreas Gohr return $this->addElement(new FieldsetOpenElement($legend), $pos); 41364744a10SAndreas Gohr } 41464744a10SAndreas Gohr 41564744a10SAndreas Gohr /** 41664744a10SAndreas Gohr * Close a fieldset 41764744a10SAndreas Gohr * 41864744a10SAndreas Gohr * @param int $pos 41964744a10SAndreas Gohr * @return TagCloseElement 42064744a10SAndreas Gohr */ 4219d01c1d9SSatoshi Sahara public function addFieldsetClose($pos = -1) 4229d01c1d9SSatoshi Sahara { 42364744a10SAndreas Gohr return $this->addElement(new FieldsetCloseElement(), $pos); 42464744a10SAndreas Gohr } 42564744a10SAndreas Gohr 42664744a10SAndreas Gohr #endregion 42764744a10SAndreas Gohr 4281f5d8b65SAndreas Gohr /** 4291f5d8b65SAndreas Gohr * Adjust the elements so that fieldset open and closes are matching 4301f5d8b65SAndreas Gohr */ 4319d01c1d9SSatoshi Sahara protected function balanceFieldsets() 4329d01c1d9SSatoshi Sahara { 4331f5d8b65SAndreas Gohr $lastclose = 0; 4341f5d8b65SAndreas Gohr $isopen = false; 4351f5d8b65SAndreas Gohr $len = count($this->elements); 4361f5d8b65SAndreas Gohr 4371f5d8b65SAndreas Gohr for ($pos = 0; $pos < $len; $pos++) { 4381f5d8b65SAndreas Gohr $type = $this->elements[$pos]->getType(); 4391f5d8b65SAndreas Gohr if ($type == 'fieldsetopen') { 4401f5d8b65SAndreas Gohr if ($isopen) { 44180b13baaSGerrit Uitslag //close previous fieldset 4421f5d8b65SAndreas Gohr $this->addFieldsetClose($pos); 4431f5d8b65SAndreas Gohr $lastclose = $pos + 1; 4441f5d8b65SAndreas Gohr $pos++; 4451f5d8b65SAndreas Gohr $len++; 4461f5d8b65SAndreas Gohr } 4471f5d8b65SAndreas Gohr $isopen = true; 4481f5d8b65SAndreas Gohr } elseif ($type == 'fieldsetclose') { 4491f5d8b65SAndreas Gohr if (!$isopen) { 4501f5d8b65SAndreas Gohr // make sure there was a fieldsetopen 4511f5d8b65SAndreas Gohr // either right after the last close or at the begining 4521f5d8b65SAndreas Gohr $this->addFieldsetOpen('', $lastclose); 4531f5d8b65SAndreas Gohr $len++; 4541f5d8b65SAndreas Gohr $pos++; 4551f5d8b65SAndreas Gohr } 4561f5d8b65SAndreas Gohr $lastclose = $pos; 4571f5d8b65SAndreas Gohr $isopen = false; 4581f5d8b65SAndreas Gohr } 4591f5d8b65SAndreas Gohr } 4601f5d8b65SAndreas Gohr 4611f5d8b65SAndreas Gohr // close open fieldset at the end 4621f5d8b65SAndreas Gohr if ($isopen) { 4631f5d8b65SAndreas Gohr $this->addFieldsetClose(); 4641f5d8b65SAndreas Gohr } 465de19515fSAndreas Gohr } 466de19515fSAndreas Gohr 467de19515fSAndreas Gohr /** 46812a4e4d1SAndreas Gohr * The HTML representation of the whole form 46912a4e4d1SAndreas Gohr * 470*0dd35558SSatoshi Sahara * @param string $eventName (optional) name of the event: HTMLFORM_{$name}_OUTPUT 47112a4e4d1SAndreas Gohr * @return string 47212a4e4d1SAndreas Gohr */ 473*0dd35558SSatoshi Sahara public function toHTML($eventName = null) 4749d01c1d9SSatoshi Sahara { 475de19515fSAndreas Gohr $this->balanceFieldsets(); 476de19515fSAndreas Gohr 477*0dd35558SSatoshi Sahara // trigger event to provide an opportunity to modify this form 478*0dd35558SSatoshi Sahara if (isset($eventName)) { 479*0dd35558SSatoshi Sahara if (!preg_match('/^HTMLFORM_[A-Z]+?_OUTPUT$/', $eventName)) { 480*0dd35558SSatoshi Sahara $eventName = 'HTMLFORM_'.strtoupper($eventName).'_OUTPUT'; 481*0dd35558SSatoshi Sahara } 482*0dd35558SSatoshi Sahara Event::createAndTrigger($eventName, $this, null, false); 483*0dd35558SSatoshi Sahara } 484*0dd35558SSatoshi Sahara 48501e3f2b3SMichael Große $html = '<form '. buildAttributes($this->attrs()) .'>'; 48612a4e4d1SAndreas Gohr 48712a4e4d1SAndreas Gohr foreach ($this->hidden as $name => $value) { 48801e3f2b3SMichael Große $html .= '<input type="hidden" name="'. $name .'" value="'. formText($value) .'" />'; 48912a4e4d1SAndreas Gohr } 49012a4e4d1SAndreas Gohr 49112a4e4d1SAndreas Gohr foreach ($this->elements as $element) { 49201e3f2b3SMichael Große $html .= $element->toHTML(); 49312a4e4d1SAndreas Gohr } 49412a4e4d1SAndreas Gohr 49501e3f2b3SMichael Große $html .= '</form>'; 49612a4e4d1SAndreas Gohr 49712a4e4d1SAndreas Gohr return $html; 49812a4e4d1SAndreas Gohr } 49912a4e4d1SAndreas Gohr} 500