* @link http://getkirby.com * @copyright Bastian Allgeier * @license http://www.opensource.org/licenses/mit-license.php MIT License */ class Url { public static $home = '/'; public static $to = null; public static $current = null; public static function scheme($url = null) { if(is_null($url)) { if( (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') || server::get('SERVER_PORT') == '443' || server::get('HTTP_X_FORWARDED_PORT') == '443' || server::get('HTTP_X_FORWARDED_PROTO') == 'https' || server::get('HTTP_X_FORWARDED_PROTO') == 'https, http' ) { return 'https'; } else { return 'http'; } } return parse_url($url, PHP_URL_SCHEME); } /** * Returns the current url with all bells and whistles * * @return string */ public static function current() { if(!is_null(static::$current)) return static::$current; return static::$current = static::base() . server::get('REQUEST_URI'); } /** * Returns the url for the current directory * * @return string */ public static function currentDir() { return dirname(static::current()); } /** */ public static function host($url = null) { if(is_null($url)) $url = static::current(); return parse_url($url, PHP_URL_HOST); } /** * Returns the port for the given url * * @return mixed */ public static function port($url = null) { if(is_null($url)) $url = static::current(); $port = intval(parse_url($url, PHP_URL_PORT)); return v::between($port, 1, 65535) ? $port : false; } /** * Returns only the cleaned path of the url */ public static function path($url = null) { if(is_null($url)) $url = static::current(); // if a path is passed, let's pretend this is an absolute url // to trick the url parser. It's a bit hacky but it works if(!static::isAbsolute($url)) $url = 'http://0.0.0.0/' . $url; return trim(parse_url($url, PHP_URL_PATH), '/'); } /** * Returns the correct separator for parameters * depending on the operating system * * @return string */ public static function paramSeparator() { return detect::windows() ? ';' : ':'; } /** * Returns the params in the url */ public static function params($url = null) { if(is_null($url)) $url = static::current(); $path = static::path($url); if(empty($path)) return array(); $params = array(); foreach(explode('/', $path) as $part) { $pos = strpos($part, static::paramSeparator()); if($pos === false) continue; $params[substr($part, 0, $pos)] = urldecode(substr($part, $pos+1)); } return $params; } /** * Returns the path without params */ public static function fragments($url = null) { if(is_null($url)) $url = static::current(); $path = static::path($url); if(empty($path)) return null; $frag = array(); foreach(explode('/', $path) as $part) { if(strpos($part, static::paramSeparator()) === false) $frag[] = $part; } return $frag; } /** * Returns the query as array */ public static function query($url = null) { if(is_null($url)) $url = static::current(); parse_str(parse_url($url, PHP_URL_QUERY), $array); return $array; } /** * Checks if the url contains a query string */ public static function hasQuery($url = null) { if(is_null($url)) $url = static::current(); return str::contains($url, '?'); } /** */ public static function hash($url = null) { if(is_null($url)) $url = static::current(); return parse_url($url, PHP_URL_FRAGMENT); } public static function build($parts = array(), $url = null) { if(is_null($url)) $url = static::current(); $defaults = array( 'scheme' => static::scheme($url), 'host' => static::host($url), 'port' => static::port($url), 'fragments' => static::fragments($url), 'params' => static::params($url), 'query' => static::query($url), 'hash' => static::hash($url), ); $parts = array_merge($defaults, $parts); $result = array(r(!empty($parts['scheme']), $parts['scheme'] . '://') . $parts['host'] . r(!empty($parts['port']), ':' . $parts['port'])); if(!empty($parts['fragments'])) $result[] = implode('/', $parts['fragments']); if(!empty($parts['params'])) $result[] = static::paramsToString($parts['params']); if(!empty($parts['query'])) $result[] = '?' . static::queryToString($parts['query']); return implode('/', $result) . (!empty($parts['hash']) ? '#' . $parts['hash'] : ''); } public static function queryToString($query = null) { if(is_null($query)) $query = url::query(); return http_build_query($query); } public static function paramsToString($params = null) { if(is_null($params)) $params = url::params(); $result = array(); foreach($params as $key => $val) $result[] = $key . static::paramSeparator() . $val; return implode('/', $result); } public static function stripPath($url = null) { if(is_null($url)) $url = static::current(); return static::build(array('fragments' => array(), 'params' => array()), $url); } public static function stripFragments($url = null) { if(is_null($url)) $url = static::current(); return static::build(array('fragments' => array()), $url); } public static function stripParams($url = null) { if(is_null($url)) $url = static::current(); return static::build(array('params' => array()), $url); } /** * Strips the query from the URL * * * * echo url::stripQuery('http://www.youtube.com/watch?v=9q_aXttJduk'); * // output: http://www.youtube.com/watch * * * * @param string $url * @return string */ public static function stripQuery($url = null) { if(is_null($url)) $url = static::current(); return static::build(array('query' => array()), $url); } /** * Strips a hash value from the URL * * * * echo url::stripHash('http://testurl.com/#somehash'); * // output: http://testurl.com/ * * * * @param string $url * @return string */ public static function stripHash($url) { if(is_null($url)) $url = static::current(); return static::build(array('hash' => ''), $url); } /** * Checks if an URL is absolute * * @return boolean */ public static function isAbsolute($url) { // don't convert absolute urls return (str::startsWith($url, 'http://') || str::startsWith($url, 'https://') || str::startsWith($url, '//')); } /** * Convert a relative path into an absolute URL * * @param string $path * @param string $home * @return string */ public static function makeAbsolute($path, $home = null) { if(static::isAbsolute($path)) return $path; // build the full url $path = ltrim($path, '/'); $home = is_null($home) ? static::$home : $home; if(empty($path)) return $home; return $home == '/' ? '/' . $path : $home . '/' . $path; } /** * Tries to fix a broken url without protocol * * @param string $url * @return string */ public static function fix($url) { // make sure to not touch absolute urls return (!preg_match('!^(https|http|ftp)\:\/\/!i', $url)) ? 'http://' . $url : $url; } /** * Returns the home url if defined * * @return string */ public static function home() { return static::$home; } /** * The url smart handler. Must be defined before * * @return string */ public static function to() { return call_user_func_array(static::$to, func_get_args()); } /** * Return the last url the user has been on if detectable * * @return string */ public static function last() { return r::referer(); } /** * Returns the base url * * @param string $url * @return string */ public static function base($url = null) { if(is_null($url)) { $port = server::get('SERVER_PORT'); $port = in_array($port, array(80, 443)) ? null : $port; return static::scheme() . '://' . server::get('SERVER_NAME', server::get('SERVER_ADDR')) . r($port, ':' . $port); } else { $port = static::port($url); $scheme = static::scheme($url); $host = static::host($url) . r(is_int($port), ':' . $port); return r($scheme, $scheme . '://') . $host; } } /** * Shortens a URL * It removes http:// or https:// and uses str::short afterwards * * * * echo url::short('http://veryveryverylongurl.com', 30); * // output: veryveryverylongurl.com * * * * @param string $url The URL to be shortened * @param int $length The final number of characters the URL should have * @param boolean $base True: only take the base of the URL. * @param string $rep The element, which should be added if the string is too long. Ellipsis is the default. * @return string The shortened URL */ public static function short($url, $length = false, $base = false, $rep = '…') { if($base) $url = static::base($url); // replace all the nasty stuff from the url $url = str_replace(array('http://', 'https://', 'ftp://', 'www.'), '', $url); // try to remove the last / after the url $url = rtrim($url, '/'); return ($length) ? str::short($url, $length, $rep) : $url; } /** * Returns the URL for document root no * matter what the path is. * * @return string */ public static function index() { if(r::cli()) { return '/'; } else { return static::base() . preg_replace('!\/index\.php$!i', '', server::get('SCRIPT_NAME')); } } } // basic home url setup url::$home = url::base(); // basic url generator setup url::$to = function($path = '/') { if(url::isAbsolute($path)) return $path; $path = ltrim($path, '/'); if(empty($path)) return url::home(); return url::home() . '/' . $path; };