<?php
namespace Simply_Static;
class PhpUri {
/**
* http(s)://
*
* @var string
*/
public $scheme;
/**
* www.example.com
*
* @var string
*/
public $authority;
/**
* /search
*
* @var string
*/
public $path;
/**
* ?q=foo
*
* @var string
*/
public $query;
/**
* #bar
*
* @var string
*/
public $fragment;
private function __construct( $string ) {
preg_match_all(
'/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/',
$string,
$m
);
$this->scheme = $m[2][0];
$this->authority = $m[4][0];
/**
* CHANGE:
*
* @author Dominik Habichtsberg <Dominik.Habichtsberg@Hbg-IT.de>
* @since 24 Mai 2015 10:02 Uhr
*
* Former code: $this->path = ( empty( $m[ 5 ][ 0 ] ) ) ? '/' : $m[ 5 ][ 0 ];
* No tests failed, when the path is empty.
* With the former code, the relative urls //g and #s failed
*/
$this->path = $m[5][0];
$this->query = $m[7][0];
$this->fragment = $m[9][0];
}
private function to_str() {
$ret = '';
if ( ! empty( $this->scheme ) ) {
$ret .= "{$this->scheme}:";
}
if ( ! empty( $this->authority ) ) {
$ret .= "//{$this->authority}";
}
$ret .= $this->normalize_path( $this->path );
if ( ! empty( $this->query ) ) {
$ret .= "?{$this->query}";
}
if ( ! empty( $this->fragment ) ) {
$ret .= "#{$this->fragment}";
}
return $ret;
}
private function normalize_path( $path ) {
if ( empty( $path ) ) {
return '';
}
$normalized_path = $path;
$normalized_path = preg_replace( '`//+`', '/', $normalized_path, -1, $c0 );
$normalized_path = preg_replace( '`^/\\.\\.?/`', '/', $normalized_path, -1, $c1 );
$normalized_path = preg_replace( '`/\\.(/|$)`', '/', $normalized_path, -1, $c2 );
/**
* CHANGE:
*
* @author Dominik Habichtsberg <Dominik.Habichtsberg@Hbg-IT.de>
* @since 24 Mai 2015 10:05 Uhr
* changed limit form -1 to 1, because climbing up the directory-tree failed
*/
$normalized_path = preg_replace( '`/[^/]*?/\\.\\.(/|$)`', '/', $normalized_path, 1, $c3 );
$num_matches = $c0 + $c1 + $c2 + $c3;
return ( $num_matches > 0 ) ? $this->normalize_path( $normalized_path ) : $normalized_path;
}
/**
* Parse an url string
*
* @param string $url the url to parse
*
* @return phpUri
*/
public static function parse( $url ) {
$uri = new PhpUri( $url );
/**
* CHANGE:
*
* @author Dominik Habichtsberg <Dominik.Habichtsberg@Hbg-IT.de>
* @since 24 Mai 2015 10:25 Uhr
* The base-url should always have a path
*/
if ( empty( $uri->path ) ) {
$uri->path = '/';
}
return $uri;
}
/**
* Join with a relative url
*
* @param string $relative the relative url to join
*
* @return string
*/
public function join( $relative ) {
$uri = new PhpUri( $relative );
switch ( true ) {
case ! empty( $uri->scheme ):
break;
case ! empty( $uri->authority ):
break;
case empty( $uri->path ):
$uri->path = $this->path;
if ( empty( $uri->query ) ) {
$uri->query = $this->query;
}
break;
case strpos( $uri->path, '/' ) === 0:
break;
default:
$base_path = $this->path;
if ( strpos( $base_path, '/' ) === false ) {
$base_path = '';
} else {
$base_path = preg_replace( '/\/[^\/]+$/', '/', $base_path );
}
if ( empty( $base_path ) && empty( $this->authority ) ) {
$base_path = '/';
}
$uri->path = $base_path . $uri->path;
}
if ( empty( $uri->scheme ) ) {
$uri->scheme = $this->scheme;
if ( empty( $uri->authority ) ) {
$uri->authority = $this->authority;
}
}
return $uri->to_str();
}
}
|