218 lines
6 KiB
PHP
218 lines
6 KiB
PHP
<?php
|
|
namespace Uiharu;
|
|
|
|
use InvalidArgumentException;
|
|
|
|
final class Url {
|
|
private string $scheme = '';
|
|
private string $host = '';
|
|
private int $port = 0;
|
|
private string $user = '';
|
|
private string $pass = '';
|
|
private string $path = '';
|
|
private string $query = '';
|
|
private string $fragment = '';
|
|
|
|
private ?string $formatted = null;
|
|
|
|
public function __construct(array $parts) {
|
|
if(isset($parts['scheme']))
|
|
$this->scheme = strtolower($parts['scheme']);
|
|
if(isset($parts['host']))
|
|
$this->host = $parts['host'];
|
|
if(isset($parts['port']))
|
|
$this->port = $parts['port'];
|
|
if(isset($parts['user']))
|
|
$this->user = $parts['user'];
|
|
if(isset($parts['pass']))
|
|
$this->pass = $parts['pass'];
|
|
if(isset($parts['path']))
|
|
$this->path = $parts['path'];
|
|
if(isset($parts['query']))
|
|
$this->query = $parts['query'];
|
|
if(isset($parts['fragment']))
|
|
$this->fragment = $parts['fragment'];
|
|
}
|
|
|
|
public static function parse(string $urlString): Url {
|
|
$parts = parse_url($urlString);
|
|
if($parts === false)
|
|
throw new InvalidArgumentException('Invalid URL provided.');
|
|
return new Url($parts);
|
|
}
|
|
|
|
public function resetString(): void {
|
|
$this->formatted = null;
|
|
}
|
|
public function setScheme(string $scheme): void {
|
|
$this->scheme = $scheme;
|
|
$this->resetString();
|
|
}
|
|
public function discardFragment(): void {
|
|
$this->fragment = '';
|
|
$this->resetString();
|
|
}
|
|
|
|
public function hasScheme(): bool {
|
|
return $this->scheme !== '';
|
|
}
|
|
public function hasHost(): bool {
|
|
return $this->host !== '';
|
|
}
|
|
public function hasPort(): bool {
|
|
return $this->port !== 0;
|
|
}
|
|
public function hasUser(): bool {
|
|
return $this->user !== '';
|
|
}
|
|
public function hasPassword(): bool {
|
|
return $this->pass !== '';
|
|
}
|
|
public function hasPath(): bool {
|
|
return $this->path !== '';
|
|
}
|
|
public function hasQuery(): bool {
|
|
return $this->query !== '';
|
|
}
|
|
public function hasFragment(): bool {
|
|
return $this->fragment !== '';
|
|
}
|
|
|
|
public function getScheme(): string {
|
|
return $this->scheme;
|
|
}
|
|
public function getHost(): string {
|
|
return $this->host;
|
|
}
|
|
public function getPort(): int {
|
|
return $this->port;
|
|
}
|
|
public function getUser(): string {
|
|
return $this->user;
|
|
}
|
|
public function getPassword(): string {
|
|
return $this->pass;
|
|
}
|
|
public function getPath(): string {
|
|
return $this->path;
|
|
}
|
|
public function getQuery(): string {
|
|
return $this->query;
|
|
}
|
|
public function getFragment(): string {
|
|
return $this->fragment;
|
|
}
|
|
|
|
public function hasUserInfo(): bool {
|
|
return $this->hasUser()
|
|
|| $this->hasPassword();
|
|
}
|
|
public function hasAuthority(): bool {
|
|
return $this->hasUserInfo()
|
|
|| $this->hasHost();
|
|
}
|
|
|
|
public function getUserInfo(): string {
|
|
$userInfo = $this->user;
|
|
if($this->pass !== '')
|
|
$userInfo .= ':' . $this->pass;
|
|
return $userInfo;
|
|
}
|
|
public function getAuthority(): string {
|
|
$authority = '//';
|
|
|
|
if($this->hasUserInfo())
|
|
$authority .= $this->getUserInfo() . '@';
|
|
|
|
$authority .= $this->host;
|
|
|
|
if($this->port !== 0)
|
|
$authority .= ':' . $this->port;
|
|
|
|
return $authority;
|
|
}
|
|
|
|
public function calculateHash(bool $raw = true): string {
|
|
return hash('sha256', (string)$this, $raw);
|
|
}
|
|
|
|
public function isHTTP(): bool {
|
|
return $this->scheme === 'http';
|
|
}
|
|
public function isHTTPS(): bool {
|
|
return $this->scheme === 'https';
|
|
}
|
|
public function isWeb(): bool {
|
|
return $this->scheme === 'https'
|
|
|| $this->scheme === 'http';
|
|
}
|
|
|
|
public function __toString(): string {
|
|
if($this->formatted === null) {
|
|
$string = '';
|
|
|
|
if($this->hasScheme())
|
|
$string .= $this->getScheme() . ':';
|
|
|
|
$hasAuthority = $this->hasAuthority();
|
|
if($hasAuthority)
|
|
$string .= $this->getAuthority();
|
|
|
|
$hasPath = $this->hasPath();
|
|
$path = $this->getPath();
|
|
|
|
if($hasAuthority && (!$hasPath || $path[0] !== '/'))
|
|
$string .= '/';
|
|
elseif(!$hasAuthority && $path[1] === '/')
|
|
$path = '/' . trim($path, '/');
|
|
|
|
$string .= $path;
|
|
|
|
// is all this necessary...?
|
|
if($this->hasQuery()) {
|
|
$string .= '?';
|
|
$parts = explode('&', $this->getQuery());
|
|
|
|
foreach($parts as $part) {
|
|
$param = explode('=', $part, 2);
|
|
$string .= rawurlencode($param[0]);
|
|
if(isset($param[1]))
|
|
$string .= '=' . rawurlencode($param[1]);
|
|
$string .= '&';
|
|
}
|
|
|
|
$string = substr($string, 0, -1);
|
|
}
|
|
|
|
if($this->hasFragment())
|
|
$string .= '#' . rawurlencode($this->getFragment());
|
|
|
|
$this->formatted = $string;
|
|
}
|
|
|
|
return $this->formatted;
|
|
}
|
|
|
|
public function toV1(): array {
|
|
$parts = ['uri' => (string)$this];
|
|
|
|
if($this->hasScheme())
|
|
$parts['scheme'] = $this->getScheme();
|
|
if($this->hasHost())
|
|
$parts['host'] = $this->getHost();
|
|
if($this->hasPort())
|
|
$parts['port'] = $this->getPort();
|
|
if($this->hasUser())
|
|
$parts['user'] = $this->getUser();
|
|
if($this->hasPassword())
|
|
$parts['pass'] = $parts['password'] = $this->getPassword();
|
|
if($this->hasPath())
|
|
$parts['path'] = $this->getPath();
|
|
if($this->hasQuery())
|
|
$parts['query'] = $this->getQuery();
|
|
if($this->hasFragment())
|
|
$parts['fragment'] = $this->getFragment();
|
|
|
|
return $parts;
|
|
}
|
|
}
|