Commit 041bd4245746832166f0d9959053ac4c7384c067
1 parent
04b5edc9
Add Net_URL 1.0.14 from PEAR (BSD-licensed).
git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@4439 c91229c3-7414-0410-bfa2-8a42b809f60b
Showing
1 changed file
with
410 additions
and
0 deletions
thirdparty/pear/Net/URL.php
0 → 100644
| 1 | +<?php | ||
| 2 | +// +-----------------------------------------------------------------------+ | ||
| 3 | +// | Copyright (c) 2002-2004, Richard Heyes | | ||
| 4 | +// | All rights reserved. | | ||
| 5 | +// | | | ||
| 6 | +// | Redistribution and use in source and binary forms, with or without | | ||
| 7 | +// | modification, are permitted provided that the following conditions | | ||
| 8 | +// | are met: | | ||
| 9 | +// | | | ||
| 10 | +// | o Redistributions of source code must retain the above copyright | | ||
| 11 | +// | notice, this list of conditions and the following disclaimer. | | ||
| 12 | +// | o Redistributions in binary form must reproduce the above copyright | | ||
| 13 | +// | notice, this list of conditions and the following disclaimer in the | | ||
| 14 | +// | documentation and/or other materials provided with the distribution.| | ||
| 15 | +// | o The names of the authors may not be used to endorse or promote | | ||
| 16 | +// | products derived from this software without specific prior written | | ||
| 17 | +// | permission. | | ||
| 18 | +// | | | ||
| 19 | +// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | | ||
| 20 | +// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | | ||
| 21 | +// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | | ||
| 22 | +// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | | ||
| 23 | +// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | | ||
| 24 | +// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | | ||
| 25 | +// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | ||
| 26 | +// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | ||
| 27 | +// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | ||
| 28 | +// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | | ||
| 29 | +// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | ||
| 30 | +// | | | ||
| 31 | +// +-----------------------------------------------------------------------+ | ||
| 32 | +// | Author: Richard Heyes <richard at php net> | | ||
| 33 | +// +-----------------------------------------------------------------------+ | ||
| 34 | +// | ||
| 35 | +// $Id$ | ||
| 36 | +// | ||
| 37 | +// Net_URL Class | ||
| 38 | + | ||
| 39 | +class Net_URL | ||
| 40 | +{ | ||
| 41 | + /** | ||
| 42 | + * Full url | ||
| 43 | + * @var string | ||
| 44 | + */ | ||
| 45 | + var $url; | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * Protocol | ||
| 49 | + * @var string | ||
| 50 | + */ | ||
| 51 | + var $protocol; | ||
| 52 | + | ||
| 53 | + /** | ||
| 54 | + * Username | ||
| 55 | + * @var string | ||
| 56 | + */ | ||
| 57 | + var $username; | ||
| 58 | + | ||
| 59 | + /** | ||
| 60 | + * Password | ||
| 61 | + * @var string | ||
| 62 | + */ | ||
| 63 | + var $password; | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * Host | ||
| 67 | + * @var string | ||
| 68 | + */ | ||
| 69 | + var $host; | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Port | ||
| 73 | + * @var integer | ||
| 74 | + */ | ||
| 75 | + var $port; | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * Path | ||
| 79 | + * @var string | ||
| 80 | + */ | ||
| 81 | + var $path; | ||
| 82 | + | ||
| 83 | + /** | ||
| 84 | + * Query string | ||
| 85 | + * @var array | ||
| 86 | + */ | ||
| 87 | + var $querystring; | ||
| 88 | + | ||
| 89 | + /** | ||
| 90 | + * Anchor | ||
| 91 | + * @var string | ||
| 92 | + */ | ||
| 93 | + var $anchor; | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * Whether to use [] | ||
| 97 | + * @var bool | ||
| 98 | + */ | ||
| 99 | + var $useBrackets; | ||
| 100 | + | ||
| 101 | + /** | ||
| 102 | + * PHP4 Constructor | ||
| 103 | + * | ||
| 104 | + * @see __construct() | ||
| 105 | + */ | ||
| 106 | + function Net_URL($url = null, $useBrackets = true) | ||
| 107 | + { | ||
| 108 | + $this->__construct($url, $useBrackets); | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + /** | ||
| 112 | + * PHP5 Constructor | ||
| 113 | + * | ||
| 114 | + * Parses the given url and stores the various parts | ||
| 115 | + * Defaults are used in certain cases | ||
| 116 | + * | ||
| 117 | + * @param string $url Optional URL | ||
| 118 | + * @param bool $useBrackets Whether to use square brackets when | ||
| 119 | + * multiple querystrings with the same name | ||
| 120 | + * exist | ||
| 121 | + */ | ||
| 122 | + function __construct($url = null, $useBrackets = true) | ||
| 123 | + { | ||
| 124 | + $HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; | ||
| 125 | + | ||
| 126 | + $this->useBrackets = $useBrackets; | ||
| 127 | + $this->url = $url; | ||
| 128 | + $this->user = ''; | ||
| 129 | + $this->pass = ''; | ||
| 130 | + $this->host = ''; | ||
| 131 | + $this->port = 80; | ||
| 132 | + $this->path = ''; | ||
| 133 | + $this->querystring = array(); | ||
| 134 | + $this->anchor = ''; | ||
| 135 | + | ||
| 136 | + // Only use defaults if not an absolute URL given | ||
| 137 | + if (!preg_match('/^[a-z0-9]+:\/\//i', $url)) { | ||
| 138 | + | ||
| 139 | + $this->protocol = (@$HTTP_SERVER_VARS['HTTPS'] == 'on' ? 'https' : 'http'); | ||
| 140 | + | ||
| 141 | + /** | ||
| 142 | + * Figure out host/port | ||
| 143 | + */ | ||
| 144 | + if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) AND preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) { | ||
| 145 | + $host = $matches[1]; | ||
| 146 | + if (!empty($matches[3])) { | ||
| 147 | + $port = $matches[3]; | ||
| 148 | + } else { | ||
| 149 | + $port = $this->getStandardPort($this->protocol); | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + $this->user = ''; | ||
| 154 | + $this->pass = ''; | ||
| 155 | + $this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost'); | ||
| 156 | + $this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol)); | ||
| 157 | + $this->path = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/'; | ||
| 158 | + $this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null; | ||
| 159 | + $this->anchor = ''; | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + // Parse the url and store the various parts | ||
| 163 | + if (!empty($url)) { | ||
| 164 | + $urlinfo = parse_url($url); | ||
| 165 | + | ||
| 166 | + // Default querystring | ||
| 167 | + $this->querystring = array(); | ||
| 168 | + | ||
| 169 | + foreach ($urlinfo as $key => $value) { | ||
| 170 | + switch ($key) { | ||
| 171 | + case 'scheme': | ||
| 172 | + $this->protocol = $value; | ||
| 173 | + $this->port = $this->getStandardPort($value); | ||
| 174 | + break; | ||
| 175 | + | ||
| 176 | + case 'user': | ||
| 177 | + case 'pass': | ||
| 178 | + case 'host': | ||
| 179 | + case 'port': | ||
| 180 | + $this->$key = $value; | ||
| 181 | + break; | ||
| 182 | + | ||
| 183 | + case 'path': | ||
| 184 | + if ($value{0} == '/') { | ||
| 185 | + $this->path = $value; | ||
| 186 | + } else { | ||
| 187 | + $path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path); | ||
| 188 | + $this->path = sprintf('%s/%s', $path, $value); | ||
| 189 | + } | ||
| 190 | + break; | ||
| 191 | + | ||
| 192 | + case 'query': | ||
| 193 | + $this->querystring = $this->_parseRawQueryString($value); | ||
| 194 | + break; | ||
| 195 | + | ||
| 196 | + case 'fragment': | ||
| 197 | + $this->anchor = $value; | ||
| 198 | + break; | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | + } | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + /** | ||
| 205 | + * Returns full url | ||
| 206 | + * | ||
| 207 | + * @return string Full url | ||
| 208 | + * @access public | ||
| 209 | + */ | ||
| 210 | + function getURL() | ||
| 211 | + { | ||
| 212 | + $querystring = $this->getQueryString(); | ||
| 213 | + | ||
| 214 | + $this->url = $this->protocol . '://' | ||
| 215 | + . $this->user . (!empty($this->pass) ? ':' : '') | ||
| 216 | + . $this->pass . (!empty($this->user) ? '@' : '') | ||
| 217 | + . $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port) | ||
| 218 | + . $this->path | ||
| 219 | + . (!empty($querystring) ? '?' . $querystring : '') | ||
| 220 | + . (!empty($this->anchor) ? '#' . $this->anchor : ''); | ||
| 221 | + | ||
| 222 | + return $this->url; | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + /** | ||
| 226 | + * Adds a querystring item | ||
| 227 | + * | ||
| 228 | + * @param string $name Name of item | ||
| 229 | + * @param string $value Value of item | ||
| 230 | + * @param bool $preencoded Whether value is urlencoded or not, default = not | ||
| 231 | + * @access public | ||
| 232 | + */ | ||
| 233 | + function addQueryString($name, $value, $preencoded = false) | ||
| 234 | + { | ||
| 235 | + if ($preencoded) { | ||
| 236 | + $this->querystring[$name] = $value; | ||
| 237 | + } else { | ||
| 238 | + $this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value); | ||
| 239 | + } | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + /** | ||
| 243 | + * Removes a querystring item | ||
| 244 | + * | ||
| 245 | + * @param string $name Name of item | ||
| 246 | + * @access public | ||
| 247 | + */ | ||
| 248 | + function removeQueryString($name) | ||
| 249 | + { | ||
| 250 | + if (isset($this->querystring[$name])) { | ||
| 251 | + unset($this->querystring[$name]); | ||
| 252 | + } | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + /** | ||
| 256 | + * Sets the querystring to literally what you supply | ||
| 257 | + * | ||
| 258 | + * @param string $querystring The querystring data. Should be of the format foo=bar&x=y etc | ||
| 259 | + * @access public | ||
| 260 | + */ | ||
| 261 | + function addRawQueryString($querystring) | ||
| 262 | + { | ||
| 263 | + $this->querystring = $this->_parseRawQueryString($querystring); | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + /** | ||
| 267 | + * Returns flat querystring | ||
| 268 | + * | ||
| 269 | + * @return string Querystring | ||
| 270 | + * @access public | ||
| 271 | + */ | ||
| 272 | + function getQueryString() | ||
| 273 | + { | ||
| 274 | + if (!empty($this->querystring)) { | ||
| 275 | + foreach ($this->querystring as $name => $value) { | ||
| 276 | + if (is_array($value)) { | ||
| 277 | + foreach ($value as $k => $v) { | ||
| 278 | + $querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v); | ||
| 279 | + } | ||
| 280 | + } elseif (!is_null($value)) { | ||
| 281 | + $querystring[] = $name . '=' . $value; | ||
| 282 | + } else { | ||
| 283 | + $querystring[] = $name; | ||
| 284 | + } | ||
| 285 | + } | ||
| 286 | + $querystring = implode(ini_get('arg_separator.output'), $querystring); | ||
| 287 | + } else { | ||
| 288 | + $querystring = ''; | ||
| 289 | + } | ||
| 290 | + | ||
| 291 | + return $querystring; | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + /** | ||
| 295 | + * Parses raw querystring and returns an array of it | ||
| 296 | + * | ||
| 297 | + * @param string $querystring The querystring to parse | ||
| 298 | + * @return array An array of the querystring data | ||
| 299 | + * @access private | ||
| 300 | + */ | ||
| 301 | + function _parseRawQuerystring($querystring) | ||
| 302 | + { | ||
| 303 | + $parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY); | ||
| 304 | + $return = array(); | ||
| 305 | + | ||
| 306 | + foreach ($parts as $part) { | ||
| 307 | + if (strpos($part, '=') !== false) { | ||
| 308 | + $value = substr($part, strpos($part, '=') + 1); | ||
| 309 | + $key = substr($part, 0, strpos($part, '=')); | ||
| 310 | + } else { | ||
| 311 | + $value = null; | ||
| 312 | + $key = $part; | ||
| 313 | + } | ||
| 314 | + if (substr($key, -2) == '[]') { | ||
| 315 | + $key = substr($key, 0, -2); | ||
| 316 | + if (@!is_array($return[$key])) { | ||
| 317 | + $return[$key] = array(); | ||
| 318 | + $return[$key][] = $value; | ||
| 319 | + } else { | ||
| 320 | + $return[$key][] = $value; | ||
| 321 | + } | ||
| 322 | + } elseif (!$this->useBrackets AND !empty($return[$key])) { | ||
| 323 | + $return[$key] = (array)$return[$key]; | ||
| 324 | + $return[$key][] = $value; | ||
| 325 | + } else { | ||
| 326 | + $return[$key] = $value; | ||
| 327 | + } | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + return $return; | ||
| 331 | + } | ||
| 332 | + | ||
| 333 | + /** | ||
| 334 | + * Resolves //, ../ and ./ from a path and returns | ||
| 335 | + * the result. Eg: | ||
| 336 | + * | ||
| 337 | + * /foo/bar/../boo.php => /foo/boo.php | ||
| 338 | + * /foo/bar/../../boo.php => /boo.php | ||
| 339 | + * /foo/bar/.././/boo.php => /foo/boo.php | ||
| 340 | + * | ||
| 341 | + * This method can also be called statically. | ||
| 342 | + * | ||
| 343 | + * @param string $url URL path to resolve | ||
| 344 | + * @return string The result | ||
| 345 | + */ | ||
| 346 | + function resolvePath($path) | ||
| 347 | + { | ||
| 348 | + $path = explode('/', str_replace('//', '/', $path)); | ||
| 349 | + | ||
| 350 | + for ($i=0; $i<count($path); $i++) { | ||
| 351 | + if ($path[$i] == '.') { | ||
| 352 | + unset($path[$i]); | ||
| 353 | + $path = array_values($path); | ||
| 354 | + $i--; | ||
| 355 | + | ||
| 356 | + } elseif ($path[$i] == '..' AND ($i > 1 OR ($i == 1 AND $path[0] != '') ) ) { | ||
| 357 | + unset($path[$i]); | ||
| 358 | + unset($path[$i-1]); | ||
| 359 | + $path = array_values($path); | ||
| 360 | + $i -= 2; | ||
| 361 | + | ||
| 362 | + } elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') { | ||
| 363 | + unset($path[$i]); | ||
| 364 | + $path = array_values($path); | ||
| 365 | + $i--; | ||
| 366 | + | ||
| 367 | + } else { | ||
| 368 | + continue; | ||
| 369 | + } | ||
| 370 | + } | ||
| 371 | + | ||
| 372 | + return implode('/', $path); | ||
| 373 | + } | ||
| 374 | + | ||
| 375 | + /** | ||
| 376 | + * Returns the standard port number for a protocol | ||
| 377 | + * | ||
| 378 | + * @param string $scheme The protocol to lookup | ||
| 379 | + * @return integer Port number or NULL if no scheme matches | ||
| 380 | + * | ||
| 381 | + * @author Philippe Jausions <Philippe.Jausions@11abacus.com> | ||
| 382 | + */ | ||
| 383 | + function getStandardPort($scheme) | ||
| 384 | + { | ||
| 385 | + switch (strtolower($scheme)) { | ||
| 386 | + case 'http': return 80; | ||
| 387 | + case 'https': return 443; | ||
| 388 | + case 'ftp': return 21; | ||
| 389 | + case 'imap': return 143; | ||
| 390 | + case 'imaps': return 993; | ||
| 391 | + case 'pop3': return 110; | ||
| 392 | + case 'pop3s': return 995; | ||
| 393 | + default: return null; | ||
| 394 | + } | ||
| 395 | + } | ||
| 396 | + | ||
| 397 | + /** | ||
| 398 | + * Forces the URL to a particular protocol | ||
| 399 | + * | ||
| 400 | + * @param string $protocol Protocol to force the URL to | ||
| 401 | + * @param integer $port Optional port (standard port is used by default) | ||
| 402 | + */ | ||
| 403 | + function setProtocol($protocol, $port = null) | ||
| 404 | + { | ||
| 405 | + $this->protocol = $protocol; | ||
| 406 | + $this->port = is_null($port) ? $this->getStandardPort() : $port; | ||
| 407 | + } | ||
| 408 | + | ||
| 409 | +} | ||
| 410 | +?> |