[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to [email protected] so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Uri 17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 18 * @license http://framework.zend.com/license/new-bsd New BSD License 19 * @version $Id$ 20 */ 21 22 /** 23 * @see Zend_Uri 24 */ 25 require_once 'Zend/Uri.php'; 26 27 /** 28 * @see Zend_Validate_Hostname 29 */ 30 require_once 'Zend/Validate/Hostname.php'; 31 32 /** 33 * HTTP(S) URI handler 34 * 35 * @category Zend 36 * @package Zend_Uri 37 * @uses Zend_Uri 38 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 39 * @license http://framework.zend.com/license/new-bsd New BSD License 40 */ 41 class Zend_Uri_Http extends Zend_Uri 42 { 43 /** 44 * Character classes for validation regular expressions 45 */ 46 const CHAR_ALNUM = 'A-Za-z0-9'; 47 const CHAR_MARK = '-_.!~*\'()\[\]'; 48 const CHAR_RESERVED = ';\/?:@&=+$,'; 49 const CHAR_SEGMENT = ':@&=+$,;'; 50 const CHAR_UNWISE = '{}|\\\\^`'; 51 52 /** 53 * HTTP username 54 * 55 * @var string 56 */ 57 protected $_username = ''; 58 59 /** 60 * HTTP password 61 * 62 * @var string 63 */ 64 protected $_password = ''; 65 66 /** 67 * HTTP host 68 * 69 * @var string 70 */ 71 protected $_host = ''; 72 73 /** 74 * HTTP post 75 * 76 * @var string 77 */ 78 protected $_port = ''; 79 80 /** 81 * HTTP part 82 * 83 * @var string 84 */ 85 protected $_path = ''; 86 87 /** 88 * HTTP query 89 * 90 * @var string 91 */ 92 protected $_query = ''; 93 94 /** 95 * HTTP fragment 96 * 97 * @var string 98 */ 99 protected $_fragment = ''; 100 101 /** 102 * Regular expression grammar rules for validation; values added by constructor 103 * 104 * @var array 105 */ 106 protected $_regex = array(); 107 108 /** 109 * Constructor accepts a string $scheme (e.g., http, https) and a scheme-specific part of the URI 110 * (e.g., example.com/path/to/resource?query=param#fragment) 111 * 112 * @param string $scheme The scheme of the URI 113 * @param string $schemeSpecific The scheme-specific part of the URI 114 * @throws Zend_Uri_Exception When the URI is not valid 115 */ 116 protected function __construct($scheme, $schemeSpecific = '') 117 { 118 // Set the scheme 119 $this->_scheme = $scheme; 120 121 // Set up grammar rules for validation via regular expressions. These 122 // are to be used with slash-delimited regular expression strings. 123 124 // Escaped special characters (eg. '%25' for '%') 125 $this->_regex['escaped'] = '%[[:xdigit:]]{2}'; 126 127 // Unreserved characters 128 $this->_regex['unreserved'] = '[' . self::CHAR_ALNUM . self::CHAR_MARK . ']'; 129 130 // Segment can use escaped, unreserved or a set of additional chars 131 $this->_regex['segment'] = '(?:' . $this->_regex['escaped'] . '|[' . 132 self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_SEGMENT . '])*'; 133 134 // Path can be a series of segmets char strings seperated by '/' 135 $this->_regex['path'] = '(?:\/(?:' . $this->_regex['segment'] . ')?)+'; 136 137 // URI characters can be escaped, alphanumeric, mark or reserved chars 138 $this->_regex['uric'] = '(?:' . $this->_regex['escaped'] . '|[' . 139 self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_RESERVED . 140 141 // If unwise chars are allowed, add them to the URI chars class 142 (self::$_config['allow_unwise'] ? self::CHAR_UNWISE : '') . '])'; 143 144 // If no scheme-specific part was supplied, the user intends to create 145 // a new URI with this object. No further parsing is required. 146 if (strlen($schemeSpecific) === 0) { 147 return; 148 } 149 150 // Parse the scheme-specific URI parts into the instance variables. 151 $this->_parseUri($schemeSpecific); 152 153 // Validate the URI 154 if ($this->valid() === false) { 155 require_once 'Zend/Uri/Exception.php'; 156 throw new Zend_Uri_Exception('Invalid URI supplied'); 157 } 158 } 159 160 /** 161 * Creates a Zend_Uri_Http from the given string 162 * 163 * @param string $uri String to create URI from, must start with 164 * 'http://' or 'https://' 165 * @throws InvalidArgumentException When the given $uri is not a string or 166 * does not start with http:// or https:// 167 * @throws Zend_Uri_Exception When the given $uri is invalid 168 * @return Zend_Uri_Http 169 */ 170 public static function fromString($uri) 171 { 172 if (is_string($uri) === false) { 173 require_once 'Zend/Uri/Exception.php'; 174 throw new Zend_Uri_Exception('$uri is not a string'); 175 } 176 177 $uri = explode(':', $uri, 2); 178 $scheme = strtolower($uri[0]); 179 $schemeSpecific = isset($uri[1]) === true ? $uri[1] : ''; 180 181 if (in_array($scheme, array('http', 'https')) === false) { 182 require_once 'Zend/Uri/Exception.php'; 183 throw new Zend_Uri_Exception("Invalid scheme: '$scheme'"); 184 } 185 186 $schemeHandler = new Zend_Uri_Http($scheme, $schemeSpecific); 187 return $schemeHandler; 188 } 189 190 /** 191 * Parse the scheme-specific portion of the URI and place its parts into instance variables. 192 * 193 * @param string $schemeSpecific The scheme-specific portion to parse 194 * @throws Zend_Uri_Exception When scheme-specific decoposition fails 195 * @throws Zend_Uri_Exception When authority decomposition fails 196 * @return void 197 */ 198 protected function _parseUri($schemeSpecific) 199 { 200 // High-level decomposition parser 201 $pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~'; 202 $status = @preg_match($pattern, $schemeSpecific, $matches); 203 if ($status === false) { 204 require_once 'Zend/Uri/Exception.php'; 205 throw new Zend_Uri_Exception('Internal error: scheme-specific decomposition failed'); 206 } 207 208 // Failed decomposition; no further processing needed 209 if ($status === false) { 210 return; 211 } 212 213 // Save URI components that need no further decomposition 214 $this->_path = isset($matches[4]) === true ? $matches[4] : ''; 215 $this->_query = isset($matches[6]) === true ? $matches[6] : ''; 216 $this->_fragment = isset($matches[8]) === true ? $matches[8] : ''; 217 218 // Additional decomposition to get username, password, host, and port 219 $combo = isset($matches[3]) === true ? $matches[3] : ''; 220 $pattern = '~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~'; 221 $status = @preg_match($pattern, $combo, $matches); 222 if ($status === false) { 223 require_once 'Zend/Uri/Exception.php'; 224 throw new Zend_Uri_Exception('Internal error: authority decomposition failed'); 225 } 226 227 // Failed decomposition; no further processing needed 228 if ($status === false) { 229 return; 230 } 231 232 // Save remaining URI components 233 $this->_username = isset($matches[2]) === true ? $matches[2] : ''; 234 $this->_password = isset($matches[4]) === true ? $matches[4] : ''; 235 $this->_host = isset($matches[5]) === true ? $matches[5] : ''; 236 $this->_port = isset($matches[7]) === true ? $matches[7] : ''; 237 238 } 239 240 /** 241 * Returns a URI based on current values of the instance variables. If any 242 * part of the URI does not pass validation, then an exception is thrown. 243 * 244 * @throws Zend_Uri_Exception When one or more parts of the URI are invalid 245 * @return string 246 */ 247 public function getUri() 248 { 249 if ($this->valid() === false) { 250 require_once 'Zend/Uri/Exception.php'; 251 throw new Zend_Uri_Exception('One or more parts of the URI are invalid'); 252 } 253 254 $password = strlen($this->_password) > 0 ? ":$this->_password" : ''; 255 $auth = strlen($this->_username) > 0 ? "$this->_username$password@" : ''; 256 $port = strlen($this->_port) > 0 ? ":$this->_port" : ''; 257 $query = strlen($this->_query) > 0 ? "?$this->_query" : ''; 258 $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : ''; 259 260 return $this->_scheme 261 . '://' 262 . $auth 263 . $this->_host 264 . $port 265 . $this->_path 266 . $query 267 . $fragment; 268 } 269 270 /** 271 * Validate the current URI from the instance variables. Returns true if and only if all 272 * parts pass validation. 273 * 274 * @return boolean 275 */ 276 public function valid() 277 { 278 // Return true if and only if all parts of the URI have passed validation 279 return $this->validateUsername() 280 and $this->validatePassword() 281 and $this->validateHost() 282 and $this->validatePort() 283 and $this->validatePath() 284 and $this->validateQuery() 285 and $this->validateFragment(); 286 } 287 288 /** 289 * Returns the username portion of the URL, or FALSE if none. 290 * 291 * @return string 292 */ 293 public function getUsername() 294 { 295 return strlen($this->_username) > 0 ? $this->_username : false; 296 } 297 298 /** 299 * Returns true if and only if the username passes validation. If no username is passed, 300 * then the username contained in the instance variable is used. 301 * 302 * @param string $username The HTTP username 303 * @throws Zend_Uri_Exception When username validation fails 304 * @return boolean 305 * @link http://www.faqs.org/rfcs/rfc2396.html 306 */ 307 public function validateUsername($username = null) 308 { 309 if ($username === null) { 310 $username = $this->_username; 311 } 312 313 // If the username is empty, then it is considered valid 314 if (strlen($username) === 0) { 315 return true; 316 } 317 318 // Check the username against the allowed values 319 $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' . 320 self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $username); 321 322 if ($status === false) { 323 require_once 'Zend/Uri/Exception.php'; 324 throw new Zend_Uri_Exception('Internal error: username validation failed'); 325 } 326 327 return $status === 1; 328 } 329 330 /** 331 * Sets the username for the current URI, and returns the old username 332 * 333 * @param string $username The HTTP username 334 * @throws Zend_Uri_Exception When $username is not a valid HTTP username 335 * @return string 336 */ 337 public function setUsername($username) 338 { 339 if ($this->validateUsername($username) === false) { 340 require_once 'Zend/Uri/Exception.php'; 341 throw new Zend_Uri_Exception("Username \"$username\" is not a valid HTTP username"); 342 } 343 344 $oldUsername = $this->_username; 345 $this->_username = $username; 346 347 return $oldUsername; 348 } 349 350 /** 351 * Returns the password portion of the URL, or FALSE if none. 352 * 353 * @return string 354 */ 355 public function getPassword() 356 { 357 return strlen($this->_password) > 0 ? $this->_password : false; 358 } 359 360 /** 361 * Returns true if and only if the password passes validation. If no password is passed, 362 * then the password contained in the instance variable is used. 363 * 364 * @param string $password The HTTP password 365 * @throws Zend_Uri_Exception When password validation fails 366 * @return boolean 367 * @link http://www.faqs.org/rfcs/rfc2396.html 368 */ 369 public function validatePassword($password = null) 370 { 371 if ($password === null) { 372 $password = $this->_password; 373 } 374 375 // If the password is empty, then it is considered valid 376 if (strlen($password) === 0) { 377 return true; 378 } 379 380 // If the password is nonempty, but there is no username, then it is considered invalid 381 if (strlen($password) > 0 and strlen($this->_username) === 0) { 382 return false; 383 } 384 385 // Check the password against the allowed values 386 $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' . 387 self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $password); 388 389 if ($status === false) { 390 require_once 'Zend/Uri/Exception.php'; 391 throw new Zend_Uri_Exception('Internal error: password validation failed.'); 392 } 393 394 return $status == 1; 395 } 396 397 /** 398 * Sets the password for the current URI, and returns the old password 399 * 400 * @param string $password The HTTP password 401 * @throws Zend_Uri_Exception When $password is not a valid HTTP password 402 * @return string 403 */ 404 public function setPassword($password) 405 { 406 if ($this->validatePassword($password) === false) { 407 require_once 'Zend/Uri/Exception.php'; 408 throw new Zend_Uri_Exception("Password \"$password\" is not a valid HTTP password."); 409 } 410 411 $oldPassword = $this->_password; 412 $this->_password = $password; 413 414 return $oldPassword; 415 } 416 417 /** 418 * Returns the domain or host IP portion of the URL, or FALSE if none. 419 * 420 * @return string 421 */ 422 public function getHost() 423 { 424 return strlen($this->_host) > 0 ? $this->_host : false; 425 } 426 427 /** 428 * Returns true if and only if the host string passes validation. If no host is passed, 429 * then the host contained in the instance variable is used. 430 * 431 * @param string $host The HTTP host 432 * @return boolean 433 * @uses Zend_Filter 434 */ 435 public function validateHost($host = null) 436 { 437 if ($host === null) { 438 $host = $this->_host; 439 } 440 441 // If the host is empty, then it is considered invalid 442 if (strlen($host) === 0) { 443 return false; 444 } 445 446 // Check the host against the allowed values; delegated to Zend_Filter. 447 $validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL); 448 449 return $validate->isValid($host); 450 } 451 452 /** 453 * Sets the host for the current URI, and returns the old host 454 * 455 * @param string $host The HTTP host 456 * @throws Zend_Uri_Exception When $host is nota valid HTTP host 457 * @return string 458 */ 459 public function setHost($host) 460 { 461 if ($this->validateHost($host) === false) { 462 require_once 'Zend/Uri/Exception.php'; 463 throw new Zend_Uri_Exception("Host \"$host\" is not a valid HTTP host"); 464 } 465 466 $oldHost = $this->_host; 467 $this->_host = $host; 468 469 return $oldHost; 470 } 471 472 /** 473 * Returns the TCP port, or FALSE if none. 474 * 475 * @return string 476 */ 477 public function getPort() 478 { 479 return strlen($this->_port) > 0 ? $this->_port : false; 480 } 481 482 /** 483 * Returns true if and only if the TCP port string passes validation. If no port is passed, 484 * then the port contained in the instance variable is used. 485 * 486 * @param string $port The HTTP port 487 * @return boolean 488 */ 489 public function validatePort($port = null) 490 { 491 if ($port === null) { 492 $port = $this->_port; 493 } 494 495 // If the port is empty, then it is considered valid 496 if (strlen($port) === 0) { 497 return true; 498 } 499 500 // Check the port against the allowed values 501 return ctype_digit((string) $port) and 1 <= $port and $port <= 65535; 502 } 503 504 /** 505 * Sets the port for the current URI, and returns the old port 506 * 507 * @param string $port The HTTP port 508 * @throws Zend_Uri_Exception When $port is not a valid HTTP port 509 * @return string 510 */ 511 public function setPort($port) 512 { 513 if ($this->validatePort($port) === false) { 514 require_once 'Zend/Uri/Exception.php'; 515 throw new Zend_Uri_Exception("Port \"$port\" is not a valid HTTP port."); 516 } 517 518 $oldPort = $this->_port; 519 $this->_port = $port; 520 521 return $oldPort; 522 } 523 524 /** 525 * Returns the path and filename portion of the URL, or FALSE if none. 526 * 527 * @return string 528 */ 529 public function getPath() 530 { 531 return strlen($this->_path) > 0 ? $this->_path : '/'; 532 } 533 534 /** 535 * Returns true if and only if the path string passes validation. If no path is passed, 536 * then the path contained in the instance variable is used. 537 * 538 * @param string $path The HTTP path 539 * @throws Zend_Uri_Exception When path validation fails 540 * @return boolean 541 */ 542 public function validatePath($path = null) 543 { 544 if ($path === null) { 545 $path = $this->_path; 546 } 547 548 // If the path is empty, then it is considered valid 549 if (strlen($path) === 0) { 550 return true; 551 } 552 553 // Determine whether the path is well-formed 554 $pattern = '/^' . $this->_regex['path'] . '$/'; 555 $status = @preg_match($pattern, $path); 556 if ($status === false) { 557 require_once 'Zend/Uri/Exception.php'; 558 throw new Zend_Uri_Exception('Internal error: path validation failed'); 559 } 560 561 return (boolean) $status; 562 } 563 564 /** 565 * Sets the path for the current URI, and returns the old path 566 * 567 * @param string $path The HTTP path 568 * @throws Zend_Uri_Exception When $path is not a valid HTTP path 569 * @return string 570 */ 571 public function setPath($path) 572 { 573 if ($this->validatePath($path) === false) { 574 require_once 'Zend/Uri/Exception.php'; 575 throw new Zend_Uri_Exception("Path \"$path\" is not a valid HTTP path"); 576 } 577 578 $oldPath = $this->_path; 579 $this->_path = $path; 580 581 return $oldPath; 582 } 583 584 /** 585 * Returns the query portion of the URL (after ?), or FALSE if none. 586 * 587 * @return string 588 */ 589 public function getQuery() 590 { 591 return strlen($this->_query) > 0 ? $this->_query : false; 592 } 593 594 /** 595 * Returns the query portion of the URL (after ?) as a 596 * key-value-array. If the query is empty an empty array 597 * is returned 598 * 599 * @return array 600 */ 601 public function getQueryAsArray() 602 { 603 $query = $this->getQuery(); 604 $querryArray = array(); 605 if ($query !== false) { 606 parse_str($query, $querryArray); 607 } 608 return $querryArray; 609 } 610 611 /** 612 * Returns true if and only if the query string passes validation. If no query is passed, 613 * then the query string contained in the instance variable is used. 614 * 615 * @param string $query The query to validate 616 * @throws Zend_Uri_Exception When query validation fails 617 * @return boolean 618 * @link http://www.faqs.org/rfcs/rfc2396.html 619 */ 620 public function validateQuery($query = null) 621 { 622 if ($query === null) { 623 $query = $this->_query; 624 } 625 626 // If query is empty, it is considered to be valid 627 if (strlen($query) === 0) { 628 return true; 629 } 630 631 // Determine whether the query is well-formed 632 $pattern = '/^' . $this->_regex['uric'] . '*$/'; 633 $status = @preg_match($pattern, $query); 634 if ($status === false) { 635 require_once 'Zend/Uri/Exception.php'; 636 throw new Zend_Uri_Exception('Internal error: query validation failed'); 637 } 638 639 return $status == 1; 640 } 641 642 /** 643 * Add or replace params in the query string for the current URI, and 644 * return the old query. 645 * 646 * @param array $queryParams 647 * @return string Old query string 648 */ 649 public function addReplaceQueryParameters(array $queryParams) 650 { 651 $queryParams = array_merge($this->getQueryAsArray(), $queryParams); 652 return $this->setQuery($queryParams); 653 } 654 655 /** 656 * Remove params in the query string for the current URI, and 657 * return the old query. 658 * 659 * @param array $queryParamKeys 660 * @return string Old query string 661 */ 662 public function removeQueryParameters(array $queryParamKeys) 663 { 664 $queryParams = array_diff_key($this->getQueryAsArray(), array_fill_keys($queryParamKeys, 0)); 665 return $this->setQuery($queryParams); 666 } 667 668 /** 669 * Set the query string for the current URI, and return the old query 670 * string This method accepts both strings and arrays. 671 * 672 * @param string|array $query The query string or array 673 * @throws Zend_Uri_Exception When $query is not a valid query string 674 * @return string Old query string 675 */ 676 public function setQuery($query) 677 { 678 $oldQuery = $this->_query; 679 680 // If query is empty, set an empty string 681 if (empty($query) === true) { 682 $this->_query = ''; 683 return $oldQuery; 684 } 685 686 // If query is an array, make a string out of it 687 if (is_array($query) === true) { 688 $query = http_build_query($query, '', '&'); 689 } else { 690 // If it is a string, make sure it is valid. If not parse and encode it 691 $query = (string) $query; 692 if ($this->validateQuery($query) === false) { 693 parse_str($query, $queryArray); 694 $query = http_build_query($queryArray, '', '&'); 695 } 696 } 697 698 // Make sure the query is valid, and set it 699 if ($this->validateQuery($query) === false) { 700 require_once 'Zend/Uri/Exception.php'; 701 throw new Zend_Uri_Exception("'$query' is not a valid query string"); 702 } 703 704 $this->_query = $query; 705 706 return $oldQuery; 707 } 708 709 /** 710 * Returns the fragment portion of the URL (after #), or FALSE if none. 711 * 712 * @return string|false 713 */ 714 public function getFragment() 715 { 716 return strlen($this->_fragment) > 0 ? $this->_fragment : false; 717 } 718 719 /** 720 * Returns true if and only if the fragment passes validation. If no fragment is passed, 721 * then the fragment contained in the instance variable is used. 722 * 723 * @param string $fragment Fragment of an URI 724 * @throws Zend_Uri_Exception When fragment validation fails 725 * @return boolean 726 * @link http://www.faqs.org/rfcs/rfc2396.html 727 */ 728 public function validateFragment($fragment = null) 729 { 730 if ($fragment === null) { 731 $fragment = $this->_fragment; 732 } 733 734 // If fragment is empty, it is considered to be valid 735 if (strlen($fragment) === 0) { 736 return true; 737 } 738 739 // Determine whether the fragment is well-formed 740 $pattern = '/^' . $this->_regex['uric'] . '*$/'; 741 $status = @preg_match($pattern, $fragment); 742 if ($status === false) { 743 require_once 'Zend/Uri/Exception.php'; 744 throw new Zend_Uri_Exception('Internal error: fragment validation failed'); 745 } 746 747 return (boolean) $status; 748 } 749 750 /** 751 * Sets the fragment for the current URI, and returns the old fragment 752 * 753 * @param string $fragment Fragment of the current URI 754 * @throws Zend_Uri_Exception When $fragment is not a valid HTTP fragment 755 * @return string 756 */ 757 public function setFragment($fragment) 758 { 759 if ($this->validateFragment($fragment) === false) { 760 require_once 'Zend/Uri/Exception.php'; 761 throw new Zend_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment"); 762 } 763 764 $oldFragment = $this->_fragment; 765 $this->_fragment = $fragment; 766 767 return $oldFragment; 768 } 769 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |