PageRenderTime 59ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/simpletest/tag.php

https://github.com/chregu/fluxcms
PHP | 1374 lines | 587 code | 119 blank | 668 comment | 89 complexity | a2e89e8c61b7e8f392597f7ea7e61faa MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Base include file for SimpleTest.
  4. * @package SimpleTest
  5. * @subpackage WebTester
  6. * @version $Id: tag.php,v 1.84 2005/08/07 23:30:06 lastcraft Exp $
  7. */
  8. /**#@+
  9. * include SimpleTest files
  10. */
  11. require_once(dirname(__FILE__) . '/parser.php');
  12. require_once(dirname(__FILE__) . '/encoding.php');
  13. /**#@-*/
  14. /**
  15. * HTML or XML tag.
  16. * @package SimpleTest
  17. * @subpackage WebTester
  18. */
  19. class SimpleTag {
  20. var $_name;
  21. var $_attributes;
  22. var $_content;
  23. /**
  24. * Starts with a named tag with attributes only.
  25. * @param string $name Tag name.
  26. * @param hash $attributes Attribute names and
  27. * string values. Note that
  28. * the keys must have been
  29. * converted to lower case.
  30. */
  31. function SimpleTag($name, $attributes) {
  32. $this->_name = strtolower(trim($name));
  33. $this->_attributes = $attributes;
  34. $this->_content = '';
  35. }
  36. /**
  37. * Check to see if the tag can have both start and
  38. * end tags with content in between.
  39. * @return boolean True if content allowed.
  40. * @access public
  41. */
  42. function expectEndTag() {
  43. return true;
  44. }
  45. /**
  46. * Appends string content to the current content.
  47. * @param string $content Additional text.
  48. * @access public
  49. */
  50. function addContent($content) {
  51. $this->_content .= (string)$content;
  52. }
  53. /**
  54. * Adds an enclosed tag to the content.
  55. * @param SimpleTag $tag New tag.
  56. * @access public
  57. */
  58. function addTag(&$tag) {
  59. }
  60. /**
  61. * Accessor for tag name.
  62. * @return string Name of tag.
  63. * @access public
  64. */
  65. function getTagName() {
  66. return $this->_name;
  67. }
  68. /**
  69. * List of legal child elements.
  70. * @return array List of element names.
  71. * @access public
  72. */
  73. function getChildElements() {
  74. return array();
  75. }
  76. /**
  77. * Accessor for an attribute.
  78. * @param string $label Attribute name.
  79. * @return string Attribute value.
  80. * @access public
  81. */
  82. function getAttribute($label) {
  83. $label = strtolower($label);
  84. if (! isset($this->_attributes[$label])) {
  85. return false;
  86. }
  87. if ($this->_attributes[$label] === '') {
  88. return true;
  89. }
  90. return (string)$this->_attributes[$label];
  91. }
  92. /**
  93. * Sets an attribute.
  94. * @param string $label Attribute name.
  95. * @return string $value New attribute value.
  96. * @access protected
  97. */
  98. function _setAttribute($label, $value) {
  99. $this->_attributes[strtolower($label)] = $value;
  100. }
  101. /**
  102. * Accessor for the whole content so far.
  103. * @return string Content as big raw string.
  104. * @access public
  105. */
  106. function getContent() {
  107. return $this->_content;
  108. }
  109. /**
  110. * Accessor for content reduced to visible text. Acts
  111. * like a text mode browser, normalising space and
  112. * reducing images to their alt text.
  113. * @return string Content as plain text.
  114. * @access public
  115. */
  116. function getText() {
  117. return SimpleSaxParser::normalise($this->_content);
  118. }
  119. /**
  120. * Test to see if id attribute matches.
  121. * @param string $id ID to test against.
  122. * @return boolean True on match.
  123. * @access public
  124. */
  125. function isId($id) {
  126. return ($this->getAttribute('id') == $id);
  127. }
  128. }
  129. /**
  130. * Page title.
  131. * @package SimpleTest
  132. * @subpackage WebTester
  133. */
  134. class SimpleTitleTag extends SimpleTag {
  135. /**
  136. * Starts with a named tag with attributes only.
  137. * @param hash $attributes Attribute names and
  138. * string values.
  139. */
  140. function SimpleTitleTag($attributes) {
  141. $this->SimpleTag('title', $attributes);
  142. }
  143. }
  144. /**
  145. * Link.
  146. * @package SimpleTest
  147. * @subpackage WebTester
  148. */
  149. class SimpleAnchorTag extends SimpleTag {
  150. /**
  151. * Starts with a named tag with attributes only.
  152. * @param hash $attributes Attribute names and
  153. * string values.
  154. */
  155. function SimpleAnchorTag($attributes) {
  156. $this->SimpleTag('a', $attributes);
  157. }
  158. /**
  159. * Accessor for URL as string.
  160. * @return string Coerced as string.
  161. * @access public
  162. */
  163. function getHref() {
  164. $url = $this->getAttribute('href');
  165. if (is_bool($url)) {
  166. $url = '';
  167. }
  168. return $url;
  169. }
  170. }
  171. /**
  172. * Form element.
  173. * @package SimpleTest
  174. * @subpackage WebTester
  175. */
  176. class SimpleWidget extends SimpleTag {
  177. var $_value;
  178. var $_label;
  179. var $_is_set;
  180. /**
  181. * Starts with a named tag with attributes only.
  182. * @param string $name Tag name.
  183. * @param hash $attributes Attribute names and
  184. * string values.
  185. */
  186. function SimpleWidget($name, $attributes) {
  187. $this->SimpleTag($name, $attributes);
  188. $this->_value = false;
  189. $this->_label = false;
  190. $this->_is_set = false;
  191. }
  192. /**
  193. * Accessor for name submitted as the key in
  194. * GET/POST variables hash.
  195. * @return string Parsed value.
  196. * @access public
  197. */
  198. function getName() {
  199. return $this->getAttribute('name');
  200. }
  201. /**
  202. * Accessor for default value parsed with the tag.
  203. * @return string Parsed value.
  204. * @access public
  205. */
  206. function getDefault() {
  207. $default = $this->getAttribute('value');
  208. if ($default === true) {
  209. $default = '';
  210. }
  211. if ($default === false) {
  212. $default = '';
  213. }
  214. return $default;
  215. }
  216. /**
  217. * Accessor for currently set value or default if
  218. * none.
  219. * @return string Value set by form or default
  220. * if none.
  221. * @access public
  222. */
  223. function getValue() {
  224. if (! $this->_is_set) {
  225. return $this->getDefault();
  226. }
  227. return $this->_value;
  228. }
  229. /**
  230. * Sets the current form element value.
  231. * @param string $value New value.
  232. * @return boolean True if allowed.
  233. * @access public
  234. */
  235. function setValue($value) {
  236. $this->_value = $value;
  237. $this->_is_set = true;
  238. return true;
  239. }
  240. /**
  241. * Resets the form element value back to the
  242. * default.
  243. * @access public
  244. */
  245. function resetValue() {
  246. $this->_is_set = false;
  247. }
  248. /**
  249. * Allows setting of a label externally, say by a
  250. * label tag.
  251. * @param string $label Label to attach.
  252. * @access public
  253. */
  254. function setLabel($label) {
  255. $this->_label = trim($label);
  256. }
  257. /**
  258. * Reads external or internal label.
  259. * @param string $label Label to test.
  260. * @return boolean True is match.
  261. * @access public
  262. */
  263. function isLabel($label) {
  264. return $this->_label == trim($label);
  265. }
  266. /**
  267. * Dispatches the value into the form encoded packet.
  268. * @param SimpleEncoding $encoding Form packet.
  269. * @access public
  270. */
  271. function write(&$encoding) {
  272. $encoding->add($this->getName(), $this->getValue());
  273. }
  274. }
  275. /**
  276. * Text, password and hidden field.
  277. * @package SimpleTest
  278. * @subpackage WebTester
  279. */
  280. class SimpleTextTag extends SimpleWidget {
  281. /**
  282. * Starts with a named tag with attributes only.
  283. * @param hash $attributes Attribute names and
  284. * string values.
  285. */
  286. function SimpleTextTag($attributes) {
  287. $this->SimpleWidget('input', $attributes);
  288. if ($this->getAttribute('value') === false) {
  289. $this->_setAttribute('value', '');
  290. }
  291. }
  292. /**
  293. * Tag contains no content.
  294. * @return boolean False.
  295. * @access public
  296. */
  297. function expectEndTag() {
  298. return false;
  299. }
  300. /**
  301. * Sets the current form element value. Cannot
  302. * change the value of a hidden field.
  303. * @param string $value New value.
  304. * @return boolean True if allowed.
  305. * @access public
  306. */
  307. function setValue($value) {
  308. if ($this->getAttribute('type') == 'hidden') {
  309. return false;
  310. }
  311. return parent::setValue($value);
  312. }
  313. }
  314. /**
  315. * Submit button as input tag.
  316. * @package SimpleTest
  317. * @subpackage WebTester
  318. */
  319. class SimpleSubmitTag extends SimpleWidget {
  320. /**
  321. * Starts with a named tag with attributes only.
  322. * @param hash $attributes Attribute names and
  323. * string values.
  324. */
  325. function SimpleSubmitTag($attributes) {
  326. $this->SimpleWidget('input', $attributes);
  327. if ($this->getAttribute('name') === false) {
  328. $this->_setAttribute('name', 'submit');
  329. }
  330. if ($this->getAttribute('value') === false) {
  331. $this->_setAttribute('value', 'Submit');
  332. }
  333. }
  334. /**
  335. * Tag contains no end element.
  336. * @return boolean False.
  337. * @access public
  338. */
  339. function expectEndTag() {
  340. return false;
  341. }
  342. /**
  343. * Disables the setting of the button value.
  344. * @param string $value Ignored.
  345. * @return boolean True if allowed.
  346. * @access public
  347. */
  348. function setValue($value) {
  349. return false;
  350. }
  351. /**
  352. * Value of browser visible text.
  353. * @return string Visible label.
  354. * @access public
  355. */
  356. function getLabel() {
  357. return $this->getValue();
  358. }
  359. /**
  360. * Test for a label match when searching.
  361. * @param string $label Label to test.
  362. * @return boolean True on match.
  363. * @access public
  364. */
  365. function isLabel($label) {
  366. return trim($label) == trim($this->getLabel());
  367. }
  368. /**
  369. * Gets the values submitted as a form.
  370. * @return array Hash of name and values.
  371. * @access public
  372. */
  373. function getSubmitValues() {
  374. return array($this->getName() => $this->getValue());
  375. }
  376. }
  377. /**
  378. * Image button as input tag.
  379. * @package SimpleTest
  380. * @subpackage WebTester
  381. */
  382. class SimpleImageSubmitTag extends SimpleWidget {
  383. /**
  384. * Starts with a named tag with attributes only.
  385. * @param hash $attributes Attribute names and
  386. * string values.
  387. */
  388. function SimpleImageSubmitTag($attributes) {
  389. $this->SimpleWidget('input', $attributes);
  390. }
  391. /**
  392. * Tag contains no end element.
  393. * @return boolean False.
  394. * @access public
  395. */
  396. function expectEndTag() {
  397. return false;
  398. }
  399. /**
  400. * Disables the setting of the button value.
  401. * @param string $value Ignored.
  402. * @return boolean True if allowed.
  403. * @access public
  404. */
  405. function setValue($value) {
  406. return false;
  407. }
  408. /**
  409. * Value of browser visible text.
  410. * @return string Visible label.
  411. * @access public
  412. */
  413. function getLabel() {
  414. if ($this->getAttribute('title')) {
  415. return $this->getAttribute('title');
  416. }
  417. return $this->getAttribute('alt');
  418. }
  419. /**
  420. * Test for a label match when searching.
  421. * @param string $label Label to test.
  422. * @return boolean True on match.
  423. * @access public
  424. */
  425. function isLabel($label) {
  426. return trim($label) == trim($this->getLabel());
  427. }
  428. /**
  429. * Gets the values submitted as a form.
  430. * @return array Hash of name and values.
  431. * @access public
  432. */
  433. function getSubmitValues($x, $y) {
  434. return array(
  435. $this->getName() . '.x' => $x,
  436. $this->getName() . '.y' => $y);
  437. }
  438. }
  439. /**
  440. * Submit button as button tag.
  441. * @package SimpleTest
  442. * @subpackage WebTester
  443. */
  444. class SimpleButtonTag extends SimpleWidget {
  445. /**
  446. * Starts with a named tag with attributes only.
  447. * Defaults are very browser dependent.
  448. * @param hash $attributes Attribute names and
  449. * string values.
  450. */
  451. function SimpleButtonTag($attributes) {
  452. $this->SimpleWidget('button', $attributes);
  453. }
  454. /**
  455. * Check to see if the tag can have both start and
  456. * end tags with content in between.
  457. * @return boolean True if content allowed.
  458. * @access public
  459. */
  460. function expectEndTag() {
  461. return true;
  462. }
  463. /**
  464. * Disables the setting of the button value.
  465. * @param string $value Ignored.
  466. * @return boolean True if allowed.
  467. * @access public
  468. */
  469. function setValue($value) {
  470. return false;
  471. }
  472. /**
  473. * Value of browser visible text.
  474. * @return string Visible label.
  475. * @access public
  476. */
  477. function getLabel() {
  478. return $this->getContent();
  479. }
  480. /**
  481. * Test for a label match when searching.
  482. * @param string $label Label to test.
  483. * @return boolean True on match.
  484. * @access public
  485. */
  486. function isLabel($label) {
  487. return trim($label) == trim($this->getLabel());
  488. }
  489. /**
  490. * Gets the values submitted as a form. Gone
  491. * for the Mozilla defaults values.
  492. * @return array Hash of name and values.
  493. * @access public
  494. */
  495. function getSubmitValues() {
  496. if ($this->getAttribute('name') === false) {
  497. return array();
  498. }
  499. if ($this->getAttribute('value') === false) {
  500. return array($this->getName() => '');
  501. }
  502. return array($this->getName() => $this->getValue());
  503. }
  504. }
  505. /**
  506. * Content tag for text area.
  507. * @package SimpleTest
  508. * @subpackage WebTester
  509. */
  510. class SimpleTextAreaTag extends SimpleWidget {
  511. /**
  512. * Starts with a named tag with attributes only.
  513. * @param hash $attributes Attribute names and
  514. * string values.
  515. */
  516. function SimpleTextAreaTag($attributes) {
  517. $this->SimpleWidget('textarea', $attributes);
  518. }
  519. /**
  520. * Accessor for starting value.
  521. * @return string Parsed value.
  522. * @access public
  523. */
  524. function getDefault() {
  525. if ($this->_wrapIsEnabled()) {
  526. return wordwrap(
  527. $this->getContent(),
  528. (integer)$this->getAttribute('cols'),
  529. "\n");
  530. }
  531. return $this->getContent();
  532. }
  533. /**
  534. * Applies word wrapping if needed.
  535. * @param string $value New value.
  536. * @return boolean True if allowed.
  537. * @access public
  538. */
  539. function setValue($value) {
  540. if ($this->_wrapIsEnabled()) {
  541. $value = wordwrap(
  542. $value,
  543. (integer)$this->getAttribute('cols'),
  544. "\n");
  545. }
  546. return parent::setValue($value);
  547. }
  548. /**
  549. * Test to see if text should be wrapped.
  550. * @return boolean True if wrapping on.
  551. * @access private
  552. */
  553. function _wrapIsEnabled() {
  554. if ($this->getAttribute('cols')) {
  555. $wrap = $this->getAttribute('wrap');
  556. if (($wrap == 'physical') || ($wrap == 'hard')) {
  557. return true;
  558. }
  559. }
  560. return false;
  561. }
  562. }
  563. /**
  564. * File upload widget.
  565. * @package SimpleTest
  566. * @subpackage WebTester
  567. */
  568. class SimpleUploadTag extends SimpleWidget {
  569. /**
  570. * Starts with attributes only.
  571. * @param hash $attributes Attribute names and
  572. * string values.
  573. */
  574. function SimpleUploadTag($attributes) {
  575. $this->SimpleWidget('input', $attributes);
  576. }
  577. /**
  578. * Tag contains no content.
  579. * @return boolean False.
  580. * @access public
  581. */
  582. function expectEndTag() {
  583. return false;
  584. }
  585. /**
  586. * Dispatches the value into the form encoded packet.
  587. * @param SimpleEncoding $encoding Form packet.
  588. * @access public
  589. */
  590. function write(&$encoding) {
  591. if (! file_exists($this->getValue())) {
  592. return;
  593. }
  594. $encoding->attach(
  595. $this->getName(),
  596. implode('', file($this->getValue())),
  597. basename($this->getValue()));
  598. }
  599. }
  600. /**
  601. * Checkbox widget.
  602. * @package SimpleTest
  603. * @subpackage WebTester
  604. */
  605. class SimpleCheckboxTag extends SimpleWidget {
  606. /**
  607. * Starts with attributes only.
  608. * @param hash $attributes Attribute names and
  609. * string values.
  610. */
  611. function SimpleCheckboxTag($attributes) {
  612. $this->SimpleWidget('input', $attributes);
  613. if ($this->getAttribute('value') === false) {
  614. $this->_setAttribute('value', 'on');
  615. }
  616. }
  617. /**
  618. * Tag contains no content.
  619. * @return boolean False.
  620. * @access public
  621. */
  622. function expectEndTag() {
  623. return false;
  624. }
  625. /**
  626. * The only allowed value in the one in the
  627. * "value" attribute. The default for this
  628. * attribute is "on".
  629. * @param string $value New value.
  630. * @return boolean True if allowed.
  631. * @access public
  632. */
  633. function setValue($value) {
  634. if ($value === false) {
  635. return parent::setValue($value);
  636. }
  637. if ($value != $this->getAttribute('value')) {
  638. return false;
  639. }
  640. return parent::setValue($value);
  641. }
  642. /**
  643. * Accessor for starting value. The default
  644. * value is "on".
  645. * @return string Parsed value.
  646. * @access public
  647. */
  648. function getDefault() {
  649. if ($this->getAttribute('checked')) {
  650. return $this->getAttribute('value');
  651. }
  652. return false;
  653. }
  654. }
  655. /**
  656. * Drop down widget.
  657. * @package SimpleTest
  658. * @subpackage WebTester
  659. */
  660. class SimpleSelectionTag extends SimpleWidget {
  661. var $_options;
  662. var $_choice;
  663. /**
  664. * Starts with attributes only.
  665. * @param hash $attributes Attribute names and
  666. * string values.
  667. */
  668. function SimpleSelectionTag($attributes) {
  669. $this->SimpleWidget('select', $attributes);
  670. $this->_options = array();
  671. $this->_choice = false;
  672. }
  673. /**
  674. * Adds an option tag to a selection field.
  675. * @param SimpleOptionTag $tag New option.
  676. * @access public
  677. */
  678. function addTag(&$tag) {
  679. if ($tag->getTagName() == 'option') {
  680. $this->_options[] = &$tag;
  681. }
  682. }
  683. /**
  684. * Text within the selection element is ignored.
  685. * @param string $content Ignored.
  686. * @access public
  687. */
  688. function addContent($content) {
  689. }
  690. /**
  691. * Scans options for defaults. If none, then
  692. * the first option is selected.
  693. * @return string Selected field.
  694. * @access public
  695. */
  696. function getDefault() {
  697. for ($i = 0, $count = count($this->_options); $i < $count; $i++) {
  698. if ($this->_options[$i]->getAttribute('selected')) {
  699. return $this->_options[$i]->getDefault();
  700. }
  701. }
  702. if ($count > 0) {
  703. return $this->_options[0]->getDefault();
  704. }
  705. return '';
  706. }
  707. /**
  708. * Can only set allowed values.
  709. * @param string $value New choice.
  710. * @return boolean True if allowed.
  711. * @access public
  712. */
  713. function setValue($value) {
  714. for ($i = 0, $count = count($this->_options); $i < $count; $i++) {
  715. if ($this->_options[$i]->isValue($value)) {
  716. $this->_choice = $i;
  717. return true;
  718. }
  719. }
  720. return false;
  721. }
  722. /**
  723. * Accessor for current selection value.
  724. * @return string Value attribute or
  725. * content of opton.
  726. * @access public
  727. */
  728. function getValue() {
  729. if ($this->_choice === false) {
  730. return $this->getDefault();
  731. }
  732. return $this->_options[$this->_choice]->getValue();
  733. }
  734. }
  735. /**
  736. * Drop down widget.
  737. * @package SimpleTest
  738. * @subpackage WebTester
  739. */
  740. class MultipleSelectionTag extends SimpleWidget {
  741. var $_options;
  742. var $_values;
  743. /**
  744. * Starts with attributes only.
  745. * @param hash $attributes Attribute names and
  746. * string values.
  747. */
  748. function MultipleSelectionTag($attributes) {
  749. $this->SimpleWidget('select', $attributes);
  750. $this->_options = array();
  751. $this->_values = false;
  752. }
  753. /**
  754. * Adds an option tag to a selection field.
  755. * @param SimpleOptionTag $tag New option.
  756. * @access public
  757. */
  758. function addTag(&$tag) {
  759. if ($tag->getTagName() == 'option') {
  760. $this->_options[] = &$tag;
  761. }
  762. }
  763. /**
  764. * Text within the selection element is ignored.
  765. * @param string $content Ignored.
  766. * @access public
  767. */
  768. function addContent($content) {
  769. }
  770. /**
  771. * Scans options for defaults to populate the
  772. * value array().
  773. * @return array Selected fields.
  774. * @access public
  775. */
  776. function getDefault() {
  777. $default = array();
  778. for ($i = 0, $count = count($this->_options); $i < $count; $i++) {
  779. if ($this->_options[$i]->getAttribute('selected')) {
  780. $default[] = $this->_options[$i]->getDefault();
  781. }
  782. }
  783. return $default;
  784. }
  785. /**
  786. * Can only set allowed values. Any illegal value
  787. * will result in a failure, but all correct values
  788. * will be set.
  789. * @param array $desired New choices.
  790. * @return boolean True if all allowed.
  791. * @access public
  792. */
  793. function setValue($desired) {
  794. $achieved = array();
  795. foreach ($desired as $value) {
  796. $success = false;
  797. for ($i = 0, $count = count($this->_options); $i < $count; $i++) {
  798. if ($this->_options[$i]->isValue($value)) {
  799. $achieved[] = $this->_options[$i]->getValue();
  800. $success = true;
  801. break;
  802. }
  803. }
  804. if (! $success) {
  805. return false;
  806. }
  807. }
  808. $this->_values = $achieved;
  809. return true;
  810. }
  811. /**
  812. * Accessor for current selection value.
  813. * @return array List of currently set options.
  814. * @access public
  815. */
  816. function getValue() {
  817. if ($this->_values === false) {
  818. return $this->getDefault();
  819. }
  820. return $this->_values;
  821. }
  822. }
  823. /**
  824. * Option for selection field.
  825. * @package SimpleTest
  826. * @subpackage WebTester
  827. */
  828. class SimpleOptionTag extends SimpleWidget {
  829. /**
  830. * Stashes the attributes.
  831. */
  832. function SimpleOptionTag($attributes) {
  833. $this->SimpleWidget('option', $attributes);
  834. }
  835. /**
  836. * Does nothing.
  837. * @param string $value Ignored.
  838. * @return boolean Not allowed.
  839. * @access public
  840. */
  841. function setValue($value) {
  842. return false;
  843. }
  844. /**
  845. * Test to see if a value matches the option.
  846. * @param string $compare Value to compare with.
  847. * @return boolean True if possible match.
  848. * @access public
  849. */
  850. function isValue($compare) {
  851. $compare = trim($compare);
  852. if (trim($this->getValue()) == $compare) {
  853. return true;
  854. }
  855. return trim($this->getContent()) == $compare;
  856. }
  857. /**
  858. * Accessor for starting value. Will be set to
  859. * the option label if no value exists.
  860. * @return string Parsed value.
  861. * @access public
  862. */
  863. function getDefault() {
  864. if ($this->getAttribute('value') === false) {
  865. return $this->getContent();
  866. }
  867. return $this->getAttribute('value');
  868. }
  869. }
  870. /**
  871. * Radio button.
  872. * @package SimpleTest
  873. * @subpackage WebTester
  874. */
  875. class SimpleRadioButtonTag extends SimpleWidget {
  876. /**
  877. * Stashes the attributes.
  878. * @param array $attributes Hash of attributes.
  879. */
  880. function SimpleRadioButtonTag($attributes) {
  881. $this->SimpleWidget('input', $attributes);
  882. if ($this->getAttribute('value') === false) {
  883. $this->_setAttribute('value', 'on');
  884. }
  885. }
  886. /**
  887. * Tag contains no content.
  888. * @return boolean False.
  889. * @access public
  890. */
  891. function expectEndTag() {
  892. return false;
  893. }
  894. /**
  895. * The only allowed value in the one in the
  896. * "value" attribute.
  897. * @param string $value New value.
  898. * @return boolean True if allowed.
  899. * @access public
  900. */
  901. function setValue($value) {
  902. if ($value === false) {
  903. return parent::setValue($value);
  904. }
  905. if ($value != $this->getAttribute('value')) {
  906. return false;
  907. }
  908. return parent::setValue($value);
  909. }
  910. /**
  911. * Accessor for starting value.
  912. * @return string Parsed value.
  913. * @access public
  914. */
  915. function getDefault() {
  916. if ($this->getAttribute('checked')) {
  917. return $this->getAttribute('value');
  918. }
  919. return false;
  920. }
  921. }
  922. /**
  923. * A group of multiple widgets with some shared behaviour.
  924. * @package SimpleTest
  925. * @subpackage WebTester
  926. */
  927. class SimpleTagGroup {
  928. var $_widgets = array();
  929. /**
  930. * Adds a tag to the group.
  931. * @param SimpleWidget $widget
  932. * @access public
  933. */
  934. function addWidget(&$widget) {
  935. $this->_widgets[] = &$widget;
  936. }
  937. /**
  938. * Accessor to widget set.
  939. * @return array All widgets.
  940. * @access protected
  941. */
  942. function &_getWidgets() {
  943. return $this->_widgets;
  944. }
  945. /**
  946. * Accessor for an attribute.
  947. * @param string $label Attribute name.
  948. * @return boolean Always false.
  949. * @access public
  950. */
  951. function getAttribute($label) {
  952. return false;
  953. }
  954. /**
  955. * Fetches the name for the widget from the first
  956. * member.
  957. * @return string Name of widget.
  958. * @access public
  959. */
  960. function getName() {
  961. if (count($this->_widgets) > 0) {
  962. return $this->_widgets[0]->getName();
  963. }
  964. }
  965. /**
  966. * Scans the widgets for one with the appropriate
  967. * ID field.
  968. * @param string $id ID value to try.
  969. * @return boolean True if matched.
  970. * @access public
  971. */
  972. function isId($id) {
  973. for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
  974. if ($this->_widgets[$i]->isId($id)) {
  975. return true;
  976. }
  977. }
  978. return false;
  979. }
  980. /**
  981. * Scans the widgets for one with the appropriate
  982. * attached label.
  983. * @param string $label Attached label to try.
  984. * @return boolean True if matched.
  985. * @access public
  986. */
  987. function isLabel($label) {
  988. for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
  989. if ($this->_widgets[$i]->isLabel($label)) {
  990. return true;
  991. }
  992. }
  993. return false;
  994. }
  995. /**
  996. * Dispatches the value into the form encoded packet.
  997. * @param SimpleEncoding $encoding Form packet.
  998. * @access public
  999. */
  1000. function write(&$encoding) {
  1001. $encoding->add($this->getName(), $this->getValue());
  1002. }
  1003. }
  1004. /**
  1005. * A group of tags with the same name within a form.
  1006. * @package SimpleTest
  1007. * @subpackage WebTester
  1008. */
  1009. class SimpleCheckboxGroup extends SimpleTagGroup {
  1010. /**
  1011. * Accessor for current selected widget or false
  1012. * if none.
  1013. * @return string/array Widget values or false if none.
  1014. * @access public
  1015. */
  1016. function getValue() {
  1017. $values = array();
  1018. $widgets = &$this->_getWidgets();
  1019. for ($i = 0, $count = count($widgets); $i < $count; $i++) {
  1020. if ($widgets[$i]->getValue()) {
  1021. $values[] = $widgets[$i]->getValue();
  1022. }
  1023. }
  1024. return $this->_coerceValues($values);
  1025. }
  1026. /**
  1027. * Accessor for starting value that is active.
  1028. * @return string/array Widget values or false if none.
  1029. * @access public
  1030. */
  1031. function getDefault() {
  1032. $values = array();
  1033. $widgets = &$this->_getWidgets();
  1034. for ($i = 0, $count = count($widgets); $i < $count; $i++) {
  1035. if ($widgets[$i]->getDefault()) {
  1036. $values[] = $widgets[$i]->getDefault();
  1037. }
  1038. }
  1039. return $this->_coerceValues($values);
  1040. }
  1041. /**
  1042. * Accessor for current set values.
  1043. * @param string/array/boolean $values Either a single string, a
  1044. * hash or false for nothing set.
  1045. * @return boolean True if all values can be set.
  1046. * @access public
  1047. */
  1048. function setValue($values) {
  1049. $values = $this->_makeArray($values);
  1050. if (! $this->_valuesArePossible($values)) {
  1051. return false;
  1052. }
  1053. $widgets = &$this->_getWidgets();
  1054. for ($i = 0, $count = count($widgets); $i < $count; $i++) {
  1055. $possible = $widgets[$i]->getAttribute('value');
  1056. if (in_array($widgets[$i]->getAttribute('value'), $values)) {
  1057. $widgets[$i]->setValue($possible);
  1058. } else {
  1059. $widgets[$i]->setValue(false);
  1060. }
  1061. }
  1062. return true;
  1063. }
  1064. /**
  1065. * Tests to see if a possible value set is legal.
  1066. * @param string/array/boolean $values Either a single string, a
  1067. * hash or false for nothing set.
  1068. * @return boolean False if trying to set a
  1069. * missing value.
  1070. * @access private
  1071. */
  1072. function _valuesArePossible($values) {
  1073. $matches = array();
  1074. $widgets = &$this->_getWidgets();
  1075. for ($i = 0, $count = count($widgets); $i < $count; $i++) {
  1076. $possible = $widgets[$i]->getAttribute('value');
  1077. if (in_array($possible, $values)) {
  1078. $matches[] = $possible;
  1079. }
  1080. }
  1081. return ($values == $matches);
  1082. }
  1083. /**
  1084. * Converts the output to an appropriate format. This means
  1085. * that no values is false, a single value is just that
  1086. * value and only two or more are contained in an array.
  1087. * @param array $values List of values of widgets.
  1088. * @return string/array/boolean Expected format for a tag.
  1089. * @access private
  1090. */
  1091. function _coerceValues($values) {
  1092. if (count($values) == 0) {
  1093. return false;
  1094. } elseif (count($values) == 1) {
  1095. return $values[0];
  1096. } else {
  1097. return $values;
  1098. }
  1099. }
  1100. /**
  1101. * Converts false or string into array. The opposite of
  1102. * the coercian method.
  1103. * @param string/array/boolean $value A single item is converted
  1104. * to a one item list. False
  1105. * gives an empty list.
  1106. * @return array List of values, possibly empty.
  1107. * @access private
  1108. */
  1109. function _makeArray($value) {
  1110. if ($value === false) {
  1111. return array();
  1112. }
  1113. if (is_string($value)) {
  1114. return array($value);
  1115. }
  1116. return $value;
  1117. }
  1118. }
  1119. /**
  1120. * A group of tags with the same name within a form.
  1121. * Used for radio buttons.
  1122. * @package SimpleTest
  1123. * @subpackage WebTester
  1124. */
  1125. class SimpleRadioGroup extends SimpleTagGroup {
  1126. /**
  1127. * Each tag is tried in turn until one is
  1128. * successfully set. The others will be
  1129. * unchecked if successful.
  1130. * @param string $value New value.
  1131. * @return boolean True if any allowed.
  1132. * @access public
  1133. */
  1134. function setValue($value) {
  1135. if (! $this->_valueIsPossible($value)) {
  1136. return false;
  1137. }
  1138. $index = false;
  1139. $widgets = &$this->_getWidgets();
  1140. for ($i = 0, $count = count($widgets); $i < $count; $i++) {
  1141. if (! $widgets[$i]->setValue($value)) {
  1142. $widgets[$i]->setValue(false);
  1143. }
  1144. }
  1145. return true;
  1146. }
  1147. /**
  1148. * Tests to see if a value is allowed.
  1149. * @param string Attempted value.
  1150. * @return boolean True if a valid value.
  1151. * @access private
  1152. */
  1153. function _valueIsPossible($value) {
  1154. $widgets = &$this->_getWidgets();
  1155. for ($i = 0, $count = count($widgets); $i < $count; $i++) {
  1156. if ($widgets[$i]->getAttribute('value') == $value) {
  1157. return true;
  1158. }
  1159. }
  1160. return false;
  1161. }
  1162. /**
  1163. * Accessor for current selected widget or false
  1164. * if none.
  1165. * @return string/boolean Value attribute or
  1166. * content of opton.
  1167. * @access public
  1168. */
  1169. function getValue() {
  1170. $widgets = &$this->_getWidgets();
  1171. for ($i = 0, $count = count($widgets); $i < $count; $i++) {
  1172. if ($widgets[$i]->getValue()) {
  1173. return $widgets[$i]->getValue();
  1174. }
  1175. }
  1176. return false;
  1177. }
  1178. /**
  1179. * Accessor for starting value that is active.
  1180. * @return string/boolean Value of first checked
  1181. * widget or false if none.
  1182. * @access public
  1183. */
  1184. function getDefault() {
  1185. $widgets = &$this->_getWidgets();
  1186. for ($i = 0, $count = count($widgets); $i < $count; $i++) {
  1187. if ($widgets[$i]->getDefault()) {
  1188. return $widgets[$i]->getDefault();
  1189. }
  1190. }
  1191. return false;
  1192. }
  1193. }
  1194. /**
  1195. * Tag to keep track of labels.
  1196. * @package SimpleTest
  1197. * @subpackage WebTester
  1198. */
  1199. class SimpleLabelTag extends SimpleTag {
  1200. /**
  1201. * Starts with a named tag with attributes only.
  1202. * @param hash $attributes Attribute names and
  1203. * string values.
  1204. */
  1205. function SimpleLabelTag($attributes) {
  1206. $this->SimpleTag('label', $attributes);
  1207. }
  1208. /**
  1209. * Access for the ID to attach the label to.
  1210. * @return string For attribute.
  1211. * @access public
  1212. */
  1213. function getFor() {
  1214. return $this->getAttribute('for');
  1215. }
  1216. }
  1217. /**
  1218. * Tag to aid parsing the form.
  1219. * @package SimpleTest
  1220. * @subpackage WebTester
  1221. */
  1222. class SimpleFormTag extends SimpleTag {
  1223. /**
  1224. * Starts with a named tag with attributes only.
  1225. * @param hash $attributes Attribute names and
  1226. * string values.
  1227. */
  1228. function SimpleFormTag($attributes) {
  1229. $this->SimpleTag('form', $attributes);
  1230. }
  1231. }
  1232. /**
  1233. * Tag to aid parsing the frames in a page.
  1234. * @package SimpleTest
  1235. * @subpackage WebTester
  1236. */
  1237. class SimpleFrameTag extends SimpleTag {
  1238. /**
  1239. * Starts with a named tag with attributes only.
  1240. * @param hash $attributes Attribute names and
  1241. * string values.
  1242. */
  1243. function SimpleFrameTag($attributes) {
  1244. $this->SimpleTag('frame', $attributes);
  1245. }
  1246. /**
  1247. * Tag contains no content.
  1248. * @return boolean False.
  1249. * @access public
  1250. */
  1251. function expectEndTag() {
  1252. return false;
  1253. }
  1254. }
  1255. ?>