| [ Index ] |
PHP Cross Reference of Limb3 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Base include file for SimpleTest 4 * @package SimpleTest 5 * @subpackage WebTester 6 * @version $Id: frames.php 5999 2007-06-18 13:13:08Z pachanga $ 7 */ 8 9 /**#@+ 10 * include other SimpleTest class files 11 */ 12 require_once(dirname(__FILE__) . '/page.php'); 13 require_once(dirname(__FILE__) . '/user_agent.php'); 14 /**#@-*/ 15 16 /** 17 * A composite page. Wraps a frameset page and 18 * adds subframes. The original page will be 19 * mostly ignored. Implements the SimplePage 20 * interface so as to be interchangeable. 21 * @package SimpleTest 22 * @subpackage WebTester 23 */ 24 class SimpleFrameset { 25 var $_frameset; 26 var $_frames; 27 var $_focus; 28 var $_names; 29 30 /** 31 * Stashes the frameset page. Will make use of the 32 * browser to fetch the sub frames recursively. 33 * @param SimplePage $page Frameset page. 34 */ 35 function SimpleFrameset(&$page) { 36 $this->_frameset = &$page; 37 $this->_frames = array(); 38 $this->_focus = false; 39 $this->_names = array(); 40 } 41 42 /** 43 * Adds a parsed page to the frameset. 44 * @param SimplePage $page Frame page. 45 * @param string $name Name of frame in frameset. 46 * @access public 47 */ 48 function addFrame(&$page, $name = false) { 49 $this->_frames[] = &$page; 50 if ($name) { 51 $this->_names[$name] = count($this->_frames) - 1; 52 } 53 } 54 55 /** 56 * Replaces existing frame with another. If the 57 * frame is nested, then the call is passed down 58 * one level. 59 * @param array $path Path of frame in frameset. 60 * @param SimplePage $page Frame source. 61 * @access public 62 */ 63 function setFrame($path, &$page) { 64 $name = array_shift($path); 65 if (isset($this->_names[$name])) { 66 $index = $this->_names[$name]; 67 } else { 68 $index = $name - 1; 69 } 70 if (count($path) == 0) { 71 $this->_frames[$index] = &$page; 72 return; 73 } 74 $this->_frames[$index]->setFrame($path, $page); 75 } 76 77 /** 78 * Accessor for current frame focus. Will be 79 * false if no frame has focus. Will have the nested 80 * frame focus if any. 81 * @return array Labels or indexes of nested frames. 82 * @access public 83 */ 84 function getFrameFocus() { 85 if ($this->_focus === false) { 86 return array(); 87 } 88 return array_merge( 89 array($this->_getPublicNameFromIndex($this->_focus)), 90 $this->_frames[$this->_focus]->getFrameFocus()); 91 } 92 93 /** 94 * Turns an internal array index into the frames list 95 * into a public name, or if none, then a one offset 96 * index. 97 * @param integer $subject Internal index. 98 * @return integer/string Public name. 99 * @access private 100 */ 101 function _getPublicNameFromIndex($subject) { 102 foreach ($this->_names as $name => $index) { 103 if ($subject == $index) { 104 return $name; 105 } 106 } 107 return $subject + 1; 108 } 109 110 /** 111 * Sets the focus by index. The integer index starts from 1. 112 * If already focused and the target frame also has frames, 113 * then the nested frame will be focused. 114 * @param integer $choice Chosen frame. 115 * @return boolean True if frame exists. 116 * @access public 117 */ 118 function setFrameFocusByIndex($choice) { 119 if (is_integer($this->_focus)) { 120 if ($this->_frames[$this->_focus]->hasFrames()) { 121 return $this->_frames[$this->_focus]->setFrameFocusByIndex($choice); 122 } 123 } 124 if (($choice < 1) || ($choice > count($this->_frames))) { 125 return false; 126 } 127 $this->_focus = $choice - 1; 128 return true; 129 } 130 131 /** 132 * Sets the focus by name. If already focused and the 133 * target frame also has frames, then the nested frame 134 * will be focused. 135 * @param string $name Chosen frame. 136 * @return boolean True if frame exists. 137 * @access public 138 */ 139 function setFrameFocus($name) { 140 if (is_integer($this->_focus)) { 141 if ($this->_frames[$this->_focus]->hasFrames()) { 142 return $this->_frames[$this->_focus]->setFrameFocus($name); 143 } 144 } 145 if (in_array($name, array_keys($this->_names))) { 146 $this->_focus = $this->_names[$name]; 147 return true; 148 } 149 return false; 150 } 151 152 /** 153 * Clears the frame focus. 154 * @access public 155 */ 156 function clearFrameFocus() { 157 $this->_focus = false; 158 $this->_clearNestedFramesFocus(); 159 } 160 161 /** 162 * Clears the frame focus for any nested frames. 163 * @access private 164 */ 165 function _clearNestedFramesFocus() { 166 for ($i = 0; $i < count($this->_frames); $i++) { 167 $this->_frames[$i]->clearFrameFocus(); 168 } 169 } 170 171 /** 172 * Test for the presence of a frameset. 173 * @return boolean Always true. 174 * @access public 175 */ 176 function hasFrames() { 177 return true; 178 } 179 180 /** 181 * Accessor for frames information. 182 * @return array/string Recursive hash of frame URL strings. 183 * The key is either a numerical 184 * index or the name attribute. 185 * @access public 186 */ 187 function getFrames() { 188 $report = array(); 189 for ($i = 0; $i < count($this->_frames); $i++) { 190 $report[$this->_getPublicNameFromIndex($i)] = 191 $this->_frames[$i]->getFrames(); 192 } 193 return $report; 194 } 195 196 /** 197 * Accessor for raw text of either all the pages or 198 * the frame in focus. 199 * @return string Raw unparsed content. 200 * @access public 201 */ 202 function getRaw() { 203 if (is_integer($this->_focus)) { 204 return $this->_frames[$this->_focus]->getRaw(); 205 } 206 $raw = ''; 207 for ($i = 0; $i < count($this->_frames); $i++) { 208 $raw .= $this->_frames[$i]->getRaw(); 209 } 210 return $raw; 211 } 212 213 /** 214 * Accessor for plain text of either all the pages or 215 * the frame in focus. 216 * @return string Plain text content. 217 * @access public 218 */ 219 function getText() { 220 if (is_integer($this->_focus)) { 221 return $this->_frames[$this->_focus]->getText(); 222 } 223 $raw = ''; 224 for ($i = 0; $i < count($this->_frames); $i++) { 225 $raw .= ' ' . $this->_frames[$i]->getText(); 226 } 227 return trim($raw); 228 } 229 230 /** 231 * Accessor for last error. 232 * @return string Error from last response. 233 * @access public 234 */ 235 function getTransportError() { 236 if (is_integer($this->_focus)) { 237 return $this->_frames[$this->_focus]->getTransportError(); 238 } 239 return $this->_frameset->getTransportError(); 240 } 241 242 /** 243 * Request method used to fetch this frame. 244 * @return string GET, POST or HEAD. 245 * @access public 246 */ 247 function getMethod() { 248 if (is_integer($this->_focus)) { 249 return $this->_frames[$this->_focus]->getMethod(); 250 } 251 return $this->_frameset->getMethod(); 252 } 253 254 /** 255 * Original resource name. 256 * @return SimpleUrl Current url. 257 * @access public 258 */ 259 function getUrl() { 260 if (is_integer($this->_focus)) { 261 $url = $this->_frames[$this->_focus]->getUrl(); 262 $url->setTarget($this->_getPublicNameFromIndex($this->_focus)); 263 } else { 264 $url = $this->_frameset->getUrl(); 265 } 266 return $url; 267 } 268 269 /** 270 * Original request data. 271 * @return mixed Sent content. 272 * @access public 273 */ 274 function getRequestData() { 275 if (is_integer($this->_focus)) { 276 return $this->_frames[$this->_focus]->getRequestData(); 277 } 278 return $this->_frameset->getRequestData(); 279 } 280 281 /** 282 * Accessor for current MIME type. 283 * @return string MIME type as string; e.g. 'text/html' 284 * @access public 285 */ 286 function getMimeType() { 287 if (is_integer($this->_focus)) { 288 return $this->_frames[$this->_focus]->getMimeType(); 289 } 290 return $this->_frameset->getMimeType(); 291 } 292 293 /** 294 * Accessor for last response code. 295 * @return integer Last HTTP response code received. 296 * @access public 297 */ 298 function getResponseCode() { 299 if (is_integer($this->_focus)) { 300 return $this->_frames[$this->_focus]->getResponseCode(); 301 } 302 return $this->_frameset->getResponseCode(); 303 } 304 305 /** 306 * Accessor for last Authentication type. Only valid 307 * straight after a challenge (401). 308 * @return string Description of challenge type. 309 * @access public 310 */ 311 function getAuthentication() { 312 if (is_integer($this->_focus)) { 313 return $this->_frames[$this->_focus]->getAuthentication(); 314 } 315 return $this->_frameset->getAuthentication(); 316 } 317 318 /** 319 * Accessor for last Authentication realm. Only valid 320 * straight after a challenge (401). 321 * @return string Name of security realm. 322 * @access public 323 */ 324 function getRealm() { 325 if (is_integer($this->_focus)) { 326 return $this->_frames[$this->_focus]->getRealm(); 327 } 328 return $this->_frameset->getRealm(); 329 } 330 331 /** 332 * Accessor for outgoing header information. 333 * @return string Header block. 334 * @access public 335 */ 336 function getRequest() { 337 if (is_integer($this->_focus)) { 338 return $this->_frames[$this->_focus]->getRequest(); 339 } 340 return $this->_frameset->getRequest(); 341 } 342 343 /** 344 * Accessor for raw header information. 345 * @return string Header block. 346 * @access public 347 */ 348 function getHeaders() { 349 if (is_integer($this->_focus)) { 350 return $this->_frames[$this->_focus]->getHeaders(); 351 } 352 return $this->_frameset->getHeaders(); 353 } 354 355 /** 356 * Accessor for parsed title. 357 * @return string Title or false if no title is present. 358 * @access public 359 */ 360 function getTitle() { 361 return $this->_frameset->getTitle(); 362 } 363 364 /** 365 * Accessor for a list of all fixed links. 366 * @return array List of urls with scheme of 367 * http or https and hostname. 368 * @access public 369 */ 370 function getAbsoluteUrls() { 371 if (is_integer($this->_focus)) { 372 return $this->_frames[$this->_focus]->getAbsoluteUrls(); 373 } 374 $urls = array(); 375 foreach ($this->_frames as $frame) { 376 $urls = array_merge($urls, $frame->getAbsoluteUrls()); 377 } 378 return array_values(array_unique($urls)); 379 } 380 381 /** 382 * Accessor for a list of all relative links. 383 * @return array List of urls without hostname. 384 * @access public 385 */ 386 function getRelativeUrls() { 387 if (is_integer($this->_focus)) { 388 return $this->_frames[$this->_focus]->getRelativeUrls(); 389 } 390 $urls = array(); 391 foreach ($this->_frames as $frame) { 392 $urls = array_merge($urls, $frame->getRelativeUrls()); 393 } 394 return array_values(array_unique($urls)); 395 } 396 397 /** 398 * Accessor for URLs by the link label. Label will match 399 * regardess of whitespace issues and case. 400 * @param string $label Text of link. 401 * @return array List of links with that label. 402 * @access public 403 */ 404 function getUrlsByLabel($label) { 405 if (is_integer($this->_focus)) { 406 return $this->_tagUrlsWithFrame( 407 $this->_frames[$this->_focus]->getUrlsByLabel($label), 408 $this->_focus); 409 } 410 $urls = array(); 411 foreach ($this->_frames as $index => $frame) { 412 $urls = array_merge( 413 $urls, 414 $this->_tagUrlsWithFrame( 415 $frame->getUrlsByLabel($label), 416 $index)); 417 } 418 return $urls; 419 } 420 421 /** 422 * Accessor for a URL by the id attribute. If in a frameset 423 * then the first link found with that ID attribute is 424 * returned only. Focus on a frame if you want one from 425 * a specific part of the frameset. 426 * @param string $id Id attribute of link. 427 * @return string URL with that id. 428 * @access public 429 */ 430 function getUrlById($id) { 431 foreach ($this->_frames as $index => $frame) { 432 if ($url = $frame->getUrlById($id)) { 433 if (! $url->gettarget()) { 434 $url->setTarget($this->_getPublicNameFromIndex($index)); 435 } 436 return $url; 437 } 438 } 439 return false; 440 } 441 442 /** 443 * Attaches the intended frame index to a list of URLs. 444 * @param array $urls List of SimpleUrls. 445 * @param string $frame Name of frame or index. 446 * @return array List of tagged URLs. 447 * @access private 448 */ 449 function _tagUrlsWithFrame($urls, $frame) { 450 $tagged = array(); 451 foreach ($urls as $url) { 452 if (! $url->getTarget()) { 453 $url->setTarget($this->_getPublicNameFromIndex($frame)); 454 } 455 $tagged[] = $url; 456 } 457 return $tagged; 458 } 459 460 /** 461 * Finds a held form by button label. Will only 462 * search correctly built forms. 463 * @param SimpleSelector $selector Button finder. 464 * @return SimpleForm Form object containing 465 * the button. 466 * @access public 467 */ 468 function &getFormBySubmit($selector) { 469 $form = &$this->_findForm('getFormBySubmit', $selector); 470 return $form; 471 } 472 473 /** 474 * Finds a held form by image using a selector. 475 * Will only search correctly built forms. The first 476 * form found either within the focused frame, or 477 * across frames, will be the one returned. 478 * @param SimpleSelector $selector Image finder. 479 * @return SimpleForm Form object containing 480 * the image. 481 * @access public 482 */ 483 function &getFormByImage($selector) { 484 $form = &$this->_findForm('getFormByImage', $selector); 485 return $form; 486 } 487 488 /** 489 * Finds a held form by the form ID. A way of 490 * identifying a specific form when we have control 491 * of the HTML code. The first form found 492 * either within the focused frame, or across frames, 493 * will be the one returned. 494 * @param string $id Form label. 495 * @return SimpleForm Form object containing the matching ID. 496 * @access public 497 */ 498 function &getFormById($id) { 499 $form = &$this->_findForm('getFormById', $id); 500 return $form; 501 } 502 503 /** 504 * General form finder. Will search all the frames or 505 * just the one in focus. 506 * @param string $method Method to use to find in a page. 507 * @param string $attribute Label, name or ID. 508 * @return SimpleForm Form object containing the matching ID. 509 * @access private 510 */ 511 function &_findForm($method, $attribute) { 512 if (is_integer($this->_focus)) { 513 $form = &$this->_findFormInFrame( 514 $this->_frames[$this->_focus], 515 $this->_focus, 516 $method, 517 $attribute); 518 return $form; 519 } 520 for ($i = 0; $i < count($this->_frames); $i++) { 521 $form = &$this->_findFormInFrame( 522 $this->