Skip to content

Commit

Permalink
Simplify codebase
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Dec 30, 2024
1 parent afe442f commit 564245f
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 203 deletions.
9 changes: 4 additions & 5 deletions components/Modifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
use JsonSerializable;
use League\Uri\Components\DataPath;
use League\Uri\Components\Domain;
use League\Uri\Components\Fragment;
use League\Uri\Components\HierarchicalPath;
use League\Uri\Components\Host;
use League\Uri\Components\Path;
Expand All @@ -28,7 +27,7 @@
use League\Uri\Contracts\UriAccess;
use League\Uri\Contracts\UriInterface;
use League\Uri\Exceptions\SyntaxError;
use League\Uri\Idna\Converter as IdnConverter;
use League\Uri\Idna\Converter as IdnaConverter;
use League\Uri\IPv4\Converter as IPv4Converter;
use League\Uri\IPv6\Converter as IPv6Converter;
use League\Uri\KeyValuePair\Converter as KeyValuePairConverter;
Expand Down Expand Up @@ -406,7 +405,7 @@ public function appendLabel(Stringable|string|null $label): static
public function hostToAscii(): static
{
$currentHost = $this->uri->getHost();
$host = IdnConverter::toAsciiOrFail((string) $currentHost);
$host = IdnaConverter::toAsciiOrFail((string) $currentHost);

return match (true) {
null === $currentHost,
Expand All @@ -422,7 +421,7 @@ public function hostToAscii(): static
public function hostToUnicode(): static
{
$currentHost = $this->uri->getHost();
$host = IdnConverter::toUnicode((string) $currentHost)->domain();
$host = IdnaConverter::toUnicode((string) $currentHost)->domain();

return match (true) {
null === $currentHost,
Expand Down Expand Up @@ -845,7 +844,7 @@ public function getIdnUriString(): string
return $this->getUriString();
}

$host = IdnConverter::toUnicode($currentHost)->domain();
$host = IdnaConverter::toUnicode($currentHost)->domain();
if ($host === $currentHost) {
return $this->getUriString();
}
Expand Down
276 changes: 115 additions & 161 deletions uri/BaseUri.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace League\Uri;

use Deprecated;
use JsonSerializable;
use League\Uri\Contracts\Conditionable;
use League\Uri\Contracts\UriAccess;
Expand Down Expand Up @@ -202,7 +203,7 @@ public function isLocalFile(): bool
* Tells whether the URI is opaque or not.
*
* A URI is opaque if and only if it is absolute
* and does not has an authority path.
* and does not have an authority path.
*/
public function isOpaque(): bool
{
Expand Down Expand Up @@ -271,7 +272,10 @@ public function isRelativePath(): bool
*/
public function isSameDocument(Stringable|string $uri): bool
{
return $this->normalize(static::filterUri($uri)) === $this->normalize($this->uri);
return (match (true) {
$this->uri instanceof Uri => $this->uri,
default => Uri::new($this->uri),
})->isSameDocument($uri);
}

/**
Expand Down Expand Up @@ -301,44 +305,12 @@ public function hasIPv4(): bool
*/
public function resolve(Stringable|string $uri): static
{
$uri = static::formatHost(static::filterUri($uri, $this->uriFactory));
$null = $uri instanceof Psr7UriInterface ? '' : null;

if ($null !== $uri->getScheme()) {
return new static(
$uri->withPath(static::removeDotSegments($uri->getPath())),
$this->uriFactory
);
}

if ($null !== $uri->getAuthority()) {
return new static(
$uri
->withScheme($this->uri->getScheme())
->withPath(static::removeDotSegments($uri->getPath())),
$this->uriFactory
);
}

$user = $null;
$pass = null;
$userInfo = $this->uri->getUserInfo();
if (null !== $userInfo) {
[$user, $pass] = explode(':', $userInfo, 2) + [1 => null];
}

[$path, $query] = $this->resolvePathAndQuery($uri);
$resolved = UriString::resolve($uri, $this->uri->__toString());

return new static(
$uri
->withPath($this->removeDotSegments($path))
->withQuery($query)
->withHost($this->uri->getHost())
->withPort($this->uri->getPort())
->withUserInfo($user, $pass)
->withScheme($this->uri->getScheme()),
$this->uriFactory
);
return new static(match ($this->uriFactory) {
null => Uri::new($resolved),
default => $this->uriFactory->createUri($resolved),
}, $this->uriFactory);
}

/**
Expand Down Expand Up @@ -419,42 +391,6 @@ final protected function computeOrigin(Psr7UriInterface|UriInterface $uri, ?stri
};
}

/**
* Normalizes a URI for comparison; this URI string representation is not suitable for usage as per RFC guidelines.
*/
final protected function normalize(Psr7UriInterface|UriInterface $uri): string
{
$null = $uri instanceof Psr7UriInterface ? '' : null;

$path = $uri->getPath();
if ('/' === ($path[0] ?? '') || '' !== $uri->getScheme().$uri->getAuthority()) {
$path = $this->removeDotSegments($path);
}

$query = $uri->getQuery();
$pairs = null === $query ? [] : explode('&', $query);
sort($pairs);

static $regexpEncodedChars = ',%(2[D|E]|3\d|4[1-9|A-F]|5[\d|AF]|6[1-9|A-F]|7[\d|E]),i';
$value = preg_replace_callback(
$regexpEncodedChars,
static fn (array $matches): string => rawurldecode($matches[0]),
[$path, implode('&', $pairs)]
) ?? ['', $null];

[$path, $query] = $value + ['', $null];
if ($null !== $uri->getAuthority() && '' === $path) {
$path = '/';
}

return $uri
->withHost(Uri::fromComponents(['host' => $uri->getHost()])->getHost())
->withPath($path)
->withQuery([] === $pairs ? $null : $query)
->withFragment($null)
->__toString();
}

/**
* Input URI normalization to allow Stringable and string URI.
*/
Expand All @@ -469,92 +405,6 @@ final protected static function filterUri(Stringable|string $uri, UriFactoryInte
};
}

/**
* Remove dot segments from the URI path as per RFC specification.
*/
final protected function removeDotSegments(string $path): string
{
if (!str_contains($path, '.')) {
return $path;
}

$reducer = function (array $carry, string $segment): array {
if ('..' === $segment) {
array_pop($carry);

return $carry;
}

if (!isset(static::DOT_SEGMENTS[$segment])) {
$carry[] = $segment;
}

return $carry;
};

$oldSegments = explode('/', $path);
$newPath = implode('/', array_reduce($oldSegments, $reducer(...), []));
if (isset(static::DOT_SEGMENTS[end($oldSegments)])) {
$newPath .= '/';
}

// @codeCoverageIgnoreStart
// added because some PSR-7 implementations do not respect RFC3986
if (str_starts_with($path, '/') && !str_starts_with($newPath, '/')) {
return '/'.$newPath;
}
// @codeCoverageIgnoreEnd

return $newPath;
}

/**
* Resolves an URI path and query component.
*
* @return array{0:string, 1:string|null}
*/
final protected function resolvePathAndQuery(Psr7UriInterface|UriInterface $uri): array
{
$targetPath = $uri->getPath();
$null = $uri instanceof Psr7UriInterface ? '' : null;

if (str_starts_with($targetPath, '/')) {
return [$targetPath, $uri->getQuery()];
}

if ('' === $targetPath) {
$targetQuery = $uri->getQuery();
if ($null === $targetQuery) {
$targetQuery = $this->uri->getQuery();
}

$targetPath = $this->uri->getPath();
//@codeCoverageIgnoreStart
//because some PSR-7 Uri implementations allow this RFC3986 forbidden construction
if (null !== $this->uri->getAuthority() && !str_starts_with($targetPath, '/')) {
$targetPath = '/'.$targetPath;
}
//@codeCoverageIgnoreEnd

return [$targetPath, $targetQuery];
}

$basePath = $this->uri->getPath();
if (null !== $this->uri->getAuthority() && '' === $basePath) {
$targetPath = '/'.$targetPath;
}

if ('' !== $basePath) {
$segments = explode('/', $basePath);
array_pop($segments);
if ([] !== $segments) {
$targetPath = implode('/', $segments).'/'.$targetPath;
}
}

return [$targetPath, $uri->getQuery()];
}

/**
* Tells whether the component value from both URI object equals.
*
Expand Down Expand Up @@ -681,4 +531,108 @@ final protected static function formatPathWithEmptyBaseQuery(string $path): stri

return '' === $basename ? './' : $basename;
}

/**
* Normalizes a URI for comparison; this URI string representation is not suitable for usage as per RFC guidelines.
*
* @deprecated since version 7.6.0
*/
#[Deprecated(message:'no longer used by the isSameDocument method', since:'league/uri-interfaces:7.6.0')]
final protected function normalize(Psr7UriInterface|UriInterface $uri): string
{
return UriString::normalize($uri->withScheme($uri instanceof Psr7UriInterface ? '' : null));
}


/**
* Remove dot segments from the URI path as per RFC specification.
*
* @deprecated since version 7.6.0
*/
#[Deprecated(message:'no longer used by the isSameDocument method', since:'league/uri-interfaces:7.6.0')]
final protected function removeDotSegments(string $path): string
{
if (!str_contains($path, '.')) {
return $path;
}

$reducer = function (array $carry, string $segment): array {
if ('..' === $segment) {
array_pop($carry);

return $carry;
}

if (!isset(static::DOT_SEGMENTS[$segment])) {
$carry[] = $segment;
}

return $carry;
};

$oldSegments = explode('/', $path);
$newPath = implode('/', array_reduce($oldSegments, $reducer(...), []));
if (isset(static::DOT_SEGMENTS[end($oldSegments)])) {
$newPath .= '/';
}

// @codeCoverageIgnoreStart
// added because some PSR-7 implementations do not respect RFC3986
if (str_starts_with($path, '/') && !str_starts_with($newPath, '/')) {
return '/'.$newPath;
}
// @codeCoverageIgnoreEnd

return $newPath;
}

/**
* Resolves an URI path and query component.
*
* @return array{0:string, 1:string|null}
*
* @deprecated since version 7.6.0
*/
#[Deprecated(message:'no longer used by the isSameDocument method', since:'league/uri-interfaces:7.6.0')]
final protected function resolvePathAndQuery(Psr7UriInterface|UriInterface $uri): array
{
$targetPath = $uri->getPath();
$null = $uri instanceof Psr7UriInterface ? '' : null;

if (str_starts_with($targetPath, '/')) {
return [$targetPath, $uri->getQuery()];
}

if ('' === $targetPath) {
$targetQuery = $uri->getQuery();
if ($null === $targetQuery) {
$targetQuery = $this->uri->getQuery();
}

$targetPath = $this->uri->getPath();
//@codeCoverageIgnoreStart
//because some PSR-7 Uri implementations allow this RFC3986 forbidden construction
if (null !== $this->uri->getAuthority() && !str_starts_with($targetPath, '/')) {
$targetPath = '/'.$targetPath;
}
//@codeCoverageIgnoreEnd

return [$targetPath, $targetQuery];
}

$basePath = $this->uri->getPath();
if (null !== $this->uri->getAuthority() && '' === $basePath) {
$targetPath = '/'.$targetPath;
}

if ('' !== $basePath) {
$segments = explode('/', $basePath);
array_pop($segments);
if ([] !== $segments) {
$targetPath = implode('/', $segments).'/'.$targetPath;
}
}

return [$targetPath, $uri->getQuery()];
}
}
Loading

0 comments on commit 564245f

Please sign in to comment.