Completed
Pull Request — 3.6 (#7850)
by Jono
07:19
created

SimpleForm::SimpleForm()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 2
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 *  Base include file for SimpleTest.
4
 *  @package    SimpleTest
5
 *  @subpackage WebTester
6
 *  @version    $Id: form.php 1672 2008-03-02 04:47:34Z edwardzyang $
7
 */
8
    
9
/**#@+
10
 * include SimpleTest files
11
 */
12
require_once(dirname(__FILE__) . '/tag.php');
13
require_once(dirname(__FILE__) . '/encoding.php');
14
require_once(dirname(__FILE__) . '/selector.php');
15
/**#@-*/
16
17
/**
18
 *    Form tag class to hold widget values.
19
 *    @package SimpleTest
20
 *    @subpackage WebTester
21
 */
22
class SimpleForm {
23
    var $_method;
24
    var $_action;
25
    var $_encoding;
26
    var $_default_target;
27
    var $_id;
28
    var $_buttons;
29
    var $_images;
30
    var $_widgets;
31
    var $_radios;
32
    var $_checkboxes;
33
    
34
    /**
35
     *    Starts with no held controls/widgets.
36
     *    @param SimpleTag $tag        Form tag to read.
37
     *    @param SimplePage $page      Holding page.
38
     */
39
    function SimpleForm($tag, &$page) {
40
        $this->_method = $tag->getAttribute('method');
41
        $this->_action = $this->_createAction($tag->getAttribute('action'), $page);
42
        $this->_encoding = $this->_setEncodingClass($tag);
43
        $this->_default_target = false;
44
        $this->_id = $tag->getAttribute('id');
45
        $this->_buttons = array();
46
        $this->_images = array();
47
        $this->_widgets = array();
48
        $this->_radios = array();
49
        $this->_checkboxes = array();
50
    }
51
    
52
    /**
53
     *    Creates the request packet to be sent by the form.
54
     *    @param SimpleTag $tag        Form tag to read.
55
     *    @return string               Packet class.
56
     *    @access private
57
     */
58
    function _setEncodingClass($tag) {
59
        if (strtolower($tag->getAttribute('method')) == 'post') {
60
            if (strtolower($tag->getAttribute('enctype')) == 'multipart/form-data') {
61
                return 'SimpleMultipartEncoding';
62
            }
63
            return 'SimplePostEncoding';
64
        }
65
        return 'SimpleGetEncoding';
66
    }
67
    
68
    /**
69
     *    Sets the frame target within a frameset.
70
     *    @param string $frame        Name of frame.
71
     *    @access public
72
     */
73
    function setDefaultTarget($frame) {
74
        $this->_default_target = $frame;
75
    }
76
    
77
    /**
78
     *    Accessor for method of form submission.
79
     *    @return string           Either get or post.
80
     *    @access public
81
     */
82
    function getMethod() {
83
        return ($this->_method ? strtolower($this->_method) : 'get');
84
    }
85
    
86
    /**
87
     *    Combined action attribute with current location
88
     *    to get an absolute form target.
89
     *    @param string $action    Action attribute from form tag.
90
     *    @param SimpleUrl $base   Page location.
91
     *    @return SimpleUrl        Absolute form target.
92
     */
93
    function _createAction($action, &$page) {
94
        if (($action === '') || ($action === false)) {
95
            return $page->expandUrl($page->getUrl());
96
        }
97
        return $page->expandUrl(new SimpleUrl($action));;
98
    }
99
    
100
    /**
101
     *    Absolute URL of the target.
102
     *    @return SimpleUrl           URL target.
103
     *    @access public
104
     */
105
    function getAction() {
106
        $url = $this->_action;
107
        if ($this->_default_target && ! $url->getTarget()) {
108
            $url->setTarget($this->_default_target);
109
        }
110
        return $url;
111
    }
112
    
113
    /**
114
     *    Creates the encoding for the current values in the
115
     *    form.
116
     *    @return SimpleFormEncoding    Request to submit.
117
     *    @access private
118
     */
119
    function _encode() {
120
        $class = $this->_encoding;
121
        $encoding = new $class();
122
        for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
123
            $this->_widgets[$i]->write($encoding, 0, 0);
124
        }
125
        return $encoding;
126
    }
127
            
128
    /**
129
     *    ID field of form for unique identification.
130
     *    @return string           Unique tag ID.
131
     *    @access public
132
     */
133
    function getId() {
134
        return $this->_id;
135
    }
136
    
137
    /**
138
     *    Adds a tag contents to the form.
139
     *    @param SimpleWidget $tag        Input tag to add.
140
     *    @access public
141
     */
142
    function addWidget(&$tag) {
143
        if (strtolower($tag->getAttribute('type')) == 'submit') {
144
            $this->_buttons[] = &$tag;
145
        } elseif (strtolower($tag->getAttribute('type')) == 'image') {
146
            $this->_images[] = &$tag;
147
        } elseif ($tag->getName()) {
148
            $this->_setWidget($tag);
149
        }
150
    }
151
    
152
    /**
153
     *    Sets the widget into the form, grouping radio
154
     *    buttons if any.
155
     *    @param SimpleWidget $tag   Incoming form control.
156
     *    @access private
157
     */
158
    function _setWidget(&$tag) {
159
        if (strtolower($tag->getAttribute('type')) == 'radio') {
160
            $this->_addRadioButton($tag);
161
        } elseif (strtolower($tag->getAttribute('type')) == 'checkbox') {
162
            $this->_addCheckbox($tag);
163
        } else {
164
            $this->_widgets[] = &$tag;
165
        }
166
    }
167
    
168
    /**
169
     *    Adds a radio button, building a group if necessary.
170
     *    @param SimpleRadioButtonTag $tag   Incoming form control.
171
     *    @access private
172
     */
173
    function _addRadioButton(&$tag) {
174
        if (! isset($this->_radios[$tag->getName()])) {
175
            $this->_widgets[] = new SimpleRadioGroup();
176
            $this->_radios[$tag->getName()] = count($this->_widgets) - 1;
177
        }
178
        $this->_widgets[$this->_radios[$tag->getName()]]->addWidget($tag);
179
    }
180
    
181
    /**
182
     *    Adds a checkbox, making it a group on a repeated name.
183
     *    @param SimpleCheckboxTag $tag   Incoming form control.
184
     *    @access private
185
     */
186
    function _addCheckbox(&$tag) {
187
        if (! isset($this->_checkboxes[$tag->getName()])) {
188
            $this->_widgets[] = &$tag;
189
            $this->_checkboxes[$tag->getName()] = count($this->_widgets) - 1;
190
        } else {
191
            $index = $this->_checkboxes[$tag->getName()];
192
            if (! SimpleTestCompatibility::isA($this->_widgets[$index], 'SimpleCheckboxGroup')) {
193
                $previous = &$this->_widgets[$index];
194
                $this->_widgets[$index] = new SimpleCheckboxGroup();
195
                $this->_widgets[$index]->addWidget($previous);
196
            }
197
            $this->_widgets[$index]->addWidget($tag);
198
        }
199
    }
200
    
201
    /**
202
     *    Extracts current value from form.
203
     *    @param SimpleSelector $selector   Criteria to apply.
204
     *    @return string/array              Value(s) as string or null
205
     *                                      if not set.
206
     *    @access public
207
     */
208
    function getValue($selector) {
209
        for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
210
            if ($selector->isMatch($this->_widgets[$i])) {
211
                return $this->_widgets[$i]->getValue();
212
            }
213
        }
214
        foreach ($this->_buttons as $button) {
215
            if ($selector->isMatch($button)) {
216
                return $button->getValue();
217
            }
218
        }
219
        return null;
220
    }
