xref: /dokuwiki/inc/Form/Form.php (revision de19515f04567db78bd41d5bff68a88bfb8c2a22)
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    /**
71     * Adds an element to the end of the form
72     *
73     * @param Element $element
74     * @param int $pos 0-based position in the form, -1 for at the end
75     * @return Element
76     */
77    public function addElement(Element $element, $pos = -1) {
78        if(is_a($element, 'Doku_Form2')) throw new \InvalidArgumentException('You can\'t add a form to a form');
79        if($pos < 0) {
80            $this->elements[] = $element;
81        } else {
82            array_splice($this->elements, $pos, 0, array($element));
83        }
84        return $element;
85    }
86
87    /**
88     * Adds a text input field
89     *
90     * @param $name
91     * @param $label
92     * @param int $pos
93     * @return InputElement
94     */
95    public function addTextInput($name, $label = '', $pos = -1) {
96        return $this->addElement(new InputElement('text', $name, $label), $pos);
97    }
98
99    /**
100     * Adds a password input field
101     *
102     * @param $name
103     * @param $label
104     * @param int $pos
105     * @return InputElement
106     */
107    public function addPasswordInput($name, $label = '', $pos = -1) {
108        return $this->addElement(new InputElement('password', $name, $label), $pos);
109    }
110
111    /**
112     * Adds a radio button field
113     *
114     * @param $name
115     * @param $label
116     * @param int $pos
117     * @return CheckableElement
118     */
119    public function addRadioButton($name, $label = '', $pos = -1) {
120        return $this->addElement(new CheckableElement('radio', $name, $label), $pos);
121    }
122
123    /**
124     * Adds a checkbox field
125     *
126     * @param $name
127     * @param $label
128     * @param int $pos
129     * @return CheckableElement
130     */
131    public function addCheckbox($name, $label = '', $pos = -1) {
132        return $this->addElement(new CheckableElement('checkbox', $name, $label), $pos);
133    }
134
135    /**
136     * Adds a textarea field
137     *
138     * @param $name
139     * @param $label
140     * @param int $pos
141     * @return TextareaElement
142     */
143    public function addTextarea($name, $label = '', $pos = -1) {
144        return $this->addElement(new TextareaElement($name, $label), $pos);
145    }
146
147    /**
148     * Add fixed HTML to the form
149     *
150     * @param $html
151     * @param int $pos
152     * @return Element
153     */
154    public function addHTML($html, $pos = -1) {
155        return $this->addElement(new HTMLElement($html), $pos);
156    }
157
158    protected function balanceFieldsets() {
159        //todo implement!
160    }
161
162    /**
163     * The HTML representation of the whole form
164     *
165     * @return string
166     */
167    public function toHTML() {
168        $this->balanceFieldsets();
169
170        $html = '<form ' . buildAttributes($this->attrs()) . '>' . DOKU_LF;
171
172        foreach($this->hidden as $name => $value) {
173            $html .= '<input type="hidden" name="' . $name . '" value="' . formText($value) . '" />' . DOKU_LF;
174        }
175
176        foreach($this->elements as $element) {
177            $html .= $element->toHTML() . DOKU_LF;
178        }
179
180        $html .= '</form>' . DOKU_LF;
181
182        return $html;
183    }
184}
185