|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00012 require_once(dirname(__FILE__) . '/http.php'); 00013 require_once(dirname(__FILE__) . '/parser.php'); 00014 require_once(dirname(__FILE__) . '/tag.php'); 00015 require_once(dirname(__FILE__) . '/form.php'); 00016 require_once(dirname(__FILE__) . '/selector.php'); 00025 class SimpleTagBuilder { 00026 00036 function createTag($name, $attributes) { 00037 static $map = array( 00038 'a' => 'SimpleAnchorTag', 00039 'title' => 'SimpleTitleTag', 00040 'base' => 'SimpleBaseTag', 00041 'button' => 'SimpleButtonTag', 00042 'textarea' => 'SimpleTextAreaTag', 00043 'option' => 'SimpleOptionTag', 00044 'label' => 'SimpleLabelTag', 00045 'form' => 'SimpleFormTag', 00046 'frame' => 'SimpleFrameTag'); 00047 $attributes = $this->_keysToLowerCase($attributes); 00048 if (array_key_exists($name, $map)) { 00049 $tag_class = $map[$name]; 00050 return new $tag_class($attributes); 00051 } elseif ($name == 'select') { 00052 return $this->_createSelectionTag($attributes); 00053 } elseif ($name == 'input') { 00054 return $this->_createInputTag($attributes); 00055 } 00056 return new SimpleTag($name, $attributes); 00057 } 00058 00065 function _createSelectionTag($attributes) { 00066 if (isset($attributes['multiple'])) { 00067 return new MultipleSelectionTag($attributes); 00068 } 00069 return new SimpleSelectionTag($attributes); 00070 } 00071 00078 function _createInputTag($attributes) { 00079 if (! isset($attributes['type'])) { 00080 return new SimpleTextTag($attributes); 00081 } 00082 $type = strtolower(trim($attributes['type'])); 00083 $map = array( 00084 'submit' => 'SimpleSubmitTag', 00085 'image' => 'SimpleImageSubmitTag', 00086 'checkbox' => 'SimpleCheckboxTag', 00087 'radio' => 'SimpleRadioButtonTag', 00088 'text' => 'SimpleTextTag', 00089 'hidden' => 'SimpleTextTag', 00090 'password' => 'SimpleTextTag', 00091 'file' => 'SimpleUploadTag'); 00092 if (array_key_exists($type, $map)) { 00093 $tag_class = $map[$type]; 00094 return new $tag_class($attributes); 00095 } 00096 return false; 00097 } 00098 00105 function _keysToLowerCase($map) { 00106 $lower = array(); 00107 foreach ($map as $key => $value) { 00108 $lower[strtolower($key)] = $value; 00109 } 00110 return $lower; 00111 } 00112 } 00113 00120 class SimplePageBuilder extends SimpleSaxListener { 00121 var $_tags; 00122 var $_page; 00123 var $_private_content_tag; 00124 00129 function SimplePageBuilder() { 00130 $this->SimpleSaxListener(); 00131 } 00132 00138 function free() { 00139 unset($this->_tags); 00140 unset($this->_page); 00141 unset($this->_private_content_tags); 00142 } 00143 00151 function &parse($response) { 00152 $this->_tags = array(); 00153 $this->_page = &$this->_createPage($response); 00154 $parser = &$this->_createParser($this); 00155 $parser->parse($response->getContent()); 00156 $this->_page->acceptPageEnd(); 00157 return $this->_page; 00158 } 00159 00165 function &_createPage($response) { 00166 $page = new SimplePage($response); 00167 return $page; 00168 } 00169 00177 function &_createParser(&$listener) { 00178 $parser = new SimpleHtmlSaxParser($listener); 00179 return $parser; 00180 } 00181 00190 function startElement($name, $attributes) { 00191 $factory = new SimpleTagBuilder(); 00192 $tag = $factory->createTag($name, $attributes); 00193 if (! $tag) { 00194 return true; 00195 } 00196 if ($tag->getTagName() == 'label') { 00197 $this->_page->acceptLabelStart($tag); 00198 $this->_openTag($tag); 00199 return true; 00200 } 00201 if ($tag->getTagName() == 'form') { 00202 $this->_page->acceptFormStart($tag); 00203 return true; 00204 } 00205 if ($tag->getTagName() == 'frameset') { 00206 $this->_page->acceptFramesetStart($tag); 00207 return true; 00208 } 00209 if ($tag->getTagName() == 'frame') { 00210 $this->_page->acceptFrame($tag); 00211 return true; 00212 } 00213 if ($tag->isPrivateContent() && ! isset($this->_private_content_tag)) { 00214 $this->_private_content_tag = &$tag; 00215 } 00216 if ($tag->expectEndTag()) { 00217 $this->_openTag($tag); 00218 return true; 00219 } 00220 $this->_page->acceptTag($tag); 00221 return true; 00222 } 00223 00230 function endElement($name) { 00231 if ($name == 'label') { 00232 $this->_page->acceptLabelEnd(); 00233 return true; 00234 } 00235 if ($name == 'form') { 00236 $this->_page->acceptFormEnd(); 00237 return true; 00238 } 00239 if ($name == 'frameset') { 00240 $this->_page->acceptFramesetEnd(); 00241 return true; 00242 } 00243 if ($this->_hasNamedTagOnOpenTagStack($name)) { 00244 $tag = array_pop($this->_tags[$name]); 00245 if ($tag->isPrivateContent() && $this->_private_content_tag->getTagName() == $name) { 00246 unset($this->_private_content_tag); 00247 } 00248 $this->_addContentTagToOpenTags($tag); 00249 $this->_page->acceptTag($tag); 00250 return true; 00251 } 00252 return true; 00253 } 00254 00262 function _hasNamedTagOnOpenTagStack($name) { 00263 return isset($this->_tags[$name]) && (count($this->_tags[$name]) > 0); 00264 } 00265 00273 function addContent($text) { 00274 if (isset($this->_private_content_tag)) { 00275 $this->_private_content_tag->addContent($text); 00276 } else { 00277 $this->_addContentToAllOpenTags($text); 00278 } 00279 return true; 00280 } 00281 00288 function _addContentToAllOpenTags($text) { 00289 foreach (array_keys($this->_tags) as $name) { 00290 for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) { 00291 $this->_tags[$name][$i]->addContent($text); 00292 } 00293 } 00294 } 00295 00303 function _addContentTagToOpenTags(&$tag) { 00304 if ($tag->getTagName() != 'option') { 00305 return; 00306 } 00307 foreach (array_keys($this->_tags) as $name) { 00308 for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) { 00309 $this->_tags[$name][$i]->addTag($tag); 00310 } 00311 } 00312 } 00313 00320 function _openTag(&$tag) { 00321 $name = $tag->getTagName(); 00322 if (! in_array($name, array_keys($this->_tags))) { 00323 $this->_tags[$name] = array(); 00324 } 00325 $this->_tags[$name][] = &$tag; 00326 } 00327 } 00328 00334 class SimplePage { 00335 var $_links; 00336 var $_title; 00337 var $_last_widget; 00338 var $_label; 00339 var $_left_over_labels; 00340 var $_open_forms; 00341 var $_complete_forms; 00342 var $_frameset; 00343 var $_frames; 00344 var $_frameset_nesting_level; 00345 var $_transport_error; 00346 var $_raw; 00347 var $_text; 00348 var $_sent; 00349 var $_headers; 00350 var $_method; 00351 var $_url; 00352 var $_base = false; 00353 var $_request_data; 00354 00360 function SimplePage($response = false) { 00361 $this->_links = array(); 00362 $this->_title = false; 00363 $this->_left_over_labels = array(); 00364 $this->_open_forms = array(); 00365 $this->_complete_forms = array(); 00366 $this->_frameset = false; 00367 $this->_frames = array(); 00368 $this->_frameset_nesting_level = 0; 00369 $this->_text = false; 00370 if ($response) { 00371 $this->_extractResponse($response); 00372 } else { 00373 $this->_noResponse(); 00374 } 00375 } 00376 00382 function _extractResponse($response) { 00383 $this->_transport_error = $response->getError(); 00384 $this->_raw = $response->getContent(); 00385 $this->_sent = $response->getSent(); 00386 $this->_headers = $response->getHeaders(); 00387 $this->_method = $response->getMethod(); 00388 $this->_url = $response->getUrl(); 00389 $this->_request_data = $response->getRequestData(); 00390 } 00391 00396 function _noResponse() { 00397 $this->_transport_error = 'No page fetched yet'; 00398 $this->_raw = false; 00399 $this->_sent = false; 00400 $this->_headers = false; 00401 $this->_method = 'GET'; 00402 $this->_url = false; 00403 $this->_request_data = false; 00404 } 00405 00411 function getRequest() { 00412 return $this->_sent; 00413 } 00414 00420 function getRaw() { 00421 return $this->_raw; 00422 } 00423 00430 function getText() { 00431 if (! $this->_text) { 00432 $this->_text = SimpleHtmlSaxParser::normalise($this->_raw); 00433 } 00434 return $this->_text; 00435 } 00436 00442 function getHeaders() { 00443 if ($this->_headers) { 00444 return $this->_headers->getRaw(); 00445 } 00446 return false; 00447 } 00448 00454 function getMethod() { 00455 return $this->_method; 00456 } 00457 00463 function getUrl() { 00464 return $this->_url; 00465 } 00466 00472 function getBaseUrl() { 00473 return $this->_base; 00474 } 00475 00481 function getRequestData() { 00482 return $this->_request_data; 00483 } 00484 00490 function getTransportError() { 00491 return $this->_transport_error; 00492 } 00493 00499 function getMimeType() { 00500 if ($this->_headers) { 00501 return $this->_headers->getMimeType(); 00502 } 00503 return false; 00504 } 00505 00511 function getResponseCode() { 00512 if ($this->_headers) { 00513 return $this->_headers->getResponseCode(); 00514 } 00515 return false; 00516 } 00517 00524 function getAuthentication() { 00525 if ($this->_headers) { 00526 return $this->_headers->getAuthentication(); 00527 } 00528 return false; 00529 } 00530 00537 function getRealm() { 00538 if ($this->_headers) { 00539 return $this->_headers->getRealm(); 00540 } 00541 return false; 00542 } 00543 00550 function getFrameFocus() { 00551 return array(); 00552 } 00553 00560 function setFrameFocusByIndex($choice) { 00561 return false; 00562 } 00563 00570 function setFrameFocus($name) { 00571 return false; 00572 } 00573 00578 function clearFrameFocus() { 00579 } 00580 00586 function acceptTag(&$tag) { 00587 if ($tag->getTagName() == "a") { 00588 $this->_addLink($tag); 00589 } elseif ($tag->getTagName() == "base") { 00590 $this->_setBase($tag); 00591 } elseif ($tag->getTagName() == "title") { 00592 $this->_setTitle($tag); 00593 } elseif ($this->_isFormElement($tag->getTagName())) { 00594 for ($i = 0; $i < count($this->_open_forms); $i++) { 00595 $this->_open_forms[$i]->addWidget($tag); 00596 } 00597 $this->_last_widget = &$tag; 00598 } 00599 } 00600 00606 function acceptLabelStart(&$tag) { 00607 $this->_label = &$tag; 00608 unset($this->_last_widget); 00609 } 00610 00615 function acceptLabelEnd() { 00616 if (isset($this->_label)) { 00617 if (isset($this->_last_widget)) { 00618 $this->_last_widget->setLabel($this->_label->getText()); 00619 unset($this->_last_widget); 00620 } else { 00621 $this->_left_over_labels[] = SimpleTestCompatibility::copy($this->_label); 00622 } 00623 unset($this->_label); 00624 } 00625 } 00626 00634 function _isFormElement($name) { 00635 return in_array($name, array('input', 'button', 'textarea', 'select')); 00636 } 00637 00643 function acceptFormStart(&$tag) { 00644 $this->_open_forms[] = new SimpleForm($tag, $this); 00645 } 00646 00651 function acceptFormEnd() { 00652 if (count($this->_open_forms)) { 00653 $this->_complete_forms[] = array_pop($this->_open_forms); 00654 } 00655 } 00656 00663 function acceptFramesetStart(&$tag) { 00664 if (! $this->_isLoadingFrames()) { 00665 $this->_frameset = &$tag; 00666 } 00667 $this->_frameset_nesting_level++; 00668 } 00669 00674 function acceptFramesetEnd() { 00675 if ($this->_isLoadingFrames()) { 00676 $this->_frameset_nesting_level--; 00677 } 00678 } 00679 00686 function acceptFrame(&$tag) { 00687 if ($this->_isLoadingFrames()) { 00688 if ($tag->getAttribute('src')) { 00689 $this->_frames[] = &$tag; 00690 } 00691 } 00692 } 00693 00700 function _isLoadingFrames() { 00701 if (! $this->_frameset) { 00702 return false; 00703 } 00704 return ($this->_frameset_nesting_level > 0); 00705 } 00706 00713 function _linkIsAbsolute($url) { 00714 $parsed = new SimpleUrl($url); 00715 return (boolean)($parsed->getScheme() && $parsed->getHost()); 00716 } 00717 00723 function _addLink($tag) { 00724 $this->_links[] = $tag; 00725 } 00726 00732 function acceptPageEnd() { 00733 while (count($this->_open_forms)) { 00734 $this->_complete_forms[] = array_pop($this->_open_forms); 00735 } 00736 foreach ($this->_left_over_labels as $label) { 00737 for ($i = 0, $count = count($this->_complete_forms); $i < $count; $i++) { 00738 $this->_complete_forms[$i]->attachLabelBySelector( 00739 new SimpleById($label->getFor()), 00740 $label->getText()); 00741 } 00742 } 00743 } 00744 00750 function hasFrames() { 00751 return (boolean)$this->_frameset; 00752 } 00753 00763 function getFrameset() { 00764 if (! $this->_frameset) { 00765 return false; 00766 } 00767 $urls = array(); 00768 for ($i = 0; $i < count($this->_frames); $i++) { 00769 $name = $this->_frames[$i]->getAttribute('name'); 00770 $url = new SimpleUrl($this->_frames[$i]->getAttribute('src')); 00771 $urls[$name ? $name : $i + 1] = $this->expandUrl($url); 00772 } 00773 return $urls; 00774 } 00775 00781 function getFrames() { 00782 $url = $this->expandUrl($this->getUrl()); 00783 return $url->asString(); 00784 } 00785 00792 function getUrls() { 00793 $all = array(); 00794 foreach ($this->_links as $link) { 00795 $url = $this->_getUrlFromLink($link); 00796 $all[] = $url->asString(); 00797 } 00798 return $all; 00799 } 00800 00808 function getUrlsByLabel($label) { 00809 $matches = array(); 00810 foreach ($this->_links as $link) { 00811 if ($link->getText() == $label) { 00812 $matches[] = $this->_getUrlFromLink($link); 00813 } 00814 } 00815 return $matches; 00816 } 00817 00824 function getUrlById($id) { 00825 foreach ($this->_links as $link) { 00826 if ($link->getAttribute('id') === (string)$id) { 00827 return $this->_getUrlFromLink($link); 00828 } 00829 } 00830 return false; 00831 } 00832 00839 function _getUrlFromLink($link) { 00840 $url = $this->expandUrl($link->getHref()); 00841 if ($link->getAttribute('target')) { 00842 $url->setTarget($link->getAttribute('target')); 00843 } 00844 return $url; 00845 } 00846 00854 function expandUrl($url) { 00855 if (! is_object($url)) { 00856 $url = new SimpleUrl($url); 00857 } 00858 $location = $this->getBaseUrl() ? $this->getBaseUrl() : new SimpleUrl(); 00859 return $url->makeAbsolute($location->makeAbsolute($this->getUrl())); 00860 } 00861 00867 function _setBase(&$tag) { 00868 $url = $tag->getAttribute('href'); 00869 $this->_base = new SimpleUrl($url); 00870 } 00871 00877 function _setTitle(&$tag) { 00878 $this->_title = &$tag; 00879 } 00880 00886 function getTitle() { 00887 if ($this->_title) { 00888 return $this->_title->getText(); 00889 } 00890 return false; 00891 } 00892 00901 function &getFormBySubmit($selector) { 00902 for ($i = 0; $i < count($this->_complete_forms); $i++) { 00903 if ($this->_complete_forms[$i]->hasSubmit($selector)) { 00904 return $this->_complete_forms[$i]; 00905 } 00906 } 00907 $null = null; 00908 return $null; 00909 } 00910 00919 function &getFormByImage($selector) { 00920 for ($i = 0; $i < count($this->_complete_forms); $i++) { 00921 if ($this->_complete_forms[$i]->hasImage($selector)) { 00922 return $this->_complete_forms[$i]; 00923 } 00924 } 00925 $null = null; 00926 return $null; 00927 } 00928 00937 function &getFormById($id) { 00938 for ($i = 0; $i < count($this->_complete_forms); $i++) { 00939 if ($this->_complete_forms[$i]->getId() == $id) { 00940 return $this->_complete_forms[$i]; 00941 } 00942 } 00943 $null = null; 00944 return $null; 00945 } 00946 00955 function setField($selector, $value, $position=false) { 00956 $is_set = false; 00957 for ($i = 0; $i < count($this->_complete_forms); $i++) { 00958 if ($this->_complete_forms[$i]->setField($selector, $value, $position)) { 00959 $is_set = true; 00960 } 00961 } 00962 return $is_set; 00963 } 00964 00973 function getField($selector) { 00974 for ($i = 0; $i < count($this->_complete_forms); $i++) { 00975 $value = $this->_complete_forms[$i]->getValue($selector); 00976 if (isset($value)) { 00977 return $value; 00978 } 00979 } 00980 return null; 00981 } 00982 } 00983 ?>