[ Index ]

PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008]

title

Body

[close]

/lib/simpletestlib/ -> page.php (source)

   1  <?php
   2      /**
   3       *    Base include file for SimpleTest
   4       *    @package    SimpleTest
   5       *    @subpackage    WebTester
   6       *    @version    $Id$
   7       */
   8  
   9      /**#@+
  10       *    include other SimpleTest class files
  11       */
  12      require_once(dirname(__FILE__) . '/http.php');
  13      require_once(dirname(__FILE__) . '/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       *    Creates tags and widgets given HTML tag
  21       *    attributes.
  22       *    @package SimpleTest
  23       *    @subpackage WebTester
  24       */
  25      class SimpleTagBuilder {
  26  
  27          /**
  28           *    Factory for the tag objects. Creates the
  29           *    appropriate tag object for the incoming tag name
  30           *    and attributes.
  31           *    @param string $name        HTML tag name.
  32           *    @param hash $attributes    Element attributes.
  33           *    @return SimpleTag          Tag object.
  34           *    @access public
  35           */
  36          function createTag($name, $attributes) {
  37              static $map = array(
  38                      'a' => 'SimpleAnchorTag',
  39                      'title' => 'SimpleTitleTag',
  40                      'button' => 'SimpleButtonTag',
  41                      'textarea' => 'SimpleTextAreaTag',
  42                      'option' => 'SimpleOptionTag',
  43                      'label' => 'SimpleLabelTag',
  44                      'form' => 'SimpleFormTag',
  45                      'frame' => 'SimpleFrameTag');
  46              $attributes = $this->_keysToLowerCase($attributes);
  47              if (array_key_exists($name, $map)) {
  48                  $tag_class = $map[$name];
  49                  return new $tag_class($attributes);
  50              } elseif ($name == 'select') {
  51                  return $this->_createSelectionTag($attributes);
  52              } elseif ($name == 'input') {
  53                  return $this->_createInputTag($attributes);
  54              }
  55              return new SimpleTag($name, $attributes);
  56          }
  57  
  58          /**
  59           *    Factory for selection fields.
  60           *    @param hash $attributes    Element attributes.
  61           *    @return SimpleTag          Tag object.
  62           *    @access protected
  63           */
  64          function _createSelectionTag($attributes) {
  65              if (isset($attributes['multiple'])) {
  66                  return new MultipleSelectionTag($attributes);
  67              }
  68              return new SimpleSelectionTag($attributes);
  69          }
  70  
  71          /**
  72           *    Factory for input tags.
  73           *    @param hash $attributes    Element attributes.
  74           *    @return SimpleTag          Tag object.
  75           *    @access protected
  76           */
  77          function _createInputTag($attributes) {
  78              if (! isset($attributes['type'])) {
  79                  return new SimpleTextTag($attributes);
  80              }
  81              $type = strtolower(trim($attributes['type']));
  82              $map = array(
  83                      'submit' => 'SimpleSubmitTag',
  84                      'image' => 'SimpleImageSubmitTag',
  85                      'checkbox' => 'SimpleCheckboxTag',
  86                      'radio' => 'SimpleRadioButtonTag',
  87                      'text' => 'SimpleTextTag',
  88                      'hidden' => 'SimpleTextTag',
  89                      'password' => 'SimpleTextTag',
  90                      'file' => 'SimpleUploadTag');
  91              if (array_key_exists($type, $map)) {
  92                  $tag_class = $map[$type];
  93                  return new $tag_class($attributes);
  94              }
  95              return false;
  96          }
  97  
  98          /**
  99           *    Make the keys lower case for case insensitive look-ups.
 100           *    @param hash $map   Hash to convert.
 101           *    @return hash       Unchanged values, but keys lower case.
 102           *    @access private
 103           */
 104          function _keysToLowerCase($map) {
 105              $lower = array();
 106              foreach ($map as $key => $value) {
 107                  $lower[strtolower($key)] = $value;
 108              }
 109              return $lower;
 110          }
 111      }
 112  
 113      /**
 114       *    SAX event handler. Maintains a list of
 115       *    open tags and dispatches them as they close.
 116       *    @package SimpleTest
 117       *    @subpackage WebTester
 118       */
 119      class SimplePageBuilder extends SimpleSaxListener {
 120          var $_tags;
 121          var $_page;
 122          var $_private_content_tag;
 123  
 124          /**
 125           *    Sets the builder up empty.
 126           *    @access public
 127           */
 128          function SimplePageBuilder() {
 129              $this->SimpleSaxListener();
 130          }
 131          
 132          /**
 133           *    Frees up any references so as to allow the PHP garbage
 134           *    collection from unset() to work.
 135           *    @access public
 136           */
 137          function free() {
 138              unset($this->_tags);
 139              unset($this->_page);
 140              unset($this->_private_content_tags);
 141          }
 142  
 143          /**
 144           *    Reads the raw content and send events
 145           *    into the page to be built.
 146           *    @param $response SimpleHttpResponse  Fetched response.
 147           *    @return SimplePage                   Newly parsed page.
 148           *    @access public
 149           */
 150          function &parse($response) {
 151              $this->_tags = array();
 152              $this->_page = &$this->_createPage($response);
 153              $parser = &$this->_createParser($this);
 154              $parser->parse($response->getContent());
 155              $this->_page->acceptPageEnd();
 156              return $this->_page;
 157          }
 158  
 159          /**
 160           *    Creates an empty page.
 161           *    @return SimplePage        New unparsed page.
 162           *    @access protected
 163           */
 164          function &_createPage($response) {
 165              $page = &new SimplePage($response);
 166              return $page;
 167          }
 168  
 169          /**
 170           *    Creates the parser used with the builder.
 171           *    @param $listener SimpleSaxListener   Target of parser.
 172           *    @return SimpleSaxParser              Parser to generate
 173           *                                         events for the builder.
 174           *    @access protected
 175           */
 176          function &_createParser(&$listener) {
 177              $parser = &new SimpleHtmlSaxParser($listener);
 178              return $parser;
 179          }
 180          
 181          /**
 182           *    Start of element event. Opens a new tag.
 183           *    @param string $name         Element name.
 184           *    @param hash $attributes     Attributes without content
 185           *                                are marked as true.
 186           *    @return boolean             False on parse error.
 187           *    @access public
 188           */
 189          function startElement($name, $attributes) {
 190              $factory = &new SimpleTagBuilder();
 191              $tag = $factory->createTag($name, $attributes);
 192              if (! $tag) {
 193                  return true;
 194              }
 195              if ($tag->getTagName() == 'label') {
 196                  $this->_page->acceptLabelStart($tag);
 197                  $this->_openTag($tag);
 198                  return true;
 199              }
 200              if ($tag->getTagName() == 'form') {
 201                  $this->_page->acceptFormStart($tag);
 202                  return true;
 203              }
 204              if ($tag->getTagName() == 'frameset') {
 205                  $this->_page->acceptFramesetStart($tag);
 206                  return true;
 207              }
 208              if ($tag->getTagName() == 'frame') {
 209                  $this->_page->acceptFrame($tag);
 210                  return true;
 211              }
 212              if ($tag->isPrivateContent() && ! isset($this->_private_content_tag)) {
 213                  $this->_private_content_tag = &$tag;
 214              }
 215              if ($tag->expectEndTag()) {
 216                  $this->_openTag($tag);
 217                  return true;
 218              }
 219              $this->_page->acceptTag($tag);
 220              return true;
 221          }
 222  
 223          /**
 224           *    End of element event.
 225           *    @param string $name        Element name.
 226           *    @return boolean            False on parse error.
 227           *    @access public
 228           */
 229          function endElement($name) {
 230              if ($name == 'label') {
 231                  $this->_page->acceptLabelEnd();
 232                  return true;
 233              }
 234              if ($name == 'form') {
 235                  $this->_page->acceptFormEnd();
 236                  return true;
 237              }
 238              if ($name == 'frameset') {
 239                  $this->_page->acceptFramesetEnd();
 240                  return true;
 241              }
 242              if ($this->_hasNamedTagOnOpenTagStack($name)) {
 243                  $tag = array_pop($this->_tags[$name]);
 244                  if ($tag->isPrivateContent() && $this->_private_content_tag->getTagName() == $name) {
 245                      unset($this->_private_content_tag);
 246                  }
 247                  $this->_addContentTagToOpenTags($tag);
 248                  $this->_page->acceptTag($tag);
 249                  return true;
 250              }
 251              return true;
 252          }
 253  
 254          /**
 255           *    Test to see if there are any open tags awaiting
 256           *    closure that match the tag name.
 257           *    @param string $name        Element name.
 258           *    @return boolean            True if any are still open.
 259           *    @access private
 260           */
 261          function _hasNamedTagOnOpenTagStack($name) {
 262              return isset($this->_tags[$name]) && (count($this->_tags[$name]) > 0);
 263          }
 264  
 265          /**
 266           *    Unparsed, but relevant data. The data is added
 267           *    to every open tag.
 268           *    @param string $text        May include unparsed tags.
 269           *    @return boolean            False on parse error.
 270           *    @access public
 271           */
 272          function addContent($text) {
 273              if (isset($this->_private_content_tag)) {
 274                  $this->_private_content_tag->addContent($text);
 275              } else {
 276                  $this->_addContentToAllOpenTags($text);
 277              }
 278              return true;
 279          }
 280  
 281          /**
 282           *    Any content fills all currently open tags unless it
 283           *    is part of an option tag.
 284           *    @param string $text        May include unparsed tags.
 285           *    @access private
 286           */
 287          function _addContentToAllOpenTags($text) {
 288              foreach (array_keys($this->_tags) as $name) {
 289                  for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) {
 290                      $this->_tags[$name][$i]->addContent($text);
 291                  }
 292              }
 293          }
 294  
 295          /**
 296           *    Parsed data in tag form. The parsed tag is added
 297           *    to every open tag. Used for adding options to select
 298           *    fields only.
 299           *    @param SimpleTag $tag        Option tags only.
 300           *    @access private
 301           */
 302          function _addContentTagToOpenTags(&$tag) {
 303              if ($tag->getTagName() != 'option') {
 304                  return;
 305              }
 306              foreach (array_keys($this->_tags) as $name) {
 307                  for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) {
 308                      $this->_tags[$name][$i]->addTag($tag);
 309                  }
 310              }
 311          }
 312  
 313          /**
 314           *    Opens a tag for receiving content. Multiple tags
 315           *    will be receiving input at the same time.
 316           *    @param SimpleTag $tag        New content tag.
 317           *    @access private
 318           */
 319          function _openTag(&$tag) {
 320              $name = $tag->getTagName();
 321              if (! in_array($name, array_keys($this->_tags))) {
 322                  $this->_tags[$name] = array();
 323              }
 324              $this->_tags[$name][] = &$tag;
 325          }
 326      }
 327  
 328      /**
 329       *    A wrapper for a web page.
 330       *    @package SimpleTest
 331       *    @subpackage WebTester
 332       */
 333      class SimplePage {
 334          var $_links;
 335          var $_title;
 336          var $_last_widget;
 337          var $_label;
 338          var $_left_over_labels;
 339          var $_open_forms;
 340          var $_complete_forms;
 341          var $_frameset;
 342          var $_frames;
 343          var $_frameset_nesting_level;
 344          var $_transport_error;
 345          var $_raw;
 346          var $_text;
 347          var $_sent;
 348          var $_headers;
 349          var $_method;
 350          var $_url;
 351          var $_request_data;
 352  
 353          /**
 354           *    Parses a page ready to access it's contents.
 355           *    @param SimpleHttpResponse $response     Result of HTTP fetch.
 356           *    @access public
 357           */
 358          function SimplePage($response = false) {
 359              $this->_links = array();
 360              $this->_title = false;
 361              $this->_left_over_labels = array();
 362              $this->_open_forms = array();
 363              $this->_complete_forms = array();
 364              $this->_frameset = false;
 365              $this->_frames = array();
 366              $this->_frameset_nesting_level = 0;
 367              $this->_text = false;
 368              if ($response) {
 369                  $this->_extractResponse($response);
 370              } else {
 371                  $this->_noResponse();
 372              }
 373          }
 374  
 375          /**
 376           *    Extracts all of the response information.
 377           *    @param SimpleHttpResponse $response    Response being parsed.
 378           *    @access private
 379           */
 380          function _extractResponse($response) {
 381              $this->_transport_error = $response->getError();
 382              $this->_raw = $response->getContent();
 383              $this->_sent = $response->getSent();
 384              $this->_headers = $response->getHeaders();
 385              $this->_method = $response->getMethod();
 386              $this->_url = $response->getUrl();
 387              $this->_request_data = $response->getRequestData();
 388          }
 389  
 390          /**
 391           *    Sets up a missing response.
 392           *    @access private
 393           */
 394          function _noResponse() {
 395              $this->_transport_error = 'No page fetched yet';
 396              $this->_raw = false;
 397              $this->_sent = false;
 398              $this->_headers = false;
 399              $this->_method = 'GET';
 400              $this->_url = false;
 401              $this->_request_data = false;
 402          }
 403  
 404          /**
 405           *    Original request as bytes sent down the wire.
 406           *    @return mixed              Sent content.
 407           *    @access public
 408           */
 409          function getRequest() {
 410              return $this->_sent;
 411          }
 412  
 413          /**
 414           *    Accessor for raw text of page.
 415           *    @return string        Raw unparsed content.
 416           *    @access public
 417           */
 418          function getRaw() {
 419              return $this->_raw;
 420          }
 421  
 422          /**
 423           *    Accessor for plain text of page as a text browser
 424           *    would see it.
 425           *    @return string        Plain text of page.
 426           *    @access public
 427           */
 428          function getText() {
 429              if (! $this->_text) {
 430                  $this->_text = SimpleHtmlSaxParser::normalise($this->_raw);
 431              }
 432              return $this->_text;
 433          }
 434  
 435          /**
 436           *    Accessor for raw headers of page.
 437           *    @return string       Header block as text.
 438           *    @access public
 439           */
 440          function getHeaders() {
 441              if ($this->_headers) {
 442                  return $this->_headers->getRaw();
 443              }
 444              return false;
 445          }
 446  
 447          /**
 448           *    Original request method.
 449           *    @return string        GET, POST or HEAD.
 450           *    @access public
 451           */
 452          function getMethod() {
 453              return $this->_method;
 454          }
 455  
 456          /**
 457           *    Original resource name.
 458           *    @return SimpleUrl        Current url.
 459           *    @access public
 460           */
 461          function getUrl() {
 462              return $this->_url;
 463          }
 464  
 465          /**
 466           *    Original request data.
 467           *    @return mixed              Sent content.
 468           *    @access public
 469           */
 470          function getRequestData() {
 471              return $this->_request_data;
 472          }
 473  
 474          /**
 475           *    Accessor for last error.
 476           *    @return string        Error from last response.
 477           *    @access public
 478           */
 479          function getTransportError() {
 480              return $this->_transport_error;
 481          }
 482  
 483          /**
 484           *    Accessor for current MIME type.
 485           *    @return string    MIME type as string; e.g. 'text/html'
 486           *    @access public
 487           */
 488          function getMimeType() {
 489              if ($this->_headers) {
 490                  return $this->_headers->getMimeType();
 491              }
 492              return false;
 493          }
 494  
 495          /**
 496           *    Accessor for HTTP response code.
 497           *    @return integer    HTTP response code received.
 498           *    @access public
 499           */
 500          function getResponseCode() {
 501              if ($this->_headers) {
 502                  return $this->_headers->getResponseCode();
 503              }
 504              return false;
 505          }
 506  
 507          /**
 508           *    Accessor for last Authentication type. Only valid
 509           *    straight after a challenge (401).
 510           *    @return string    Description of challenge type.
 511           *    @access public
 512           */
 513          function getAuthentication() {
 514              if ($this->_headers) {
 515                  return $this->_headers->getAuthentication();
 516              }
 517              return false;
 518          }
 519  
 520          /**
 521           *    Accessor for last Authentication realm. Only valid
 522           *    straight after a challenge (401).
 523           *    @return string    Name of security realm.
 524           *    @access public
 525           */
 526          function getRealm() {
 527              if ($this->_headers) {
 528                  return $this->_headers->getRealm();
 529              }
 530              return false;
 531          }
 532  
 533          /**
 534           *    Accessor for current frame focus. Will be
 535           *    false as no frames.
 536           *    @return array    Always empty.
 537           *    @access public
 538           */
 539          function getFrameFocus() {
 540              return array();
 541          }
 542  
 543          /**
 544           *    Sets the focus by index. The integer index starts from 1.
 545           *    @param integer $choice    Chosen frame.
 546           *    @return boolean           Always false.
 547           *    @access public
 548           */
 549          function setFrameFocusByIndex($choice) {
 550              return false;
 551          }
 552  
 553          /**
 554           *    Sets the focus by name. Always fails for a leaf page.
 555           *    @param string $name    Chosen frame.
 556           *    @return boolean        False as no frames.
 557           *    @access public
 558           */
 559          function setFrameFocus($name) {
 560              return false;
 561          }
 562  
 563          /**
 564           *    Clears the frame focus. Does nothing for a leaf page.
 565           *    @access public
 566           */
 567          function clearFrameFocus() {
 568          }
 569  
 570          /**
 571           *    Adds a tag to the page.
 572           *    @param SimpleTag $tag        Tag to accept.
 573           *    @access public
 574           */
 575          function acceptTag(&$tag) {
 576              if ($tag->getTagName() == "a") {
 577                  $this->_addLink($tag);
 578              } elseif ($tag->getTagName() == "title") {
 579                  $this->_setTitle($tag);
 580              } elseif ($this->_isFormElement($tag->getTagName())) {
 581                  for ($i = 0; $i < count($this->_open_forms); $i++) {
 582                      $this->_open_forms[$i]->addWidget($tag);
 583                  }
 584                  $this->_last_widget = &$tag;
 585              }
 586          }
 587  
 588          /**
 589           *    Opens a label for a described widget.
 590           *    @param SimpleFormTag $tag      Tag to accept.
 591           *    @access public
 592           */
 593          function acceptLabelStart(&$tag) {
 594              $this->_label = &$tag;
 595              unset($this->_last_widget);
 596          }
 597  
 598          /**
 599           *    Closes the most recently opened label.
 600           *    @access public
 601           */
 602          function acceptLabelEnd() {
 603              if (isset($this->_label)) {
 604                  if (isset($this->_last_widget)) {
 605                      $this->_last_widget->setLabel($this->_label->getText());
 606                      unset($this->_last_widget);
 607                  } else {
 608                      $this->_left_over_labels[] = SimpleTestCompatibility::copy($this->_label);
 609                  }
 610                  unset($this->_label);
 611              }
 612          }
 613  
 614          /**
 615           *    Tests to see if a tag is a possible form
 616           *    element.
 617           *    @param string $name     HTML element name.
 618           *    @return boolean         True if form element.
 619           *    @access private
 620           */
 621          function _isFormElement($name) {
 622              return in_array($name, array('input', 'button', 'textarea', 'select'));
 623          }
 624  
 625          /**
 626           *    Opens a form. New widgets go here.
 627           *    @param SimpleFormTag $tag      Tag to accept.
 628           *    @access public
 629           */
 630          function acceptFormStart(&$tag) {
 631              $this->_open_forms[] = &new SimpleForm($tag, $this->getUrl());
 632          }
 633  
 634          /**
 635           *    Closes the most recently opened form.
 636           *    @access public
 637           */
 638          function acceptFormEnd() {
 639              if (count($this->_open_forms)) {
 640                  $this->_complete_forms[] = array_pop($this->_open_forms);
 641              }
 642          }
 643  
 644          /**
 645           *    Opens a frameset. A frameset may contain nested
 646           *    frameset tags.
 647           *    @param SimpleFramesetTag $tag      Tag to accept.
 648           *    @access public
 649           */
 650          function acceptFramesetStart(&$tag) {
 651              if (! $this->_isLoadingFrames()) {
 652                  $this->_frameset = &$tag;
 653              }
 654              $this->_frameset_nesting_level++;
 655          }
 656  
 657          /**
 658           *    Closes the most recently opened frameset.
 659           *    @access public
 660           */
 661          function acceptFramesetEnd() {
 662              if ($this->_isLoadingFrames()) {
 663                  $this->_frameset_nesting_level--;
 664              }
 665          }
 666  
 667          /**
 668           *    Takes a single frame tag and stashes it in
 669           *    the current frame set.
 670           *    @param SimpleFrameTag $tag      Tag to accept.
 671           *    @access public
 672           */
 673          function acceptFrame(&$tag) {
 674              if ($this->_isLoadingFrames()) {
 675                  if ($tag->getAttribute('src')) {
 676                      $this->_frames[] = &$tag;
 677                  }
 678              }
 679          }
 680  
 681          /**
 682           *    Test to see if in the middle of reading
 683           *    a frameset.
 684           *    @return boolean        True if inframeset.
 685           *    @access private
 686           */
 687          function _isLoadingFrames() {
 688              if (! $this->_frameset) {
 689                  return false;
 690              }
 691              return ($this->_frameset_nesting_level > 0);
 692          }
 693  
 694          /**
 695           *    Test to see if link is an absolute one.
 696           *    @param string $url     Url to test.
 697           *    @return boolean        True if absolute.
 698           *    @access protected
 699           */
 700          function _linkIsAbsolute($url) {
 701              $parsed = new SimpleUrl($url);
 702              return (boolean)($parsed->getScheme() && $parsed->getHost());
 703          }
 704  
 705          /**
 706           *    Adds a link to the page.
 707           *    @param SimpleAnchorTag $tag      Link to accept.
 708           *    @access protected
 709           */
 710          function _addLink($tag) {
 711              $this->_links[] = $tag;
 712          }
 713  
 714          /**
 715           *    Marker for end of complete page. Any work in
 716           *    progress can now be closed.
 717           *    @access public
 718           */
 719          function acceptPageEnd() {
 720              while (count($this->_open_forms)) {
 721                  $this->_complete_forms[] = array_pop($this->_open_forms);
 722              }
 723              foreach ($this->_left_over_labels as $label) {
 724                  for ($i = 0, $count = count($this->_complete_forms); $i < $count; $i++) {
 725                      $this->_complete_forms[$i]->attachLabelBySelector(
 726                              new SimpleById($label->getFor()),
 727                              $label->getText());
 728                  }
 729              }
 730          }
 731  
 732          /**
 733           *    Test for the presence of a frameset.
 734           *    @return boolean        True if frameset.
 735           *    @access public
 736           */
 737          function hasFrames() {
 738              return (boolean)$this->_frameset;
 739          }
 740  
 741          /**
 742           *    Accessor for frame name and source URL for every frame that
 743           *    will need to be loaded. Immediate children only.
 744           *    @return boolean/array     False if no frameset or
 745           *                              otherwise a hash of frame URLs.
 746           *                              The key is either a numerical
 747           *                              base one index or the name attribute.
 748           *    @access public
 749           */
 750          function getFrameset() {
 751              if (! $this->_frameset) {
 752                  return false;
 753              }
 754              $urls = array();
 755              for ($i = 0; $i < count($this->_frames); $i++) {
 756                  $name = $this->_frames[$i]->getAttribute('name');
 757                  $url = new SimpleUrl($this->_frames[$i]->getAttribute('src'));
 758                  $urls[$name ? $name : $i + 1] = $url->makeAbsolute($this->getUrl());
 759              }
 760              return $urls;
 761          }
 762  
 763          /**
 764           *    Fetches a list of loaded frames.
 765           *    @return array/string    Just the URL for a single page.
 766           *    @access public
 767           */
 768          function getFrames() {
 769              $url = $this->getUrl();
 770              return $url->asString();
 771          }
 772  
 773          /**
 774           *    Accessor for a list of all fixed links.
 775           *    @return array   List of urls with scheme of
 776           *                    http or https and hostname.
 777           *    @access public
 778           */
 779          function getAbsoluteUrls() {
 780              $all = array();
 781              foreach ($this->_links as $link) {
 782                  if ($this->_linkIsAbsolute($link->getHref())) {
 783                      $all[] = $link->getHref();
 784                  }
 785              }
 786              return $all;
 787          }
 788  
 789          /**
 790           *    Accessor for a list of all relative links.
 791           *    @return array      List of urls without hostname.
 792           *    @access public
 793           */
 794          function getRelativeUrls() {
 795              $all = array();
 796              foreach ($this->_links as $link) {
 797                  if (! $this->_linkIsAbsolute($link->getHref())) {
 798                      $all[] = $link->getHref();
 799                  }
 800              }
 801              return $all;
 802          }
 803  
 804          /**
 805           *    Accessor for URLs by the link label. Label will match
 806           *    regardess of whitespace issues and case.
 807           *    @param string $label    Text of link.
 808           *    @return array           List of links with that label.
 809           *    @access public
 810           */
 811          function getUrlsByLabel($label) {
 812              $matches = array();
 813              foreach ($this->_links as $link) {
 814                  if ($link->getText() == $label) {
 815                      $matches[] = $this->_getUrlFromLink($link);
 816                  }
 817              }
 818              return $matches;
 819          }
 820  
 821          /**
 822           *    Accessor for a URL by the id attribute.
 823           *    @param string $id       Id attribute of link.
 824           *    @return SimpleUrl       URL with that id of false if none.
 825           *    @access public
 826           */
 827          function getUrlById($id) {
 828              foreach ($this->_links as $link) {
 829                  if ($link->getAttribute('id') === (string)$id) {
 830                      return $this->_getUrlFromLink($link);
 831                  }
 832              }
 833              return false;
 834          }
 835  
 836          /**
 837           *    Converts a link into a target URL.
 838           *    @param SimpleAnchor $link    Parsed link.
 839           *    @return SimpleUrl            URL with frame target if any.
 840           *    @access private
 841           */
 842          function _getUrlFromLink($link) {
 843              $url = $this->_makeAbsolute($link->getHref());
 844              if ($link->getAttribute('target')) {
 845                  $url->setTarget($link->getAttribute('target'));
 846              }
 847              return $url;
 848          }
 849  
 850          /**
 851           *    Expands expandomatic URLs into fully qualified
 852           *    URLs.
 853           *    @param SimpleUrl $url        Relative URL.
 854           *    @return SimpleUrl            Absolute URL.
 855           *    @access protected
 856           */
 857          function _makeAbsolute($url) {
 858              if (! is_object($url)) {
 859                  $url = new SimpleUrl($url);
 860              }
 861              return $url->makeAbsolute($this->getUrl());
 862          }
 863  
 864          /**
 865           *    Sets the title tag contents.
 866           *    @param SimpleTitleTag $tag    Title of page.
 867           *    @access protected
 868           */
 869          function _setTitle(&$tag) {
 870              $this->_title = &$tag;
 871          }
 872  
 873          /**
 874           *    Accessor for parsed title.
 875           *    @return string     Title or false if no title is present.
 876           *    @access public
 877           */
 878          function getTitle() {
 879              if ($this->_title) {
 880                  return $this->_title->getText();
 881              }
 882              return false;
 883          }
 884  
 885          /**
 886           *    Finds a held form by button label. Will only
 887           *    search correctly built forms.
 888           *    @param SimpleSelector $selector       Button finder.
 889           *    @return SimpleForm                    Form object containing
 890           *                                          the button.
 891           *    @access public
 892           */
 893          function &getFormBySubmit($selector) {
 894              for ($i = 0; $i < count($this->_complete_forms); $i++) {
 895                  if ($this->_complete_forms[$i]->hasSubmit($selector)) {
 896                      return $this->_complete_forms[$i];
 897                  }
 898              }
 899              $null = null;
 900              return $null;
 901          }
 902  
 903          /**
 904           *    Finds a held form by image using a selector.
 905           *    Will only search correctly built forms.
 906           *    @param SimpleSelector $selector  Image finder.
 907           *    @return SimpleForm               Form object containing
 908           *                                     the image.
 909           *    @access public
 910           */
 911          function &getFormByImage($selector) {
 912              for ($i = 0; $i < count($this->_complete_forms); $i++) {
 913                  if ($this->_complete_forms[$i]->hasImage($selector)) {
 914                      return $this->_complete_forms[$i];
 915                  }
 916              }
 917              $null = null;
 918              return $null;
 919          }
 920  
 921          /**
 922           *    Finds a held form by the form ID. A way of
 923           *    identifying a specific form when we have control
 924           *    of the HTML code.
 925           *    @param string $id     Form label.
 926           *    @return SimpleForm    Form object containing the matching ID.
 927           *    @access public
 928           */
 929          function &getFormById($id) {
 930              for ($i = 0; $i < count($this->_complete_forms); $i++) {
 931                  if ($this->_complete_forms[$i]->getId() == $id) {
 932                      return $this->_complete_forms[$i];
 933                  }
 934              }
 935              $null = null;
 936              return $null;
 937          }
 938  
 939          /**
 940           *    Sets a field on each form in which the field is
 941           *    available.
 942           *    @param SimpleSelector $selector    Field finder.
 943           *    @param string $value               Value to set field to.
 944           *    @return boolean                    True if value is valid.
 945           *    @access public
 946           */
 947          function setField($selector, $value) {
 948              $is_set = false;
 949              for ($i = 0; $i < count($this->_complete_forms); $i++) {
 950                  if ($this->_complete_forms[$i]->setField($selector, $value)) {
 951                      $is_set = true;
 952                  }
 953              }
 954              return $is_set;
 955          }
 956  
 957          /**
 958           *    Accessor for a form element value within a page.
 959           *    @param SimpleSelector $selector    Field finder.
 960           *    @return string/boolean             A string if the field is
 961           *                                       present, false if unchecked
 962           *                                       and null if missing.
 963           *    @access public
 964           */
 965          function getField($selector) {
 966              for ($i = 0; $i < count($this->_complete_forms); $i++) {
 967                  $value = $this->_complete_forms[$i]->getValue($selector);
 968                  if (isset($value)) {
 969                      return $value;
 970                  }
 971              }
 972              return null;
 973          }
 974      }
 975  ?>


Generated: Wed Jan 14 11:33:29 2009 Cross-referenced by PHPXref 0.7