Namespaces

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • None
  • PHP

Classes

  • Context
  • FileUpload
  • Request
  • RequestFactory
  • Response
  • Session
  • SessionSection
  • Url
  • UrlScript
  • UserStorage

Interfaces

  • IRequest
  • IResponse
  • ISessionStorage
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  *
  6:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  */
 11: 
 12: namespace Nette\Http;
 13: 
 14: use Nette;
 15: 
 16: 
 17: 
 18: /**
 19:  * URI Syntax (RFC 3986).
 20:  *
 21:  * <pre>
 22:  * scheme  user  password  host  port  basePath   relativeUrl
 23:  *   |      |      |        |      |    |             |
 24:  * /--\   /--\ /------\ /-------\ /--\/--\/----------------------------\
 25:  * http://john:x0y17575@nette.org:8042/en/manual.php?name=param#fragment  <-- absoluteUrl
 26:  *        \__________________________/\____________/^\________/^\______/
 27:  *                     |                     |           |         |
 28:  *                 authority               path        query    fragment
 29:  * </pre>
 30:  *
 31:  * - authority:   [user[:password]@]host[:port]
 32:  * - hostUrl:     http://user:password@nette.org:8042
 33:  * - basePath:    /en/ (everything before relative URI not including the script name)
 34:  * - baseUrl:     http://user:password@nette.org:8042/en/
 35:  * - relativeUrl: manual.php
 36:  *
 37:  * @author     David Grudl
 38:  *
 39:  * @property   string $scheme
 40:  * @property   string $user
 41:  * @property   string $password
 42:  * @property   string $host
 43:  * @property   string $port
 44:  * @property   string $path
 45:  * @property   string $query
 46:  * @property   string $fragment
 47:  * @property-read string $absoluteUrl
 48:  * @property-read string $authority
 49:  * @property-read string $hostUrl
 50:  * @property-read string $basePath
 51:  * @property-read string $baseUrl
 52:  * @property-read string $relativeUrl
 53:  */
 54: class Url extends Nette\FreezableObject
 55: {
 56:     /** @var array */
 57:     public static $defaultPorts = array(
 58:         'http' => 80,
 59:         'https' => 443,
 60:         'ftp' => 21,
 61:         'news' => 119,
 62:         'nntp' => 119,
 63:     );
 64: 
 65:     /** @var string */
 66:     private $scheme = '';
 67: 
 68:     /** @var string */
 69:     private $user = '';
 70: 
 71:     /** @var string */
 72:     private $pass = '';
 73: 
 74:     /** @var string */
 75:     private $host = '';
 76: 
 77:     /** @var int */
 78:     private $port = NULL;
 79: 
 80:     /** @var string */
 81:     private $path = '';
 82: 
 83:     /** @var string */
 84:     private $query = '';
 85: 
 86:     /** @var string */
 87:     private $fragment = '';
 88: 
 89: 
 90: 
 91:     /**
 92:      * @param  string  URL
 93:      * @throws Nette\InvalidArgumentException
 94:      */
 95:     public function __construct($url = NULL)
 96:     {
 97:         if (is_string($url)) {
 98:             $parts = @parse_url($url); // @ - is escalated to exception
 99:             if ($parts === FALSE) {
100:                 throw new Nette\InvalidArgumentException("Malformed or unsupported URI '$url'.");
101:             }
102: 
103:             foreach ($parts as $key => $val) {
104:                 $this->$key = $val;
105:             }
106: 
107:             if (!$this->port && isset(self::$defaultPorts[$this->scheme])) {
108:                 $this->port = self::$defaultPorts[$this->scheme];
109:             }
110: 
111:             if ($this->path === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
112:                 $this->path = '/';
113:             }
114: 
115:         } elseif ($url instanceof self) {
116:             foreach ($this as $key => $val) {
117:                 $this->$key = $url->$key;
118:             }
119:         }
120:     }
121: 
122: 
123: 
124:     /**
125:      * Sets the scheme part of URI.
126:      * @param  string
127:      * @return Url  provides a fluent interface
128:      */
129:     public function setScheme($value)
130:     {
131:         $this->updating();
132:         $this->scheme = (string) $value;
133:         return $this;
134:     }
135: 
136: 
137: 
138:     /**
139:      * Returns the scheme part of URI.
140:      * @return string
141:      */
142:     public function getScheme()
143:     {
144:         return $this->scheme;
145:     }
146: 
147: 
148: 
149:     /**
150:      * Sets the user name part of URI.
151:      * @param  string
152:      * @return Url  provides a fluent interface
153:      */
154:     public function setUser($value)
155:     {
156:         $this->updating();
157:         $this->user = (string) $value;
158:         return $this;
159:     }
160: 
161: 
162: 
163:     /**
164:      * Returns the user name part of URI.
165:      * @return string
166:      */
167:     public function getUser()
168:     {
169:         return $this->user;
170:     }
171: 
172: 
173: 
174:     /**
175:      * Sets the password part of URI.
176:      * @param  string
177:      * @return Url  provides a fluent interface
178:      */
179:     public function setPassword($value)
180:     {
181:         $this->updating();
182:         $this->pass = (string) $value;
183:         return $this;
184:     }
185: 
186: 
187: 
188:     /**
189:      * Returns the password part of URI.
190:      * @return string
191:      */
192:     public function getPassword()
193:     {
194:         return $this->pass;
195:     }
196: 
197: 
198: 
199:     /**
200:      * Sets the host part of URI.
201:      * @param  string
202:      * @return Url  provides a fluent interface
203:      */
204:     public function setHost($value)
205:     {
206:         $this->updating();
207:         $this->host = (string) $value;
208:         return $this;
209:     }
210: 
211: 
212: 
213:     /**
214:      * Returns the host part of URI.
215:      * @return string
216:      */
217:     public function getHost()
218:     {
219:         return $this->host;
220:     }
221: 
222: 
223: 
224:     /**
225:      * Sets the port part of URI.
226:      * @param  string
227:      * @return Url  provides a fluent interface
228:      */
229:     public function setPort($value)
230:     {
231:         $this->updating();
232:         $this->port = (int) $value;
233:         return $this;
234:     }
235: 
236: 
237: 
238:     /**
239:      * Returns the port part of URI.
240:      * @return string
241:      */
242:     public function getPort()
243:     {
244:         return $this->port;
245:     }
246: 
247: 
248: 
249:     /**
250:      * Sets the path part of URI.
251:      * @param  string
252:      * @return Url  provides a fluent interface
253:      */
254:     public function setPath($value)
255:     {
256:         $this->updating();
257:         $this->path = (string) $value;
258:         return $this;
259:     }
260: 
261: 
262: 
263:     /**
264:      * Returns the path part of URI.
265:      * @return string
266:      */
267:     public function getPath()
268:     {
269:         return $this->path;
270:     }
271: 
272: 
273: 
274:     /**
275:      * Sets the query part of URI.
276:      * @param  string|array
277:      * @return Url  provides a fluent interface
278:      */
279:     public function setQuery($value)
280:     {
281:         $this->updating();
282:         $this->query = (string) (is_array($value) ? http_build_query($value, '', '&') : $value);
283:         return $this;
284:     }
285: 
286: 
287: 
288:     /**
289:      * Appends the query part of URI.
290:      * @param  string|array
291:      * @return void
292:      */
293:     public function appendQuery($value)
294:     {
295:         $this->updating();
296:         $value = (string) (is_array($value) ? http_build_query($value, '', '&') : $value);
297:         $this->query .= ($this->query === '' || $value === '') ? $value : '&' . $value;
298:     }
299: 
300: 
301: 
302:     /**
303:      * Returns the query part of URI.
304:      * @return string
305:      */
306:     public function getQuery()
307:     {
308:         return $this->query;
309:     }
310: 
311: 
312: 
313:     /**
314:      * Sets the fragment part of URI.
315:      * @param  string
316:      * @return Url  provides a fluent interface
317:      */
318:     public function setFragment($value)
319:     {
320:         $this->updating();
321:         $this->fragment = (string) $value;
322:         return $this;
323:     }
324: 
325: 
326: 
327:     /**
328:      * Returns the fragment part of URI.
329:      * @return string
330:      */
331:     public function getFragment()
332:     {
333:         return $this->fragment;
334:     }
335: 
336: 
337: 
338:     /**
339:      * Returns the entire URI including query string and fragment.
340:      * @return string
341:      */
342:     public function getAbsoluteUrl()
343:     {
344:         return $this->scheme . '://' . $this->getAuthority() . $this->path
345:             . ($this->query === '' ? '' : '?' . $this->query)
346:             . ($this->fragment === '' ? '' : '#' . $this->fragment);
347:     }
348: 
349: 
350: 
351:     /**
352:      * Returns the [user[:pass]@]host[:port] part of URI.
353:      * @return string
354:      */
355:     public function getAuthority()
356:     {
357:         $authority = $this->host;
358:         if ($this->port && isset(self::$defaultPorts[$this->scheme]) && $this->port !== self::$defaultPorts[$this->scheme]) {
359:             $authority .= ':' . $this->port;
360:         }
361: 
362:         if ($this->user !== '' && $this->scheme !== 'http' && $this->scheme !== 'https') {
363:             $authority = $this->user . ($this->pass === '' ? '' : ':' . $this->pass) . '@' . $authority;
364:         }
365: 
366:         return $authority;
367:     }
368: 
369: 
370: 
371:     /**
372:      * Returns the scheme and authority part of URI.
373:      * @return string
374:      */
375:     public function getHostUrl()
376:     {
377:         return $this->scheme . '://' . $this->getAuthority();
378:     }
379: 
380: 
381: 
382:     /**
383:      * Returns the base-path.
384:      * @return string
385:      */
386:     public function getBasePath()
387:     {
388:         $pos = strrpos($this->path, '/');
389:         return $pos === FALSE ? '' : substr($this->path, 0, $pos + 1);
390:     }
391: 
392: 
393: 
394:     /**
395:      * Returns the base-URI.
396:      * @return string
397:      */
398:     public function getBaseUrl()
399:     {
400:         return $this->scheme . '://' . $this->getAuthority() . $this->getBasePath();
401:     }
402: 
403: 
404: 
405:     /**
406:      * Returns the relative-URI.
407:      * @return string
408:      */
409:     public function getRelativeUrl()
410:     {
411:         return (string) substr($this->getAbsoluteUrl(), strlen($this->getBaseUrl()));
412:     }
413: 
414: 
415: 
416:     /**
417:      * URI comparsion (this object must be in canonical form).
418:      * @param  string
419:      * @return bool
420:      */
421:     public function isEqual($url)
422:     {
423:         // compare host + path
424:         $part = self::unescape(strtok($url, '?#'), '%/');
425:         if (strncmp($part, '//', 2) === 0) { // absolute URI without scheme
426:             if ($part !== '//' . $this->getAuthority() . $this->path) {
427:                 return FALSE;
428:             }
429: 
430:         } elseif (strncmp($part, '/', 1) === 0) { // absolute path
431:             if ($part !== $this->path) {
432:                 return FALSE;
433:             }
434: 
435:         } else {
436:             if ($part !== $this->scheme . '://' . $this->getAuthority() . $this->path) {
437:                 return FALSE;
438:             }
439:         }
440: 
441:         // compare query strings
442:         $part = preg_split('#[&;]#', self::unescape(strtr((string) strtok('?#'), '+', ' '), '%&;=+'));
443:         sort($part);
444:         $query = preg_split('#[&;]#', $this->query);
445:         sort($query);
446:         return $part === $query;
447:     }
448: 
449: 
450: 
451:     /**
452:      * Transform to canonical form.
453:      * @return void
454:      */
455:     public function canonicalize()
456:     {
457:         $this->updating();
458:         $this->path = $this->path === '' ? '/' : self::unescape($this->path, '%/');
459:         $this->host = strtolower(rawurldecode($this->host));
460:         $this->query = self::unescape(strtr($this->query, '+', ' '), '%&;=+');
461:     }
462: 
463: 
464: 
465:     /**
466:      * @return string
467:      */
468:     public function __toString()
469:     {
470:         return $this->getAbsoluteUrl();
471:     }
472: 
473: 
474: 
475:     /**
476:      * Similar to rawurldecode, but preserve reserved chars encoded.
477:      * @param  string to decode
478:      * @param  string reserved characters
479:      * @return string
480:      */
481:     public static function unescape($s, $reserved = '%;/?:@&=+$,')
482:     {
483:         // reserved (@see RFC 2396) = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
484:         // within a path segment, the characters "/", ";", "=", "?" are reserved
485:         // within a query component, the characters ";", "/", "?", ":", "@", "&", "=", "+", ",", "$" are reserved.
486:         preg_match_all('#(?<=%)[a-f0-9][a-f0-9]#i', $s, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
487:         foreach (array_reverse($matches) as $match) {
488:             $ch = chr(hexdec($match[0][0]));
489:             if (strpos($reserved, $ch) === FALSE) {
490:                 $s = substr_replace($s, $ch, $match[0][1] - 1, 3);
491:             }
492:         }
493:         return $s;
494:     }
495: 
496: 
497: 
498:     /** @deprecated */
499:     function getRelativeUri()
500:     {
501:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::getRelativeUrl() instead.', E_USER_WARNING);
502:         return $this->getRelativeUrl();
503:     }
504: 
505:     /** @deprecated */
506:     function getAbsoluteUri()
507:     {
508:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::getAbsoluteUrl() instead.', E_USER_WARNING);
509:         return $this->getAbsoluteUrl();
510:     }
511: 
512:     /** @deprecated */
513:     function getHostUri()
514:     {
515:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::getHostUrl() instead.', E_USER_WARNING);
516:         return $this->getHostUrl();
517:     }
518: 
519:     /** @deprecated */
520:     function getBaseUri()
521:     {
522:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::getBaseUrl() instead.', E_USER_WARNING);
523:         return $this->getBaseUrl();
524:     }
525: 
526: }
527: 
Nette Framework 2.0.7 API API documentation generated by ApiGen 2.8.0