221
    
222
    /**
223
     *    Sets a widget value within the form.
224
     *    @param SimpleSelector $selector   Criteria to apply.
225
     *    @param string $value              Value to input into the widget.
226
     *    @return boolean                   True if value is legal, false
227
     *                                      otherwise. If the field is not
228
     *                                      present, nothing will be set.
229
     *    @access public
230
     */
231
    function setField($selector, $value, $position=false) {
232
        $success = false;
233
        $_position = 0;
234
        for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
235
            if ($selector->isMatch($this->_widgets[$i])) {
236
                $_position++;
237
                if ($position === false or $_position === (int)$position) {
238
                    if ($this->_widgets[$i]->setValue($value)) {
239
                        $success = true;
240
                    }
241
                }
242
            }
243
        }
244
        return $success;
245
    }
246
    
247
    /**
248
     *    Used by the page object to set widgets labels to
249
     *    external label tags.
250
     *    @param SimpleSelector $selector   Criteria to apply.
251
     *    @access public
252
     */
253
    function attachLabelBySelector($selector, $label) {
254
        for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
255
            if ($selector->isMatch($this->_widgets[$i])) {
256
                if (method_exists($this->_widgets[$i], 'setLabel')) {
257
                    $this->_widgets[$i]->setLabel($label);
258
                    return;
259
                }
260
            }
261
        }
