|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00025 require_once 'Zend/Uri.php'; 00026 00030 require_once 'Zend/Validate/Hostname.php'; 00031 00041 class Zend_Uri_Http extends Zend_Uri 00042 { 00046 const CHAR_ALNUM = 'A-Za-z0-9'; 00047 const CHAR_MARK = '-_.!~*\'()\[\]'; 00048 const CHAR_RESERVED = ';\/?:@&=+$,'; 00049 const CHAR_SEGMENT = ':@&=+$,;'; 00050 const CHAR_UNWISE = '{}|\\\\^`'; 00051 00057 protected $_username = ''; 00058 00064 protected $_password = ''; 00065 00071 protected $_host = ''; 00072 00078 protected $_port = ''; 00079 00085 protected $_path = ''; 00086 00092 protected $_query = ''; 00093 00099 protected $_fragment = ''; 00100 00106 protected $_regex = array(); 00107 00116 protected function __construct($scheme, $schemeSpecific = '') 00117 { 00118 // Set the scheme 00119 $this->_scheme = $scheme; 00120 00121 // Set up grammar rules for validation via regular expressions. These 00122 // are to be used with slash-delimited regular expression strings. 00123 00124 // Escaped special characters (eg. '%25' for '%') 00125 $this->_regex['escaped'] = '%[[:xdigit:]]{2}'; 00126 00127 // Unreserved characters 00128 $this->_regex['unreserved'] = '[' . self::CHAR_ALNUM . self::CHAR_MARK . ']'; 00129 00130 // Segment can use escaped, unreserved or a set of additional chars 00131 $this->_regex['segment'] = '(?:' . $this->_regex['escaped'] . '|[' . 00132 self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_SEGMENT . '])*'; 00133 00134 // Path can be a series of segmets char strings seperated by '/' 00135 $this->_regex['path'] = '(?:\/(?:' . $this->_regex['segment'] . ')?)+'; 00136 00137 // URI characters can be escaped, alphanumeric, mark or reserved chars 00138 $this->_regex['uric'] = '(?:' . $this->_regex['escaped'] . '|[' . 00139 self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_RESERVED . 00140 00141 // If unwise chars are allowed, add them to the URI chars class 00142 (self::$_config['allow_unwise'] ? self::CHAR_UNWISE : '') . '])'; 00143 00144 // If no scheme-specific part was supplied, the user intends to create 00145 // a new URI with this object. No further parsing is required. 00146 if (strlen($schemeSpecific) === 0) { 00147 return; 00148 } 00149 00150 // Parse the scheme-specific URI parts into the instance variables. 00151 $this->_parseUri($schemeSpecific); 00152 00153 // Validate the URI 00154 if ($this->valid() === false) { 00155 require_once 'Zend/Uri/Exception.php'; 00156 throw new Zend_Uri_Exception('Invalid URI supplied'); 00157 } 00158 } 00159 00170 public static function fromString($uri) 00171 { 00172 if (is_string($uri) === false) { 00173 require_once 'Zend/Uri/Exception.php'; 00174 throw new Zend_Uri_Exception('$uri is not a string'); 00175 } 00176 00177 $uri = explode(':', $uri, 2); 00178 $scheme = strtolower($uri[0]); 00179 $schemeSpecific = isset($uri[1]) === true ? $uri[1] : ''; 00180 00181 if (in_array($scheme, array('http', 'https')) === false) { 00182 require_once 'Zend/Uri/Exception.php'; 00183 throw new Zend_Uri_Exception("Invalid scheme: '$scheme'"); 00184 } 00185 00186 $schemeHandler = new Zend_Uri_Http($scheme, $schemeSpecific); 00187 return $schemeHandler; 00188 } 00189 00198 protected function _parseUri($schemeSpecific) 00199 { 00200 // High-level decomposition parser 00201 $pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~'; 00202 $status = @preg_match($pattern, $schemeSpecific, $matches); 00203 if ($status === false) { 00204 require_once 'Zend/Uri/Exception.php'; 00205 throw new Zend_Uri_Exception('Internal error: scheme-specific decomposition failed'); 00206 } 00207 00208 // Failed decomposition; no further processing needed 00209 if ($status === false) { 00210 return; 00211 } 00212 00213 // Save URI components that need no further decomposition 00214 $this->_path = isset($matches[4]) === true ? $matches[4] : ''; 00215 $this->_query = isset($matches[6]) === true ? $matches[6] : ''; 00216 $this->_fragment = isset($matches[8]) === true ? $matches[8] : ''; 00217 00218 // Additional decomposition to get username, password, host, and port 00219 $combo = isset($matches[3]) === true ? $matches[3] : ''; 00220 $pattern = '~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~'; 00221 $status = @preg_match($pattern, $combo, $matches); 00222 if ($status === false) { 00223 require_once 'Zend/Uri/Exception.php'; 00224 throw new Zend_Uri_Exception('Internal error: authority decomposition failed'); 00225 } 00226 00227 // Failed decomposition; no further processing needed 00228 if ($status === false) { 00229 return; 00230 } 00231 00232 // Save remaining URI components 00233 $this->_username = isset($matches[2]) === true ? $matches[2] : ''; 00234 $this->_password = isset($matches[4]) === true ? $matches[4] : ''; 00235 $this->_host = isset($matches[5]) === true ? $matches[5] : ''; 00236 $this->_port = isset($matches[7]) === true ? $matches[7] : ''; 00237 00238 } 00239 00247 public function getUri() 00248 { 00249 if ($this->valid() === false) { 00250 require_once 'Zend/Uri/Exception.php'; 00251 throw new Zend_Uri_Exception('One or more parts of the URI are invalid'); 00252 } 00253 00254 $password = strlen($this->_password) > 0 ? ":$this->_password" : ''; 00255 $auth = strlen($this->_username) > 0 ? "$this->_username$password@" : ''; 00256 $port = strlen($this->_port) > 0 ? ":$this->_port" : ''; 00257 $query = strlen($this->_query) > 0 ? "?$this->_query" : ''; 00258 $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : ''; 00259 00260 return $this->_scheme 00261 . '://' 00262 . $auth 00263 . $this->_host 00264 . $port 00265 . $this->_path 00266 . $query 00267 . $fragment; 00268 } 00269 00276 public function valid() 00277 { 00278 // Return true if and only if all parts of the URI have passed validation 00279 return $this->validateUsername() 00280 and $this->validatePassword() 00281 and $this->validateHost() 00282 and $this->validatePort() 00283 and $this->validatePath() 00284 and $this->validateQuery() 00285 and $this->validateFragment(); 00286 } 00287 00293 public function getUsername() 00294 { 00295 return strlen($this->_username) > 0 ? $this->_username : false; 00296 } 00297 00307 public function validateUsername($username = null) 00308 { 00309 if ($username === null) { 00310 $username = $this->_username; 00311 } 00312 00313 // If the username is empty, then it is considered valid 00314 if (strlen($username) === 0) { 00315 return true; 00316 } 00317 00318 // Check the username against the allowed values 00319 $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' . 00320 self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $username); 00321 00322 if ($status === false) { 00323 require_once 'Zend/Uri/Exception.php'; 00324 throw new Zend_Uri_Exception('Internal error: username validation failed'); 00325 } 00326 00327 return $status === 1; 00328 } 00329 00337 public function setUsername($username) 00338 { 00339 if ($this->validateUsername($username) === false) { 00340 require_once 'Zend/Uri/Exception.php'; 00341 throw new Zend_Uri_Exception("Username \"$username\" is not a valid HTTP username"); 00342 } 00343 00344 $oldUsername = $this->_username; 00345 $this->_username = $username; 00346 00347 return $oldUsername; 00348 } 00349 00355 public function getPassword() 00356 { 00357 return strlen($this->_password) > 0 ? $this->_password : false; 00358 } 00359 00369 public function validatePassword($password = null) 00370 { 00371 if ($password === null) { 00372 $password = $this->_password; 00373 } 00374 00375 // If the password is empty, then it is considered valid 00376 if (strlen($password) === 0) { 00377 return true; 00378 } 00379 00380 // If the password is nonempty, but there is no username, then it is considered invalid 00381 if (strlen($password) > 0 and strlen($this->_username) === 0) { 00382 return false; 00383 } 00384 00385 // Check the password against the allowed values 00386 $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' . 00387 self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $password); 00388 00389 if ($status === false) { 00390 require_once 'Zend/Uri/Exception.php'; 00391 throw new Zend_Uri_Exception('Internal error: password validation failed.'); 00392 } 00393 00394 return $status == 1; 00395 } 00396 00404 public function setPassword($password) 00405 { 00406 if ($this->validatePassword($password) === false) { 00407 require_once 'Zend/Uri/Exception.php'; 00408 throw new Zend_Uri_Exception("Password \"$password\" is not a valid HTTP password."); 00409 } 00410 00411 $oldPassword = $this->_password; 00412 $this->_password = $password; 00413 00414 return $oldPassword; 00415 } 00416 00422 public function getHost() 00423 { 00424 return strlen($this->_host) > 0 ? $this->_host : false; 00425 } 00426 00435 public function validateHost($host = null) 00436 { 00437 if ($host === null) { 00438 $host = $this->_host; 00439 } 00440 00441 // If the host is empty, then it is considered invalid 00442 if (strlen($host) === 0) { 00443 return false; 00444 } 00445 00446 // Check the host against the allowed values; delegated to Zend_Filter. 00447 $validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL); 00448 00449 return $validate->isValid($host); 00450 } 00451 00459 public function setHost($host) 00460 { 00461 if ($this->validateHost($host) === false) { 00462 require_once 'Zend/Uri/Exception.php'; 00463 throw new Zend_Uri_Exception("Host \"$host\" is not a valid HTTP host"); 00464 } 00465 00466 $oldHost = $this->_host; 00467 $this->_host = $host; 00468 00469 return $oldHost; 00470 } 00471 00477 public function getPort() 00478 { 00479 return strlen($this->_port) > 0 ? $this->_port : false; 00480 } 00481 00489 public function validatePort($port = null) 00490 { 00491 if ($port === null) { 00492 $port = $this->_port; 00493 } 00494 00495 // If the port is empty, then it is considered valid 00496 if (strlen($port) === 0) { 00497 return true; 00498 } 00499 00500 // Check the port against the allowed values 00501 return ctype_digit((string) $port) and 1 <= $port and $port <= 65535; 00502 } 00503 00511 public function setPort($port) 00512 { 00513 if ($this->validatePort($port) === false) { 00514 require_once 'Zend/Uri/Exception.php'; 00515 throw new Zend_Uri_Exception("Port \"$port\" is not a valid HTTP port."); 00516 } 00517 00518 $oldPort = $this->_port; 00519 $this->_port = $port; 00520 00521 return $oldPort; 00522 } 00523 00529 public function getPath() 00530 { 00531 return strlen($this->_path) > 0 ? $this->_path : '/'; 00532 } 00533 00542 public function validatePath($path = null) 00543 { 00544 if ($path === null) { 00545 $path = $this->_path; 00546 } 00547 00548 // If the path is empty, then it is considered valid 00549 if (strlen($path) === 0) { 00550 return true; 00551 } 00552 00553 // Determine whether the path is well-formed 00554 $pattern = '/^' . $this->_regex['path'] . '$/'; 00555 $status = @preg_match($pattern, $path); 00556 if ($status === false) { 00557 require_once 'Zend/Uri/Exception.php'; 00558 throw new Zend_Uri_Exception('Internal error: path validation failed'); 00559 } 00560 00561 return (boolean) $status; 00562 } 00563 00571 public function setPath($path) 00572 { 00573 if ($this->validatePath($path) === false) { 00574 require_once 'Zend/Uri/Exception.php'; 00575 throw new Zend_Uri_Exception("Path \"$path\" is not a valid HTTP path"); 00576 } 00577 00578 $oldPath = $this->_path; 00579 $this->_path = $path; 00580 00581 return $oldPath; 00582 } 00583 00589 public function getQuery() 00590 { 00591 return strlen($this->_query) > 0 ? $this->_query : false; 00592 } 00593 00601 public function getQueryAsArray() 00602 { 00603 $query = $this->getQuery(); 00604 $querryArray = array(); 00605 if ($query !== false) { 00606 parse_str($query, $querryArray); 00607 } 00608 return $querryArray; 00609 } 00610 00620 public function validateQuery($query = null) 00621 { 00622 if ($query === null) { 00623 $query = $this->_query; 00624 } 00625 00626 // If query is empty, it is considered to be valid 00627 if (strlen($query) === 0) { 00628 return true; 00629 } 00630 00631 // Determine whether the query is well-formed 00632 $pattern = '/^' . $this->_regex['uric'] . '*$/'; 00633 $status = @preg_match($pattern, $query); 00634 if ($status === false) { 00635 require_once 'Zend/Uri/Exception.php'; 00636 throw new Zend_Uri_Exception('Internal error: query validation failed'); 00637 } 00638 00639 return $status == 1; 00640 } 00641 00649 public function addReplaceQueryParameters(array $queryParams) 00650 { 00651 $queryParams = array_merge($this->getQueryAsArray(), $queryParams); 00652 return $this->setQuery($queryParams); 00653 } 00654 00662 public function removeQueryParameters(array $queryParamKeys) 00663 { 00664 $queryParams = array_diff_key($this->getQueryAsArray(), array_fill_keys($queryParamKeys, 0)); 00665 return $this->setQuery($queryParams); 00666 } 00667 00676 public function setQuery($query) 00677 { 00678 $oldQuery = $this->_query; 00679 00680 // If query is empty, set an empty string 00681 if (empty($query) === true) { 00682 $this->_query = ''; 00683 return $oldQuery; 00684 } 00685 00686 // If query is an array, make a string out of it 00687 if (is_array($query) === true) { 00688 $query = http_build_query($query, '', '&'); 00689 } else { 00690 // If it is a string, make sure it is valid. If not parse and encode it 00691 $query = (string) $query; 00692 if ($this->validateQuery($query) === false) { 00693 parse_str($query, $queryArray); 00694 $query = http_build_query($queryArray, '', '&'); 00695 } 00696 } 00697 00698 // Make sure the query is valid, and set it 00699 if ($this->validateQuery($query) === false) { 00700 require_once 'Zend/Uri/Exception.php'; 00701 throw new Zend_Uri_Exception("'$query' is not a valid query string"); 00702 } 00703 00704 $this->_query = $query; 00705 00706 return $oldQuery; 00707 } 00708 00714 public function getFragment() 00715 { 00716 return strlen($this->_fragment) > 0 ? $this->_fragment : false; 00717 } 00718 00728 public function validateFragment($fragment = null) 00729 { 00730 if ($fragment === null) { 00731 $fragment = $this->_fragment; 00732 } 00733 00734 // If fragment is empty, it is considered to be valid 00735 if (strlen($fragment) === 0) { 00736 return true; 00737 } 00738 00739 // Determine whether the fragment is well-formed 00740 $pattern = '/^' . $this->_regex['uric'] . '*$/'; 00741 $status = @preg_match($pattern, $fragment); 00742 if ($status === false) { 00743 require_once 'Zend/Uri/Exception.php'; 00744 throw new Zend_Uri_Exception('Internal error: fragment validation failed'); 00745 } 00746 00747 return (boolean) $status; 00748 } 00749 00757 public function setFragment($fragment) 00758 { 00759 if ($this->validateFragment($fragment) === false) { 00760 require_once 'Zend/Uri/Exception.php'; 00761 throw new Zend_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment"); 00762 } 00763 00764 $oldFragment = $this->_fragment; 00765 $this->_fragment = $fragment; 00766 00767 return $oldFragment; 00768 } 00769 }