3 * Base include file for SimpleTest.
5 * @subpackage WebTester
6 * @version $Id: form.php,v 1.40 2006/01/24 01:11:55 lastcraft Exp $
10 * include SimpleTest files
12 require_once(dirname(__FILE__
) . '/tag.php');
13 require_once(dirname(__FILE__
) . '/encoding.php');
14 require_once(dirname(__FILE__
) . '/selector.php');
18 * Form tag class to hold widget values.
20 * @subpackage WebTester
35 * Starts with no held controls/widgets.
36 * @param SimpleTag $tag Form tag to read.
37 * @param SimpleUrl $url Location of holding page.
39 function SimpleForm($tag, $url) {
40 $this->_method
= $tag->getAttribute('method');
41 $this->_action
= $this->_createAction($tag->getAttribute('action'), $url);
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();
53 * Creates the request packet to be sent by the form.
54 * @param SimpleTag $tag Form tag to read.
55 * @return string Packet class.
58 function _setEncodingClass($tag) {
59 if (strtolower($tag->getAttribute('method')) == 'post') {
60 if (strtolower($tag->getAttribute('enctype')) == 'multipart/form-data') {
61 return 'SimpleMultipartEncoding';
63 return 'SimplePostEncoding';
65 return 'SimpleGetEncoding';
69 * Sets the frame target within a frameset.
70 * @param string $frame Name of frame.
73 function setDefaultTarget($frame) {
74 $this->_default_target
= $frame;
78 * Accessor for method of form submission.
79 * @return string Either get or post.
82 function getMethod() {
83 return ($this->_method ?
strtolower($this->_method
) : 'get');
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.
93 function _createAction($action, $base) {
94 if (($action === '') ||
($action === false)) {
97 $url = new SimpleUrl($action);
98 return $url->makeAbsolute($base);
102 * Absolute URL of the target.
103 * @return SimpleUrl URL target.
106 function getAction() {
107 $url = $this->_action
;
108 if ($this->_default_target
&& ! $url->getTarget()) {
109 $url->setTarget($this->_default_target
);
115 * Creates the encoding for the current values in the
117 * @return SimpleFormEncoding Request to submit.
121 $class = $this->_encoding
;
122 $encoding = new $class();
123 for ($i = 0, $count = count($this->_widgets
); $i < $count; $i++
) {
124 $this->_widgets
[$i]->write($encoding);
130 * ID field of form for unique identification.
131 * @return string Unique tag ID.
139 * Adds a tag contents to the form.
140 * @param SimpleWidget $tag Input tag to add.
143 function addWidget(&$tag) {
144 if (strtolower($tag->getAttribute('type')) == 'submit') {
145 $this->_buttons
[] = &$tag;
146 } elseif (strtolower($tag->getAttribute('type')) == 'image') {
147 $this->_images
[] = &$tag;
148 } elseif ($tag->getName()) {
149 $this->_setWidget($tag);
154 * Sets the widget into the form, grouping radio
156 * @param SimpleWidget $tag Incoming form control.
159 function _setWidget(&$tag) {
160 if (strtolower($tag->getAttribute('type')) == 'radio') {
161 $this->_addRadioButton($tag);
162 } elseif (strtolower($tag->getAttribute('type')) == 'checkbox') {
163 $this->_addCheckbox($tag);
165 $this->_widgets
[] = &$tag;
170 * Adds a radio button, building a group if necessary.
171 * @param SimpleRadioButtonTag $tag Incoming form control.
174 function _addRadioButton(&$tag) {
175 if (! isset($this->_radios
[$tag->getName()])) {
176 $this->_widgets
[] = &new SimpleRadioGroup();
177 $this->_radios
[$tag->getName()] = count($this->_widgets
) - 1;
179 $this->_widgets
[$this->_radios
[$tag->getName()]]->addWidget($tag);
183 * Adds a checkbox, making it a group on a repeated name.
184 * @param SimpleCheckboxTag $tag Incoming form control.
187 function _addCheckbox(&$tag) {
188 if (! isset($this->_checkboxes
[$tag->getName()])) {
189 $this->_widgets
[] = &$tag;
190 $this->_checkboxes
[$tag->getName()] = count($this->_widgets
) - 1;
192 $index = $this->_checkboxes
[$tag->getName()];
193 if (! SimpleTestCompatibility
::isA($this->_widgets
[$index], 'SimpleCheckboxGroup')) {
194 $previous = &$this->_widgets
[$index];
195 $this->_widgets
[$index] = &new SimpleCheckboxGroup();
196 $this->_widgets
[$index]->addWidget($previous);
198 $this->_widgets
[$index]->addWidget($tag);
203 * Extracts current value from form.
204 * @param SimpleSelector $selector Criteria to apply.
205 * @return string/array Value(s) as string or null
209 function getValue($selector) {
210 for ($i = 0, $count = count($this->_widgets
); $i < $count; $i++
) {
211 if ($selector->isMatch($this->_widgets
[$i])) {
212 return $this->_widgets
[$i]->getValue();
215 foreach ($this->_buttons
as $button) {
216 if ($selector->isMatch($button)) {
217 return $button->getValue();
224 * Sets a widget value within the form.
225 * @param SimpleSelector $selector Criteria to apply.
226 * @param string $value Value to input into the widget.
227 * @return boolean True if value is legal, false
228 * otherwise. If the field is not
229 * present, nothing will be set.
232 function setField($selector, $value) {
234 for ($i = 0, $count = count($this->_widgets
); $i < $count; $i++
) {
235 if ($selector->isMatch($this->_widgets
[$i])) {
236 if ($this->_widgets
[$i]->setValue($value)) {
245 * Used by the page object to set widgets labels to
246 * external label tags.
247 * @param SimpleSelector $selector Criteria to apply.
250 function attachLabelBySelector($selector, $label) {
251 for ($i = 0, $count = count($this->_widgets
); $i < $count; $i++
) {
252 if ($selector->isMatch($this->_widgets
[$i])) {
253 if (method_exists($this->_widgets
[$i], 'setLabel')) {
254 $this->_widgets
[$i]->setLabel($label);
262 * Test to see if a form has a submit button.
263 * @param SimpleSelector $selector Criteria to apply.
264 * @return boolean True if present.
267 function hasSubmit($selector) {
268 foreach ($this->_buttons
as $button) {
269 if ($selector->isMatch($button)) {
277 * Test to see if a form has an image control.
278 * @param SimpleSelector $selector Criteria to apply.
279 * @return boolean True if present.
282 function hasImage($selector) {
283 foreach ($this->_images
as $image) {
284 if ($selector->isMatch($image)) {
292 * Gets the submit values for a selected button.
293 * @param SimpleSelector $selector Criteria to apply.
294 * @param hash $additional Additional data for the form.
295 * @return SimpleEncoding Submitted values or false
296 * if there is no such button
300 function submitButton($selector, $additional = false) {
301 $additional = $additional ?
$additional : array();
302 foreach ($this->_buttons
as $button) {
303 if ($selector->isMatch($button)) {
304 $encoding = $this->_encode();
305 $button->write($encoding);
307 $encoding->merge($additional);
316 * Gets the submit values for an image.
317 * @param SimpleSelector $selector Criteria to apply.
318 * @param integer $x X-coordinate of click.
319 * @param integer $y Y-coordinate of click.
320 * @param hash $additional Additional data for the form.
321 * @return SimpleEncoding Submitted values or false
322 * if there is no such button in the
326 function submitImage($selector, $x, $y, $additional = false) {
327 $additional = $additional ?
$additional : array();
328 foreach ($this->_images
as $image) {
329 if ($selector->isMatch($image)) {
330 $encoding = $this->_encode();
331 $image->write($encoding, $x, $y);
333 $encoding->merge($additional);
342 * Simply submits the form without the submit button
343 * value. Used when there is only one button or it
345 * @return hash Submitted values.
349 return $this->_encode();