Files
2026-02-17 14:56:23 +01:00

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();*/