123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- <?php
- namespace PicoFeed\Client;
- /**
- * URL class.
- *
- * @author Frederic Guillot
- */
- class Url
- {
- /**
- * URL.
- *
- * @var string
- */
- private $url = '';
- /**
- * URL components.
- *
- * @var array
- */
- private $components = array();
- /**
- * Constructor.
- *
- * @param string $url URL
- */
- public function __construct($url)
- {
- $this->url = $url;
- $this->components = parse_url($url) ?: array();
- // Issue with PHP < 5.4.7 and protocol relative url
- if (version_compare(PHP_VERSION, '5.4.7', '<') && $this->isProtocolRelative()) {
- $pos = strpos($this->components['path'], '/', 2);
- if ($pos === false) {
- $pos = strlen($this->components['path']);
- }
- $this->components['host'] = substr($this->components['path'], 2, $pos - 2);
- $this->components['path'] = substr($this->components['path'], $pos);
- }
- }
- /**
- * Shortcut method to get an absolute url from relative url.
- *
- * @static
- * @param mixed $item_url Unknown url (can be relative or not)
- * @param mixed $website_url Website url
- * @return string
- */
- public static function resolve($item_url, $website_url)
- {
- $link = is_string($item_url) ? new self($item_url) : $item_url;
- $website = is_string($website_url) ? new self($website_url) : $website_url;
- if ($link->isRelativeUrl()) {
- if ($link->isRelativePath()) {
- return $link->getAbsoluteUrl($website->getBaseUrl($website->getBasePath()));
- }
- return $link->getAbsoluteUrl($website->getBaseUrl());
- } elseif ($link->isProtocolRelative()) {
- $link->setScheme($website->getScheme());
- }
- return $link->getAbsoluteUrl();
- }
- /**
- * Shortcut method to get a base url.
- *
- * @static
- * @param string $url
- * @return string
- */
- public static function base($url)
- {
- $link = new self($url);
- return $link->getBaseUrl();
- }
- /**
- * Get the base URL.
- *
- * @param string $suffix Add a suffix to the url
- * @return string
- */
- public function getBaseUrl($suffix = '')
- {
- return $this->hasHost() ? $this->getScheme('://').$this->getHost().$this->getPort(':').$suffix : '';
- }
- /**
- * Get the absolute URL.
- *
- * @param string $base_url Use this url as base url
- * @return string
- */
- public function getAbsoluteUrl($base_url = '')
- {
- if ($base_url) {
- $base = new self($base_url);
- $url = $base->getAbsoluteUrl().substr($this->getFullPath(), 1);
- } else {
- $url = $this->hasHost() ? $this->getBaseUrl().$this->getFullPath() : '';
- }
- return $url;
- }
- /**
- * Return true if the url is relative.
- *
- * @return bool
- */
- public function isRelativeUrl()
- {
- return !$this->hasScheme() && !$this->isProtocolRelative();
- }
- /**
- * Return true if the path is relative.
- *
- * @return bool
- */
- public function isRelativePath()
- {
- $path = $this->getPath();
- return empty($path) || $path[0]
- !== '/';
- }
- /**
- * Filters the path of a URI.
- *
- * Imported from Guzzle library: https://github.com/guzzle/psr7/blob/master/src/Uri.php#L568-L582
- *
- * @param $path
- * @param string $charUnreserved
- * @param string $charSubDelims
- * @return string
- */
- public function filterPath($path, $charUnreserved = 'a-zA-Z0-9_\-\.~', $charSubDelims = '!\$&\'\(\)\*\+,;=')
- {
- return preg_replace_callback(
- '/(?:[^'.$charUnreserved.$charSubDelims.':@\/%]+|%(?![A-Fa-f0-9]{2}))/',
- function (array $matches) { return rawurlencode($matches[0]); },
- $path
- );
- }
- /**
- * Get the path.
- *
- * @return string
- */
- public function getPath()
- {
- return $this->filterPath(empty($this->components['path']) ? '' : $this->components['path']);
- }
- /**
- * Get the base path.
- *
- * @return string
- */
- public function getBasePath()
- {
- $current_path = $this->getPath();
- $path = $this->isRelativePath() ? '/' : '';
- $path .= substr($current_path, -1) === '/' ? $current_path : dirname($current_path);
- return preg_replace('/\\\\\/|\/\//', '/', $path.'/');
- }
- /**
- * Get the full path (path + querystring + fragment).
- *
- * @return string
- */
- public function getFullPath()
- {
- $path = $this->isRelativePath() ? '/' : '';
- $path .= $this->getPath();
- $path .= empty($this->components['query']) ? '' : '?'.$this->components['query'];
- $path .= empty($this->components['fragment']) ? '' : '#'.$this->components['fragment'];
- return $path;
- }
- /**
- * Get the hostname.
- *
- * @return string
- */
- public function getHost()
- {
- return empty($this->components['host']) ? '' : $this->components['host'];
- }
- /**
- * Return true if the url has a hostname.
- *
- * @return bool
- */
- public function hasHost()
- {
- return !empty($this->components['host']);
- }
- /**
- * Get the scheme.
- *
- * @param string $suffix Suffix to add when there is a scheme
- * @return string
- */
- public function getScheme($suffix = '')
- {
- return ($this->hasScheme() ? $this->components['scheme'] : 'http').$suffix;
- }
- /**
- * Set the scheme.
- *
- * @param string $scheme Set a scheme
- * @return $this
- */
- public function setScheme($scheme)
- {
- $this->components['scheme'] = $scheme;
- return $this;
- }
- /**
- * Return true if the url has a scheme.
- *
- * @return bool
- */
- public function hasScheme()
- {
- return !empty($this->components['scheme']);
- }
- /**
- * Get the port.
- *
- * @param string $prefix Prefix to add when there is a port
- * @return string
- */
- public function getPort($prefix = '')
- {
- return $this->hasPort() ? $prefix.$this->components['port'] : '';
- }
- /**
- * Return true if the url has a port.
- *
- * @return bool
- */
- public function hasPort()
- {
- return !empty($this->components['port']);
- }
- /**
- * Return true if the url is protocol relative (start with //).
- *
- * @return bool
- */
- public function isProtocolRelative()
- {
- return strpos($this->url, '//') === 0;
- }
- }
|