427 lines
11 KiB
PHP
427 lines
11 KiB
PHP
<?php
|
|
namespace DynCom\mysyde\common\classes;
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: Bauer
|
|
* Date: 6/22/2015
|
|
* Time: 12:09 PM
|
|
*/
|
|
final class URL
|
|
{
|
|
|
|
|
|
const PROTOCOL_HTTP = 'http';
|
|
const PROTOCOL_HTTPS = 'https';
|
|
const PROTOCOL_FTP = 'ftp';
|
|
|
|
private $protocol;
|
|
private $user;
|
|
private $password;
|
|
private $domain;
|
|
private $port;
|
|
private $path;
|
|
private $queryParams;
|
|
private $anchor;
|
|
|
|
/**
|
|
* URL constructor.
|
|
* @param $protocol
|
|
* @param null $user
|
|
* @param null $password
|
|
* @param $domain
|
|
* @param null $port
|
|
* @param null $path
|
|
* @param array|null $queryParams
|
|
* @param null $anchor
|
|
*/
|
|
public function __construct($protocol, $user = null, $password = null, $domain, $port = null, $path = null, array $queryParams = null, $anchor = null)
|
|
{
|
|
if (null === $protocol || !$this->isProtocolValid($protocol)) {
|
|
throw new \InvalidArgumentException(
|
|
'Protocol `' . $protocol . '`is not a valid protocol. Only http, https & ftp are allowed'
|
|
);
|
|
}
|
|
|
|
if (null === $domain || !$this->isDomainValid($domain)) {
|
|
throw new \InvalidArgumentException(
|
|
'Domain is not valid.'
|
|
);
|
|
}
|
|
|
|
if (null !== $port && !$this->isPortValid($port)) {
|
|
throw new \InvalidArgumentException(
|
|
'Port is not valid. Valid range is 0-65535'
|
|
);
|
|
}
|
|
|
|
if (null !== $path && !$this->isPathValid($path)) {
|
|
throw new \InvalidArgumentException(
|
|
'Path is not a valid URL-path'
|
|
);
|
|
}
|
|
|
|
if (null !== $queryParams) {
|
|
foreach ($queryParams as $paramKey => $paramValue) {
|
|
if (!$this->isQueryParamValid([$paramKey => $paramValue])) {
|
|
throw new \InvalidArgumentException(
|
|
'Query parameter name must not differ from its URL-encoding. Paramter `' . htmlentities($paramKey) . '` does not meet this criterion.'
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (null !== $anchor && !$this->isAnchorValid($anchor)) {
|
|
throw new \InvalidArgumentException(
|
|
'Ancher is not valid.'
|
|
);
|
|
}
|
|
|
|
$this->protocol = $protocol;
|
|
$this->user = $user;
|
|
$this->password = $password;
|
|
$this->domain = $domain;
|
|
$this->port = $port;
|
|
$this->path = $path;
|
|
$this->queryParams = $queryParams;
|
|
$this->anchor = $anchor;
|
|
}
|
|
|
|
/**
|
|
* @param $protocol
|
|
* @return URL
|
|
*/
|
|
public function withProtocol($protocol)
|
|
{
|
|
return new self($protocol, $this->user, $this->password, $this->domain, $this->port, $this->path, $this->queryParams, $this->anchor);
|
|
}
|
|
|
|
/**
|
|
* @param $user
|
|
* @return URL
|
|
*/
|
|
public function withUser($user)
|
|
{
|
|
return new self($this->protocol, $user, $this->password, $this->domain, $this->port, $this->path, $this->queryParams, $this->anchor);
|
|
}
|
|
|
|
/**
|
|
* @param $password
|
|
* @return URL
|
|
*/
|
|
public function withPassword($password)
|
|
{
|
|
return new self($this->protocol, $this->user, $password, $this->domain, $this->port, $this->path, $this->queryParams, $this->anchor);
|
|
}
|
|
|
|
/**
|
|
* @param $user
|
|
* @param $password
|
|
* @return URL
|
|
*/
|
|
public function withUserPassword($user, $password)
|
|
{
|
|
return new self($this->protocol, $user, $password, $this->domain, $this->port, $this->path, $this->queryParams, $this->anchor);
|
|
}
|
|
|
|
/**
|
|
* @param $domain
|
|
* @return URL
|
|
*/
|
|
public function withDomain($domain)
|
|
{
|
|
return new self($this->protocol, $this->user, $this->password, $domain, $this->port, $this->path, $this->queryParams, $this->anchor);
|
|
}
|
|
|
|
/**
|
|
* @param $port
|
|
* @return URL
|
|
*/
|
|
public function withPort($port)
|
|
{
|
|
return new self($this->protocol, $this->user, $this->password, $this->domain, $port, $this->path, $this->queryParams, $this->anchor);
|
|
}
|
|
|
|
/**
|
|
* @param $path
|
|
* @return URL
|
|
*/
|
|
public function withPath($path)
|
|
{
|
|
return new self($this->protocol, $this->user, $this->password, $this->domain, $this->port, $path, $this->queryParams, $this->anchor);
|
|
}
|
|
|
|
/**
|
|
* @param array $params
|
|
* @return static
|
|
*/
|
|
public function withAddedQueryParams(array $params)
|
|
{
|
|
$newParamArray = array_merge($this->queryParams, $params);
|
|
return new static($this->protocol, $this->user, $this->password, $this->domain, $this->port, $this->path, $newParamArray, $this->anchor);
|
|
}
|
|
|
|
/**
|
|
* @param array $params
|
|
* @return static
|
|
*/
|
|
public function withNewQueryParams(array $params)
|
|
{
|
|
return new static($this->protocol, $this->user, $this->password, $this->domain, $this->port, $this->path, $params, $this->anchor);
|
|
}
|
|
|
|
/**
|
|
* @param $anchor
|
|
* @return URL
|
|
*/
|
|
public function withAnchor($anchor)
|
|
{
|
|
return new self($this->protocol, $this->user, $this->password, $this->domain, $this->port, $this->path, $this->queryParams, $anchor);
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getQueryString()
|
|
{
|
|
$queryString = '';
|
|
if (is_array($this->queryParams) && count($this->queryParams) > 0) {
|
|
$queryString .= '?';
|
|
$i = 0;
|
|
foreach ($this->queryParams as $paramName => $paramVal) {
|
|
if ($i > 0) {
|
|
$queryString .= '&';
|
|
}
|
|
$queryString .= $paramName . '=' . $paramVal;
|
|
++$i;
|
|
}
|
|
}
|
|
return $queryString;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getFullURL()
|
|
{
|
|
if (null === $this->domain) {
|
|
throw new \RuntimeException('No domain-name set.');
|
|
}
|
|
if (null === $this->protocol) {
|
|
throw new \RuntimeException('No protocol set.');
|
|
}
|
|
|
|
//Protocol
|
|
$url = $this->protocol . '://';
|
|
//User/Pass
|
|
if (null !== $this->user) {
|
|
$url .= rawurlencode($this->user) . ':';
|
|
if (null !== $this->password) {
|
|
$url .= rawurlencode($this->password);
|
|
}
|
|
$url .= '@';
|
|
}
|
|
//Domain
|
|
$url .= $this->domain;
|
|
//Port
|
|
if (null !== $this->port) {
|
|
$url .= ':' . $this->port;
|
|
}
|
|
//Path
|
|
if (null !== $this->path) {
|
|
$url .= $this->path;
|
|
}
|
|
//QueryString
|
|
if (null !== $this->queryParams) {
|
|
$url .= $this->getQueryString();
|
|
}
|
|
//Anchor
|
|
if (null !== $this->anchor) {
|
|
$url .= '#' . $this->anchor;
|
|
}
|
|
return $url;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $protocol
|
|
* @return bool
|
|
*/
|
|
protected function isProtocolValid($protocol)
|
|
{
|
|
return in_array($protocol, [
|
|
self::PROTOCOL_HTTP,
|
|
self::PROTOCOL_HTTPS,
|
|
self::PROTOCOL_FTP
|
|
], true);
|
|
}
|
|
|
|
/**
|
|
* @param $domain
|
|
* @return bool
|
|
*/
|
|
private function isDomainValid($domain)
|
|
{
|
|
return (preg_match('/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i', $domain) //valid chars check
|
|
&& preg_match('/^.{1,253}$/', $domain) //overall length check
|
|
&& preg_match('/^[^\.]{1,63}(\.[^\.]{1,63})*$/', $domain)); //length of each label
|
|
}
|
|
|
|
/**
|
|
* @param $port
|
|
* @return bool
|
|
*/
|
|
private function isPortValid($port)
|
|
{
|
|
return ((is_int($port) || ctype_digit($port)) && $port >= 0 && $port <= 65535);
|
|
}
|
|
|
|
/**
|
|
* @param $path
|
|
* @return int
|
|
*/
|
|
private function isPathValid($path)
|
|
{
|
|
return preg_match('|^\/[a-zA-Z0-9\-\+\_%]+(?:[\/\a-zA-Z0-9\-\+\_%]+)*$|', $path);
|
|
}
|
|
|
|
/**
|
|
* @param array $queryParam
|
|
* @return bool
|
|
*/
|
|
private function isQueryParamValid(array $queryParam)
|
|
{
|
|
$firstKey = array_keys($queryParam)[0];
|
|
$firstVal = array_values($queryParam)[0];
|
|
return (count($queryParam) === 1 && $firstKey === urlencode($firstKey) && is_scalar($firstVal));
|
|
}
|
|
|
|
/**
|
|
* @param $anchor
|
|
* @return int
|
|
*/
|
|
private function isAnchorValid($anchor)
|
|
{
|
|
return preg_match('/^[a-zA-Z0-9_\-]+$/', $anchor);
|
|
}
|
|
|
|
|
|
public function getProtocol()
|
|
{
|
|
return $this->protocol;
|
|
}
|
|
|
|
/**
|
|
* @return null
|
|
*/
|
|
public function getUser()
|
|
{
|
|
return $this->user;
|
|
}
|
|
|
|
/**
|
|
* @return null
|
|
*/
|
|
public function getPassword()
|
|
{
|
|
return $this->password;
|
|
}
|
|
|
|
public function getDomain()
|
|
{
|
|
return $this->domain;
|
|
}
|
|
|
|
/**
|
|
* @return null
|
|
*/
|
|
public function getPort()
|
|
{
|
|
return $this->port;
|
|
}
|
|
|
|
/**
|
|
* @return null
|
|
*/
|
|
public function getPath()
|
|
{
|
|
return $this->path;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getQueryParams()
|
|
{
|
|
return $this->queryParams;
|
|
}
|
|
|
|
/**
|
|
* @return null
|
|
*/
|
|
public function getAnchor()
|
|
{
|
|
return $this->anchor;
|
|
}
|
|
|
|
/**
|
|
* @param $domain
|
|
* @return URL
|
|
*/
|
|
public static function createHTTPFromDomain($domain)
|
|
{
|
|
return new self(self::PROTOCOL_HTTP,null,null,$domain,null,null,null,null);
|
|
}
|
|
|
|
/**
|
|
* @param $domain
|
|
* @return URL
|
|
*/
|
|
public static function createHTTPSFromDomain($domain)
|
|
{
|
|
return new self(self::PROTOCOL_HTTPS,null,null,$domain,null,null,null,null);
|
|
}
|
|
|
|
/**
|
|
* @param $domain
|
|
* @param $path
|
|
* @return URL
|
|
*/
|
|
public static function createHTTPFromDomainAndPath($domain, $path)
|
|
{
|
|
return new self(self::PROTOCOL_HTTP,null,null,$domain,null,$path,null,null);
|
|
}
|
|
|
|
/**
|
|
* @param $domain
|
|
* @param $path
|
|
* @return URL
|
|
*/
|
|
public static function createHTTPSFromDomainAndPath($domain, $path)
|
|
{
|
|
return new self(self::PROTOCOL_HTTPS,null,null,$domain,null,$path,null,null);
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function __toString() {
|
|
return $this->getFullURL();
|
|
}
|
|
|
|
}
|
|
/*
|
|
$url1 = new URL(URL::PROTOCOL_HTTPS, 'bauer@dc-solution.de', '!mB11121983!', 'www.pearson-friends.de', 88, '/mysyde/de/software/dccms/', ['test1name' => 'test1value'], 'anchor1');
|
|
$url2 = $url1->withDomain('www.pearson-friends.de')
|
|
->withUserPassword(null,null)
|
|
->withPort(null)
|
|
->withNewQueryParams([])
|
|
->withAnchor(null);
|
|
$url3 = URL::createHTTPFromDomain('www.arstechnica.com');
|
|
$url4 = URL::createHTTPSFromDomainAndPath('www.arstechnica.com','/httpstest/is/here/in/this/file.php');
|
|
echo 'URL1: ' . $url1->getFullURL();
|
|
echo '
|
|
URL2: ' . $url2->getFullURL();
|
|
echo '
|
|
URL3: ' . $url3->getFullURL();
|
|
echo '
|
|
URL4: ' . $url4->getFullURL();*/ |