| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @version $Id: uri.php 21079 2011-04-04 20:54:40Z dextercowley $ 4 * @package Joomla.Framework 5 * @subpackage Environment 6 * @copyright Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved. 7 * @license GNU/GPL, see LICENSE.php 8 * Joomla! is free software. This version may have been modified pursuant 9 * to the GNU General Public License, and as distributed it includes or 10 * is derivative of works licensed under the GNU General Public License or 11 * other free or open source software licenses. 12 * See COPYRIGHT.php for copyright notices and details. 13 */ 14 15 // Check to ensure this file is within the rest of the framework 16 defined('JPATH_BASE') or die(); 17 18 /** 19 * JURI Class 20 * 21 * This class serves two purposes. First to parse a URI and provide a common interface 22 * for the Joomla Framework to access and manipulate a URI. Second to attain the URI of 23 * the current executing script from the server regardless of server. 24 * 25 * @package Joomla.Framework 26 * @subpackage Environment 27 * @since 1.5 28 */ 29 class JURI extends JObject 30 { 31 /** 32 * Original URI 33 * 34 * @var string 35 */ 36 var $_uri = null; 37 38 /** 39 * Protocol 40 * 41 * @var string 42 */ 43 var $_scheme = null; 44 45 /** 46 * Host 47 * 48 * @var string 49 */ 50 var $_host = null; 51 52 /** 53 * Port 54 * 55 * @var integer 56 */ 57 var $_port = null; 58 59 /** 60 * Username 61 * 62 * @var string 63 */ 64 var $_user = null; 65 66 /** 67 * Password 68 * 69 * @var string 70 */ 71 var $_pass = null; 72 73 /** 74 * Path 75 * 76 * @var string 77 */ 78 var $_path = null; 79 80 /** 81 * Query 82 * 83 * @var string 84 */ 85 var $_query = null; 86 87 /** 88 * Anchor 89 * 90 * @var string 91 */ 92 var $_fragment = null; 93 94 /** 95 * Query variable hash 96 * 97 * @var array 98 */ 99 var $_vars = array (); 100 101 /** 102 * Constructor. 103 * You can pass a URI string to the constructor to initialize a specific URI. 104 * 105 * @param string $uri The optional URI string 106 */ 107 function __construct($uri = null) 108 { 109 if ($uri !== null) { 110 $this->parse($uri); 111 } 112 } 113 114 /** 115 * Returns a reference to a global JURI object, only creating it 116 * if it doesn't already exist. 117 * 118 * This method must be invoked as: 119 * <pre> $uri =& JURI::getInstance([$uri]);</pre> 120 * 121 * @static 122 * @param string $uri The URI to parse. [optional: if null uses script URI] 123 * @return JURI The URI object. 124 * @since 1.5 125 */ 126 function &getInstance($uri = 'SERVER') 127 { 128 static $instances = array(); 129 130 if (!isset ($instances[$uri])) 131 { 132 // Are we obtaining the URI from the server? 133 if ($uri == 'SERVER') 134 { 135 // Determine if the request was over SSL (HTTPS) 136 if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off')) { 137 $https = 's://'; 138 } else { 139 $https = '://'; 140 } 141 142 /* 143 * Since we are assigning the URI from the server variables, we first need 144 * to determine if we are running on apache or IIS. If PHP_SELF and REQUEST_URI 145 * are present, we will assume we are running on apache. 146 */ 147 if (!empty ($_SERVER['PHP_SELF']) && !empty ($_SERVER['REQUEST_URI'])) { 148 149 /* 150 * To build the entire URI we need to prepend the protocol, and the http host 151 * to the URI string. 152 */ 153 $theURI = 'http' . $https . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; 154 155 /* 156 * Since we do not have REQUEST_URI to work with, we will assume we are 157 * running on IIS and will therefore need to work some magic with the SCRIPT_NAME and 158 * QUERY_STRING environment variables. 159 */ 160 161 if (strlen($_SERVER['QUERY_STRING']) && strpos($_SERVER['REQUEST_URI'], $_SERVER['QUERY_STRING']) === false) { 162 $theURI .= '?'.$_SERVER['QUERY_STRING']; 163 } 164 165 } 166 else 167 { 168 // IIS uses the SCRIPT_NAME variable instead of a REQUEST_URI variable... thanks, MS 169 $theURI = 'http' . $https . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']; 170 171 // If the query string exists append it to the URI string 172 if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) { 173 $theURI .= '?' . $_SERVER['QUERY_STRING']; 174 } 175 } 176 177 // Now we need to clean what we got since we can't trust the server var 178 // Need to check that the URI is fully decoded in case of multiple-encoded attack vectors. 179 $halt = 0; 180 while (true) 181 { 182 $last = $theURI; 183 $theURI = urldecode($theURI); 184 185 // Check whether the last decode is equal to the first. 186 if ($theURI == $last) { 187 // Break out of the while if the URI is stable. 188 break; 189 } 190 else if (++$halt > 10) { 191 // Runaway check. URI has been seriously compromised. 192 jexit(); 193 } 194 } 195 196 $theURI = str_replace('"', '"',$theURI); 197 $theURI = str_replace('<', '<',$theURI); 198 $theURI = str_replace('>', '>',$theURI); 199 $theURI = preg_replace('/eval\((.*)\)/', '', $theURI); 200 $theURI = preg_replace('/[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']/', '""', $theURI); 201 } 202 else 203 { 204 // We were given a URI 205 $theURI = $uri; 206 } 207 208 // Create the new JURI instance 209 $instances[$uri] = new JURI($theURI); 210 } 211 return $instances[$uri]; 212 } 213 214 /** 215 * Returns the base URI for the request. 216 * 217 * @access public 218 * @static 219 * @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false. 220 * @return string The base URI string 221 * @since 1.5 222 */ 223 function base($pathonly = false) 224 { 225 static $base; 226 227 // Get the base request path 228 if (!isset($base)) 229 { 230 $config =& JFactory::getConfig(); 231 $live_site = $config->getValue('config.live_site'); 232 if(trim($live_site) != '') { 233 $uri =& JURI::getInstance($live_site); 234 $base['prefix'] = $uri->toString( array('scheme', 'host', 'port')); 235 $base['path'] = rtrim($uri->toString( array('path')), '/\\'); 236 if(JPATH_BASE == JPATH_ADMINISTRATOR) { 237 $base['path'] .= '/administrator'; 238 } 239 } else { 240 $uri =& JURI::getInstance(); 241 $base['prefix'] = $uri->toString( array('scheme', 'host', 'port')); 242 243 if (strpos(php_sapi_name(), 'cgi') !== false && !empty($_SERVER['REQUEST_URI']) && 244 (!ini_get('cgi.fix_pathinfo') || version_compare(PHP_VERSION, '5.2.4', '<'))) { 245 // CGI on PHP pre-5.2.4 with cgi.fix_pathinfo = 0. 246 247 // In pre-rev. 240885 of main_cgi.c, SCRIPT_NAME doesn't conform the PHP spec., 248 // therefore we use PHP_SELF instead. 249 $base['path'] = rtrim(dirname(str_replace(array('"', '<', '>', "'"), '', $_SERVER["PHP_SELF"])), '/\\'); 250 } else { 251 // Since PHP 5.2.4 we can trust SCRIPT_NAME; it conforms the spec. 252 $base['path'] = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\'); 253 } 254 } 255 } 256 257 return $pathonly === false ? $base['prefix'].$base['path'].'/' : $base['path']; 258 } 259 260 /** 261 * Returns the root URI for the request. 262 * 263 * @access public 264 * @static 265 * @param boolean $pathonly If false, prepend the scheme, host and port information. Default is false. 266 * @return string The root URI string 267 * @since 1.5 268 */ 269 function root($pathonly = false, $path = null) 270 { 271 static $root; 272 273 // Get the scheme 274 if(!isset($root)) 275 { 276 $uri =& JURI::getInstance(JURI::base()); 277 $root['prefix'] = $uri->toString( array('scheme', 'host', 'port') ); 278 $root['path'] = rtrim($uri->toString( array('path') ), '/\\'); 279 } 280 281 // Get the scheme 282 if(isset($path)) { 283 $root['path'] = $path; 284 } 285 286 return $pathonly === false ? $root['prefix'].$root['path'].'/' : $root['path']; 287 } 288 289 /** 290 * Returns the URL for the request, minus the query 291 * 292 * @access public 293 * @return string 294 * @since 1.5 295 */ 296 function current() 297 { 298 static $current; 299 300 // Get the current URL 301 if (!isset($current)) 302 { 303 $uri = & JURI::getInstance(); 304 $current = $uri->toString( array('scheme', 'host', 'port', 'path')); 305 } 306 307 return $current; 308 } 309 310 /** 311 * Parse a given URI and populate the class fields 312 * 313 * @access public 314 * @param string $uri The URI string to parse 315 * @return boolean True on success 316 * @since 1.5 317 */ 318 function parse($uri) 319 { 320 //Initialize variables 321 $retval = false; 322 323 // Set the original URI to fall back on 324 $this->_uri = $uri; 325 326 /* 327 * Parse the URI and populate the object fields. If URI is parsed properly, 328 * set method return value to true. 329 */ 330 if ($_parts = $this->_parseURL($uri)) { 331 $retval = true; 332 } 333 334 //We need to replace & with & for parse_str to work right... 335 if(isset ($_parts['query']) && strpos($_parts['query'], '&')) { 336 $_parts['query'] = str_replace('&', '&', $_parts['query']); 337 } 338 339 $this->_scheme = isset ($_parts['scheme']) ? $_parts['scheme'] : null; 340 $this->_user = isset ($_parts['user']) ? $_parts['user'] : null; 341 $this->_pass = isset ($_parts['pass']) ? $_parts['pass'] : null; 342 $this->_host = isset ($_parts['host']) ? $_parts['host'] : null; 343 $this->_port = isset ($_parts['port']) ? $_parts['port'] : null; 344 $this->_path = isset ($_parts['path']) ? $_parts['path'] : null; 345 $this->_query = isset ($_parts['query'])? $_parts['query'] : null; 346 $this->_fragment = isset ($_parts['fragment']) ? $_parts['fragment'] : null; 347 348 //parse the query 349 350 if(isset ($_parts['query'])) parse_str($_parts['query'], $this->_vars); 351 return $retval; 352 } 353 354 /** 355 * Returns full uri string 356 * 357 * @access public 358 * @param array $parts An array specifying the parts to render 359 * @return string The rendered URI string 360 * @since 1.5 361 */ 362 function toString($parts = array('scheme', 'user', 'pass', 'host', 'port', 'path', 'query', 'fragment')) 363 { 364 $query = $this->getQuery(); //make sure the query is created 365 366 $uri = ''; 367 $uri .= in_array('scheme', $parts) ? (!empty($this->_scheme) ? $this->_scheme.'://' : '') : ''; 368 $uri .= in_array('user', $parts) ? $this->_user : ''; 369 $uri .= in_array('pass', $parts) ? (!empty ($this->_pass) ? ':' : '') .$this->_pass. (!empty ($this->_user) ? '@' : '') : ''; 370 $uri .= in_array('host', $parts) ? $this->_host : ''; 371 $uri .= in_array('port', $parts) ? (!empty ($this->_port) ? ':' : '').$this->_port : ''; 372 $uri .= in_array('path', $parts) ? $this->_path : ''; 373 $uri .= in_array('query', $parts) ? (!empty ($query) ? '?'.$query : '') : ''; 374 $uri .= in_array('fragment', $parts)? (!empty ($this->_fragment) ? '#'.$this->_fragment : '') : ''; 375 376 return $uri; 377 } 378 379 /** 380 * Adds a query variable and value, replacing the value if it 381 * already exists and returning the old value. 382 * 383 * @access public 384 * @param string $name Name of the query variable to set 385 * @param string $value Value of the query variable 386 * @return string Previous value for the query variable 387 * @since 1.5 388 */ 389 function setVar($name, $value) 390 { 391 $tmp = @$this->_vars[$name]; 392 $this->_vars[$name] = $value; 393 394 //empty the query 395 $this->_query = null; 396 397 return $tmp; 398 } 399 400 /** 401 * Returns a query variable by name 402 * 403 * @access public 404 * @param string $name Name of the query variable to get 405 * @return array Query variables 406 * @since 1.5 407 */ 408 function getVar($name = null, $default=null) 409 { 410 if(isset($this->_vars[$name])) { 411 return $this->_vars[$name]; 412 } 413 return $default; 414 } 415 416 /** 417 * Removes an item from the query string variables if it exists 418 * 419 * @access public 420 * @param string $name Name of variable to remove 421 * @since 1.5 422 */ 423 function delVar($name) 424 { 425 if (in_array($name, array_keys($this->_vars))) 426 { 427 unset ($this->_vars[$name]); 428 429 //empty the query 430 $this->_query = null; 431 } 432 } 433 434 /** 435 * Sets the query to a supplied string in format: 436 * foo=bar&x=y 437 * 438 * @access public 439 * @param mixed (array|string) $query The query string 440 * @since 1.5 441 */ 442 function setQuery($query) 443 { 444 if(!is_array($query)) { 445 if(strpos($query, '&') !== false) 446 { 447 $query = str_replace('&','&',$query); 448 } 449 parse_str($query, $this->_vars); 450 } 451 452 if(is_array($query)) { 453 $this->_vars = $query; 454 } 455 456 //empty the query 457 $this->_query = null; 458 } 459 460 /** 461 * Returns flat query string 462 * 463 * @access public 464 * @return string Query string 465 * @since 1.5 466 */ 467 function getQuery($toArray = false) 468 { 469 if($toArray) { 470 return $this->_vars; 471 } 472 473 //If the query is empty build it first 474 if(is_null($this->_query)) { 475 $this->_query = $this->buildQuery($this->_vars); 476 } 477 478 return $this->_query; 479 } 480 481 /** 482 * Build a query from a array (reverse of the PHP parse_str()) 483 * 484 * @access public 485 * @return string The resulting query string 486 * @since 1.5 487 * @see parse_str() 488 */ 489 function buildQuery ($params, $akey = null) 490 { 491 if ( !is_array($params) || count($params) == 0 ) { 492 return false; 493 } 494 495 $out = array(); 496 497 //reset in case we are looping 498 if( !isset($akey) && !count($out) ) { 499 unset($out); 500 $out = array(); 501 } 502 503 foreach ( $params as $key => $val ) 504 { 505 if ( is_array($val) ) { 506 $out[] = JURI::buildQuery($val,$key); 507 continue; 508 } 509 510 $thekey = ( !$akey ) ? $key : $akey.'['.$key.']'; 511 $out[] = $thekey."=".urlencode($val); 512 } 513 514 return implode("&",$out); 515 } 516 517 /** 518 * Get URI scheme (protocol) 519 * ie. http, https, ftp, etc... 520 * 521 * @access public 522 * @return string The URI scheme 523 * @since 1.5 524 */ 525 function getScheme() { 526 return $this->_scheme; 527 } 528 529 /** 530 * Set URI scheme (protocol) 531 * ie. http, https, ftp, etc... 532 * 533 * @access public 534 * @param string $scheme The URI scheme 535 * @since 1.5 536 */ 537 function setScheme($scheme) { 538 $this->_scheme = $scheme; 539 } 540 541 /** 542 * Get URI username 543 * returns the username, or null if no username was specified 544 * 545 * @access public 546 * @return string The URI username 547 * @since 1.5 548 */ 549 function getUser() { 550 return $this->_user; 551 } 552 553 /** 554 * Set URI username 555 * 556 * @access public 557 * @param string $user The URI username 558 * @since 1.5 559 */ 560 function setUser($user) { 561 $this->_user = $user; 562 } 563 564 /** 565 * Get URI password 566 * returns the password, or null if no password was specified 567 * 568 * @access public 569 * @return string The URI password 570 * @since 1.5 571 */ 572 function getPass() { 573 return $this->_pass; 574 } 575 576 /** 577 * Set URI password 578 * 579 * @access public 580 * @param string $pass The URI password 581 * @since 1.5 582 */ 583 function setPass($pass) { 584 $this->_pass = $pass; 585 } 586 587 /** 588 * Get URI host 589 * returns the hostname/ip, or null if no hostname/ip was specified 590 * 591 * @access public 592 * @return string The URI host 593 * @since 1.5 594 */ 595 function getHost() { 596 return $this->_host; 597 } 598 599 /** 600 * Set URI host 601 * 602 * @access public 603 * @param string $host The URI host 604 * @since 1.5 605 */ 606 function setHost($host) { 607 $this->_host = $host; 608 } 609 610 /** 611 * Get URI port 612 * returns the port number, or null if no port was specified 613 * 614 * @access public 615 * @return int The URI port number 616 */ 617 function getPort() { 618 return (isset ($this->_port)) ? $this->_port : null; 619 } 620 621 /** 622 * Set URI port 623 * 624 * @access public 625 * @param int $port The URI port number 626 * @since 1.5 627 */ 628 function setPort($port) { 629 $this->_port = $port; 630 } 631 632 /** 633 * Gets the URI path string 634 * 635 * @access public 636 * @return string The URI path string 637 * @since 1.5 638 */ 639 function getPath() { 640 return $this->_path; 641 } 642 643 /** 644 * Set the URI path string 645 * 646 * @access public 647 * @param string $path The URI path string 648 * @since 1.5 649 */ 650 function setPath($path) { 651 $this->_path = $this->_cleanPath($path); 652 } 653 654 /** 655 * Get the URI archor string 656 * everything after the "#" 657 * 658 * @access public 659 * @return string The URI anchor string 660 * @since 1.5 661 */ 662 function getFragment() { 663 return $this->_fragment; 664 } 665 666 /** 667 * Set the URI anchor string 668 * everything after the "#" 669 * 670 * @access public 671 * @param string $anchor The URI anchor string 672 * @since 1.5 673 */ 674 function setFragment($anchor) { 675 $this->_fragment = $anchor; 676 } 677 678 /** 679 * Checks whether the current URI is using HTTPS 680 * 681 * @access public 682 * @return boolean True if using SSL via HTTPS 683 * @since 1.5 684 */ 685 function isSSL() { 686 return $this->getScheme() == 'https' ? true : false; 687 } 688 689 /** 690 * Checks if the supplied URL is internal 691 * 692 * @access public 693 * @param string $url The URL to check 694 * @return boolean True if Internal 695 * @since 1.5 696 */ 697 function isInternal($url) { 698 $uri =& JURI::getInstance($url); 699 $base = $uri->toString(array('scheme', 'host', 'port', 'path')); 700 $host = $uri->toString(array('scheme', 'host', 'port')); 701 if(stripos($base, JURI::base()) !== 0 && !empty($host)) { 702 return false; 703 } 704 return true; 705 } 706 707 /** 708 * Resolves //, ../ and ./ from a path and returns 709 * the result. Eg: 710 * 711 * /foo/bar/../boo.php => /foo/boo.php 712 * /foo/bar/../../boo.php => /boo.php 713 * /foo/bar/.././/boo.php => /foo/boo.php 714 * 715 * @access private 716 * @param string $uri The URI path to clean 717 * @return string Cleaned and resolved URI path 718 * @since 1.5 719 */ 720 function _cleanPath($path) 721 { 722 $path = explode('/', preg_replace('#(/+)#', '/', $path)); 723 724 for ($i = 0; $i < count($path); $i ++) { 725 if ($path[$i] == '.') { 726 unset ($path[$i]); 727 $path = array_values($path); 728 $i --; 729 730 } 731 elseif ($path[$i] == '..' AND ($i > 1 OR ($i == 1 AND $path[0] != ''))) { 732 unset ($path[$i]); 733 unset ($path[$i -1]); 734 $path = array_values($path); 735 $i -= 2; 736 737 } 738 elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') { 739 unset ($path[$i]); 740 $path = array_values($path); 741 $i --; 742 743 } else { 744 continue; 745 } 746 } 747 748 return implode('/', $path); 749 } 750 751 /** 752 * Backwards compatibility function for parse_url function 753 * 754 * This function solves different bugs in PHP versions lower then 755 * 4.4, will be deprecated in future versions. 756 * 757 * @access private 758 * @return array Associative array containing the URL parts 759 * @since 1.5 760 * @see parse_url() 761 */ 762 function _parseURL($uri) 763 { 764 $parts = array(); 765 if (version_compare( phpversion(), '4.4' ) < 0) 766 { 767 $regex = "<^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?>"; 768 $matches = array(); 769 preg_match($regex, $uri, $matches, PREG_OFFSET_CAPTURE); 770 771 $authority = @$matches[4][0]; 772 if (strpos($authority, '@') !== false) { 773 $authority = explode('@', $authority); 774 @list($parts['user'], $parts['pass']) = explode(':', $authority[0]); 775 $authority = $authority[1]; 776 } 777 778 if (strpos($authority, ':') !== false) { 779 $authority = explode(':', $authority); 780 $parts['host'] = $authority[0]; 781 $parts['port'] = $authority[1]; 782 } else { 783 $parts['host'] = $authority; 784 } 785 786 $parts['scheme'] = @$matches[2][0]; 787 $parts['path'] = @$matches[5][0]; 788 $parts['query'] = @$matches[7][0]; 789 $parts['fragment'] = @$matches[9][0]; 790 } 791 else 792 { 793 $parts = @parse_url($uri); 794 } 795 return $parts; 796 } 797 798 799 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Mar 28 15:54:07 2012 | Cross-referenced by PHPXref 0.7.1 |