262
    }
263
    
264
    /**
265
     *    Test to see if a form has a submit button.
266
     *    @param SimpleSelector $selector   Criteria to apply.
267
     *    @return boolean                   True if present.
268
     *    @access public
269
     */
270
    function hasSubmit($selector) {
271
        foreach ($this->_buttons as $button) {
272
            if ($selector->isMatch($button)) {
273
                return true;
274
            }
275
        }
276
        return false;
277
    }
278
    
279
    /**
280
     *    Test to see if a form has an image control.
281
     *    @param SimpleSelector $selector   Criteria to apply.
282
     *    @return boolean                   True if present.
283
     *    @access public
284
     */
285
    function hasImage($selector) {
286
        foreach ($this->_images as $image) {
287
            if ($selector->isMatch($image)) {
288
                return true;
289
            }
290
        }
291
        return false;
292
    }
293
    
294
    /**
295
     *    Gets the submit values for a selected button.
296
     *    @param SimpleSelector $selector   Criteria to apply.
297
     *    @param hash $additional           Additional data for the form.
298
     *    @return SimpleEncoding            Submitted values or false
299
     *                                      if there is no such button
300
     *                                      in the form.
301
     *    @access public
302
     */
303
    function submitButton($selector, $additional = false) {
304
        $additional = $additional ? $additional : array();
305
        foreach ($this->_buttons as $button) {
306
            if ($selector->isMatch($button)) {
307
                $encoding = $this->_encode();
308
                $button->write($encoding, 0, 0);
309
                if ($additional) {
310
                    $encoding->merge($additional);
311
                }
312
                return $encoding;           
313
            }
314
        }
315
        return false;
316
    }
317
        
318
    /**
319
     *    Gets the submit values for an image.
320
     *    @param SimpleSelector $selector   Criteria to apply.
321
     *    @param integer $x                 X-coordinate of click.
322
     *    @param integer $y                 Y-coordinate of click.
323
     *    @param hash $additional           Additional data for the form.
324
     *    @return SimpleEncoding            Submitted values or false
325
     *                                      if there is no such button in the
326
     *                                      form.
327
     *    @access public
328
     */
329
    function submitImage($selector, $x, $y, $additional = false) {
330
        $additional = $additional ? $additional : array();
331
        foreach ($this->_images as $image) {
332
            if ($selector->isMatch($image)) {
333
                $encoding = $this->_encode();
334
                $image->write($encoding, $x, $y);
335
                if ($additional) {
336
                    $encoding->merge($additional);
337
                }
338
                return $encoding;           
339
            }
340
        }
341
        return false;
342
    }
343
    
344
    /**
345
     *    Simply submits the form without the submit button
346
     *    value. Used when there is only one button or it
347
     *    is unimportant.
348
     *    @return hash           Submitted values.
349
     *    @access public
350
     */
351
    function submit() {
352
        return $this->_encode();
353
    }
354
}
355
?>
356