Source for file page.php

Documentation is available at page.php

  1. <?php
  2. /**
  3.  *  Base include file for SimpleTest
  4.  *  @package    SimpleTest
  5.  *  @subpackage WebTester
  6.  *  @version    $Id: page.php 1938 2009-08-05 17:16:23Z dgheath $
  7.  */
  8.  
  9. /**#@+
  10.     *   include other SimpleTest class files
  11.     */
  12. require_once(dirname(__FILE__'/http.php');
  13. require_once(dirname(__FILE__'/php_parser.php');
  14. require_once(dirname(__FILE__'/tag.php');
  15. require_once(dirname(__FILE__'/form.php');
  16. require_once(dirname(__FILE__'/selector.php');
  17. /**#@-*/
  18.  
  19. /**
  20.  *    A wrapper for a web page.
  21.  *    @package SimpleTest
  22.  *    @subpackage WebTester
  23.  */
  24. class SimplePage {
  25.     private $links array();
  26.     private $title false;
  27.     private $last_widget;
  28.     private $label;
  29.     private $forms array();
  30.     private $frames array();
  31.     private $transport_error;
  32.     private $raw;
  33.     private $text false;
  34.     private $sent;
  35.     private $headers;
  36.     private $method;
  37.     private $url;
  38.     private $base false;
  39.     private $request_data;
  40.  
  41.     /**
  42.      *    Parses a page ready to access it's contents.
  43.      *    @param SimpleHttpResponse $response     Result of HTTP fetch.
  44.      *    @access public
  45.      */
  46.     function __construct($response false{
  47.         if ($response{
  48.             $this->extractResponse($response);
  49.         else {
  50.             $this->noResponse();
  51.         }
  52.     }
  53.  
  54.     /**
  55.      *    Extracts all of the response information.
  56.      *    @param SimpleHttpResponse $response    Response being parsed.
  57.      *    @access private
  58.      */
  59.     protected function extractResponse($response{
  60.         $this->transport_error $response->getError();
  61.         $this->raw $response->getContent();
  62.         $this->sent $response->getSent();
  63.         $this->headers $response->getHeaders();
  64.         $this->method $response->getMethod();
  65.         $this->url $response->getUrl();
  66.         $this->request_data $response->getRequestData();
  67.     }
  68.  
  69.     /**
  70.      *    Sets up a missing response.
  71.      *    @access private
  72.      */
  73.     protected function noResponse({
  74.         $this->transport_error 'No page fetched yet';
  75.         $this->raw false;
  76.         $this->sent false;
  77.         $this->headers false;
  78.         $this->method 'GET';
  79.         $this->url false;
  80.         $this->request_data false;
  81.     }
  82.  
  83.     /**
  84.      *    Original request as bytes sent down the wire.
  85.      *    @return mixed              Sent content.
  86.      *    @access public
  87.      */
  88.     function getRequest({
  89.         return $this->sent;
  90.     }
  91.  
  92.     /**
  93.      *    Accessor for raw text of page.
  94.      *    @return string        Raw unparsed content.
  95.      *    @access public
  96.      */
  97.     function getRaw({
  98.         return $this->raw;
  99.     }
  100.  
  101.     /**
  102.      *    Accessor for plain text of page as a text browser
  103.      *    would see it.
  104.      *    @return string        Plain text of page.
  105.      *    @access public
  106.      */
  107.     function getText({
  108.         if ($this->text{
  109.             $this->text SimplePage::normalise($this->raw);
  110.         }
  111.         return $this->text;
  112.     }
  113.  
  114.     /**
  115.      *    Accessor for raw headers of page.
  116.      *    @return string       Header block as text.
  117.      *    @access public
  118.      */
  119.     function getHeaders({
  120.         if ($this->headers{
  121.             return $this->headers->getRaw();
  122.         }
  123.         return false;
  124.     }
  125.  
  126.     /**
  127.      *    Original request method.
  128.      *    @return string        GET, POST or HEAD.
  129.      *    @access public
  130.      */
  131.     function getMethod({
  132.         return $this->method;
  133.     }
  134.  
  135.     /**
  136.      *    Original resource name.
  137.      *    @return SimpleUrl        Current url.
  138.      *    @access public
  139.      */
  140.     function getUrl({
  141.         return $this->url;
  142.     }
  143.  
  144.     /**
  145.      *    Base URL if set via BASE tag page url otherwise
  146.      *    @return SimpleUrl        Base url.
  147.      *    @access public
  148.      */
  149.     function getBaseUrl({
  150.         return $this->base;
  151.     }
  152.  
  153.     /**
  154.      *    Original request data.
  155.      *    @return mixed              Sent content.
  156.      *    @access public
  157.      */
  158.     function getRequestData({
  159.         return $this->request_data;
  160.     }
  161.  
  162.     /**
  163.      *    Accessor for last error.
  164.      *    @return string        Error from last response.
  165.      *    @access public
  166.      */
  167.     function getTransportError({
  168.         return $this->transport_error;
  169.     }
  170.  
  171.     /**
  172.      *    Accessor for current MIME type.
  173.      *    @return string    MIME type as string; e.g. 'text/html'
  174.      *    @access public
  175.      */
  176.     function getMimeType({
  177.         if ($this->headers{
  178.             return $this->headers->getMimeType();
  179.         }
  180.         return false;
  181.     }
  182.  
  183.     /**
  184.      *    Accessor for HTTP response code.
  185.      *    @return integer    HTTP response code received.
  186.      *    @access public
  187.      */
  188.     function getResponseCode({
  189.         if ($this->headers{
  190.             return $this->headers->getResponseCode();
  191.         }
  192.         return false;
  193.     }
  194.  
  195.     /**
  196.      *    Accessor for last Authentication type. Only valid
  197.      *    straight after a challenge (401).
  198.      *    @return string    Description of challenge type.
  199.      *    @access public
  200.      */
  201.     function getAuthentication({
  202.         if ($this->headers{
  203.             return $this->headers->getAuthentication();
  204.         }
  205.         return false;
  206.     }
  207.  
  208.     /**
  209.      *    Accessor for last Authentication realm. Only valid
  210.      *    straight after a challenge (401).
  211.      *    @return string    Name of security realm.
  212.      *    @access public
  213.      */
  214.     function getRealm({
  215.         if ($this->headers{
  216.             return $this->headers->getRealm();
  217.         }
  218.         return false;
  219.     }
  220.  
  221.     /**
  222.      *    Accessor for current frame focus. Will be
  223.      *    false as no frames.
  224.      *    @return array    Always empty.
  225.      *    @access public
  226.      */
  227.     function getFrameFocus({
  228.         return array();
  229.     }
  230.  
  231.     /**
  232.      *    Sets the focus by index. The integer index starts from 1.
  233.      *    @param integer $choice    Chosen frame.
  234.      *    @return boolean           Always false.
  235.      *    @access public
  236.      */
  237.     function setFrameFocusByIndex($choice{
  238.         return false;
  239.     }
  240.  
  241.     /**
  242.      *    Sets the focus by name. Always fails for a leaf page.
  243.      *    @param string $name    Chosen frame.
  244.      *    @return boolean        False as no frames.
  245.      *    @access public
  246.      */
  247.     function setFrameFocus($name{
  248.         return false;
  249.     }
  250.  
  251.     /**
  252.      *    Clears the frame focus. Does nothing for a leaf page.
  253.      *    @access public
  254.      */
  255.     function clearFrameFocus({
  256.     }
  257.  
  258.     /**
  259.      *    TODO: write docs
  260.      */
  261.     function setFrames($frames{
  262.         $this->frames $frames;
  263.     }
  264.  
  265.     /**
  266.      *    Test to see if link is an absolute one.
  267.      *    @param string $url     Url to test.
  268.      *    @return boolean        True if absolute.
  269.      *    @access protected
  270.      */
  271.     protected function linkIsAbsolute($url{
  272.         $parsed new SimpleUrl($url);
  273.         return (boolean)($parsed->getScheme(&& $parsed->getHost());
  274.     }
  275.  
  276.     /**
  277.      *    Adds a link to the page.
  278.      *    @param SimpleAnchorTag $tag      Link to accept.
  279.      */
  280.     function addLink($tag{
  281.         $this->links[$tag;
  282.     }
  283.  
  284.     /**
  285.      *    Set the forms
  286.      *    @param array $forms           An array of SimpleForm objects
  287.      */
  288.     function setForms($forms{
  289.         $this->forms $forms;
  290.     }
  291.  
  292.     /**
  293.      *    Test for the presence of a frameset.
  294.      *    @return boolean        True if frameset.
  295.      *    @access public
  296.      */
  297.     function hasFrames({
  298.         return count($this->frames0;
  299.     }
  300.  
  301.     /**
  302.      *    Accessor for frame name and source URL for every frame that
  303.      *    will need to be loaded. Immediate children only.
  304.      *    @return boolean/array     False if no frameset or
  305.      *                               otherwise a hash of frame URLs.
  306.      *                               The key is either a numerical
  307.      *                               base one index or the name attribute.
  308.      *    @access public
  309.      */
  310.     function getFrameset({
  311.         if ($this->hasFrames()) {
  312.             return false;
  313.         }
  314.         $urls array();
  315.         for ($i 0$i count($this->frames)$i++{
  316.             $name $this->frames[$i]->getAttribute('name');
  317.             $url new SimpleUrl($this->frames[$i]->getAttribute('src'));
  318.             $urls[$name $name $i 1$this->expandUrl($url);
  319.         }
  320.         return $urls;
  321.     }
  322.  
  323.     /**
  324.      *    Fetches a list of loaded frames.
  325.      *    @return array/string    Just the URL for a single page.
  326.      *    @access public
  327.      */
  328.     function getFrames({
  329.         $url $this->expandUrl($this->getUrl());
  330.         return $url->asString();
  331.     }
  332.  
  333.     /**
  334.      *    Accessor for a list of all links.
  335.      *    @return array   List of urls with scheme of
  336.      *                     http or https and hostname.
  337.      *    @access public
  338.      */
  339.     function getUrls({
  340.         $all array();
  341.         foreach ($this->links as $link{
  342.             $url $this->getUrlFromLink($link);
  343.             $all[$url->asString();
  344.         }
  345.         return $all;
  346.     }
  347.  
  348.     /**
  349.      *    Accessor for URLs by the link label. Label will match
  350.      *    regardess of whitespace issues and case.
  351.      *    @param string $label    Text of link.
  352.      *    @return array           List of links with that label.
  353.      *    @access public
  354.      */
  355.     function getUrlsByLabel($label{
  356.         $matches array();
  357.         foreach ($this->links as $link{
  358.             if ($link->getText(== $label{
  359.                 $matches[$this->getUrlFromLink($link);
  360.             }
  361.         }
  362.         return $matches;
  363.     }
  364.  
  365.     /**
  366.      *    Accessor for a URL by the id attribute.
  367.      *    @param string $id       Id attribute of link.
  368.      *    @return SimpleUrl       URL with that id of false if none.
  369.      *    @access public
  370.      */
  371.     function getUrlById($id{
  372.         foreach ($this->links as $link{
  373.             if ($link->getAttribute('id'=== (string)$id{
  374.                 return $this->getUrlFromLink($link);
  375.             }
  376.         }
  377.         return false;
  378.     }
  379.  
  380.     /**
  381.      *    Converts a link tag into a target URL.
  382.      *    @param SimpleAnchor $link    Parsed link.
  383.      *    @return SimpleUrl            URL with frame target if any.
  384.      *    @access private
  385.      */
  386.     protected function getUrlFromLink($link{
  387.         $url $this->expandUrl($link->getHref());
  388.         if ($link->getAttribute('target')) {
  389.             $url->setTarget($link->getAttribute('target'));
  390.         }
  391.         return $url;
  392.     }
  393.  
  394.     /**
  395.      *    Expands expandomatic URLs into fully qualified
  396.      *    URLs.
  397.      *    @param SimpleUrl $url        Relative URL.
  398.      *    @return SimpleUrl            Absolute URL.
  399.      *    @access public
  400.      */
  401.     function expandUrl($url{
  402.         if (is_object($url)) {
  403.             $url new SimpleUrl($url);
  404.         }
  405.         $location $this->getBaseUrl($this->getBaseUrl(new SimpleUrl();
  406.         return $url->makeAbsolute($location->makeAbsolute($this->getUrl()));
  407.     }
  408.  
  409.     /**
  410.      *    Sets the base url for the page.
  411.      *    @param string $url    Base URL for page.
  412.      */
  413.     function setBase($url{
  414.         $this->base new SimpleUrl($url);
  415.     }
  416.  
  417.     /**
  418.      *    Sets the title tag contents.
  419.      *    @param SimpleTitleTag $tag    Title of page.
  420.      */
  421.     function setTitle($tag{
  422.         $this->title $tag;
  423.     }
  424.  
  425.     /**
  426.      *    Accessor for parsed title.
  427.      *    @return string     Title or false if no title is present.
  428.      *    @access public
  429.      */
  430.     function getTitle({
  431.         if ($this->title{
  432.             return $this->title->getText();
  433.         }
  434.         return false;
  435.     }
  436.  
  437.     /**
  438.      *    Finds a held form by button label. Will only
  439.      *    search correctly built forms.
  440.      *    @param SimpleSelector $selector       Button finder.
  441.      *    @return SimpleForm                    Form object containing
  442.      *                                           the button.
  443.      *    @access public
  444.      */
  445.     function getFormBySubmit($selector{
  446.         for ($i 0$i count($this->forms)$i++{
  447.             if ($this->forms[$i]->hasSubmit($selector)) {
  448.                 return $this->forms[$i];
  449.             }
  450.         }
  451.         return null;
  452.     }
  453.  
  454.     /**
  455.      *    Finds a held form by image using a selector.
  456.      *    Will only search correctly built forms.
  457.      *    @param SimpleSelector $selector  Image finder.
  458.      *    @return SimpleForm               Form object containing
  459.      *                                      the image.
  460.      *    @access public
  461.      */
  462.     function getFormByImage($selector{
  463.         for ($i 0$i count($this->forms)$i++{
  464.             if ($this->forms[$i]->hasImage($selector)) {
  465.                 return $this->forms[$i];
  466.             }
  467.         }
  468.         return null;
  469.     }
  470.  
  471.     /**
  472.      *    Finds a held form by the form ID. A way of
  473.      *    identifying a specific form when we have control
  474.      *    of the HTML code.
  475.      *    @param string $id     Form label.
  476.      *    @return SimpleForm    Form object containing the matching ID.
  477.      *    @access public
  478.      */
  479.     function getFormById($id{
  480.         for ($i 0$i count($this->forms)$i++{
  481.             if ($this->forms[$i]->getId(== $id{
  482.                 return $this->forms[$i];
  483.             }
  484.         }
  485.         return null;
  486.     }
  487.  
  488.     /**
  489.      *    Sets a field on each form in which the field is
  490.      *    available.
  491.      *    @param SimpleSelector $selector    Field finder.
  492.      *    @param string $value               Value to set field to.
  493.      *    @return boolean                    True if value is valid.
  494.      *    @access public
  495.      */
  496.     function setField($selector$value$position=false{
  497.         $is_set false;
  498.         for ($i 0$i count($this->forms)$i++{
  499.             if ($this->forms[$i]->setField($selector$value$position)) {
  500.                 $is_set true;
  501.             }
  502.         }
  503.         return $is_set;
  504.     }
  505.  
  506.     /**
  507.      *    Accessor for a form element value within a page.
  508.      *    @param SimpleSelector $selector    Field finder.
  509.      *    @return string/boolean             A string if the field is
  510.      *                                        present, false if unchecked
  511.      *                                        and null if missing.
  512.      *    @access public
  513.      */
  514.     function getField($selector{
  515.         for ($i 0$i count($this->forms)$i++{
  516.             $value $this->forms[$i]->getValue($selector);
  517.             if (isset($value)) {
  518.                 return $value;
  519.             }
  520.         }
  521.         return null;
  522.     }
  523.  
  524.     /**
  525.      *    Turns HTML into text browser visible text. Images
  526.      *    are converted to their alt text and tags are supressed.
  527.      *    Entities are converted to their visible representation.
  528.      *    @param string $html        HTML to convert.
  529.      *    @return string             Plain text.
  530.      *    @access public
  531.      */
  532.     static function normalise($html{
  533.         $text preg_replace('#<!--.*?-->#si'''$html);
  534.         $text preg_replace('#<(script|option|textarea)[^>]*>.*?</\1>#si'''$text);
  535.         $text preg_replace('#<img[^>]*alt\s*=\s*("([^"]*)"|\'([^\']*)\'|([a-zA-Z_]+))[^>]*>#'' \2\3\4 '$text);
  536.         $text preg_replace('#<[^>]*>#'''$text);
  537.         $text html_entity_decode($textENT_QUOTES);
  538.         $text preg_replace('#\s+#'' '$text);
  539.         return trim(trim($text)"\xA0");        // TODO: The \xAO is a &nbsp;. Add a test for this.
  540.     }
  541. }
  542. ?>

Documentation generated on Sun, 31 Oct 2010 16:31:54 -0500 by phpDocumentor 1.4.3