Source for file tag.php

Documentation is available at tag.php

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

Documentation generated on Sun, 04 May 2008 09:22:14 -0500 by phpDocumentor 1.3.0