Skip to content

Commit

Permalink
Improve documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Jun 25, 2024
1 parent 8a83c7d commit edac618
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 46 deletions.
27 changes: 2 additions & 25 deletions components/Components/Host.php
Original file line number Diff line number Diff line change
Expand Up @@ -336,35 +336,12 @@ public function toUnicode(): ?string

public function compress(): ?string
{
if ('6' !== $this->ipVersion) {
return $this->host;
}

/** @var string $ip */
$ip = $this->getIp();
if (! $this->hasZoneIdentifier) {
return '['. Converter::compress($ip) .']';
}

[$ipv6, $zoneId] = explode('%', $ip, 2);

return '['. Converter::compress($ipv6) . '%' . $zoneId . ']';
return Converter::compress($this->value());
}

public function expand(): ?string
{
if ('6' !== $this->ipVersion) {
return $this->host;
}

/** @var string $ip */
$ip = $this->getIp();
[$ipv6, $zoneId] = explode('%', $ip, 2);

return match ($this->hasZoneIdentifier) {
false => '['.Converter::expand($ipv6).']',
true => '['.Converter::expand($ipv6). '%' . $zoneId.']',
};
return Converter::expand($this->value());
}

public function getIpVersion(): ?string
Expand Down
1 change: 1 addition & 0 deletions docs/_data/menu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ packages:
URI Parser: '/interfaces/7.0/uri-parser-builder/'
Query Parser: '/interfaces/7.0/query-parser-builder/'
IPv4 Converter: '/interfaces/7.0/ipv4/'
IPv6 Converter: '/interfaces/7.0/ipv6/'
IDN Converter: '/interfaces/7.0/idn/'
'2.0':
Documentation:
Expand Down
6 changes: 6 additions & 0 deletions docs/components/7.0/host.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,14 @@ public Host::isIpv6(): bool
public Host::isIpFuture(): bool
public Host::hasZoneIdentifier(): bool
public Host::withoutZoneIdentifier(): self
public Host::compress(): string
public Host::expand(): string
~~~

<p class="message-info">The <code>Host::compress</code> and <code>Host::expand</code>,
are added in version <code>7.6.0</code> and normalized an IPv6 host, See the <a href="/components/7.0/ipv6/">IPv6 Converter documentation</a> page for more information.
</p>

### Host::fromIp

This method allows creating a Host object from an IP.
Expand Down
30 changes: 30 additions & 0 deletions docs/components/7.0/modifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,36 @@ echo Modifier::from($uri)->hostToOctal()->getUri();
//display 'http://0xc0a811/path/to/the/sky.php'
~~~

### Modifier::hostToIpv6Compressed

Normalizes the URI host content to a compressed IPv6 notation if possible.
See the [IPv6 Converter documentation](/components/7.0/ipv6/) page for more information.

~~~php
<?php

use League\Uri\Modifier;

$uri = 'http://[1050:0000:0000:0000:0005:0000:300c:326b]/path/to/the/sky.php';
echo Modifier::from($uri)->hostToIpv6Compressed()->getUriString();
//display 'http://[1050::5:0:300c:326b]/path/to/the/sky.php'
~~~

### Modifier::hostToIpv6Expanded

Normalizes the URI host content to a expanded IPv6 notation if possible.
See the [IPv6 Converter documentation](/components/7.0/ipv6/) page for more information.

~~~php
<?php

use League\Uri\Modifier;

$uri = 'http://[0000:0000:0000:0000:0000:0000:0000:0001]/path/to/the/sky.php';
echo Modifier::from($uri)->hostToIpv6Compressed()->getUriString();
//display 'http://[::1]/path/to/the/sky.php'
~~~

### Modifier::removeZoneIdentifier

Removes the host zone identifier if present
Expand Down
10 changes: 6 additions & 4 deletions docs/interfaces/7.0/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ The `UriInterface` interface defines the following methods to access the URI str

public UriInterface::getScheme(): ?string
public UriInterface::getUserInfo(): ?string
public UriInterface::getUsername(): ?string
public UriInterface::getPassword(): ?string
public UriInterface::getHost(): ?string
public UriInterface::getPort(): ?int
public UriInterface::getAuthority(): ?string
Expand All @@ -51,7 +53,7 @@ Delimiter characters are not part of the URI component and **must not** be added
<?php

public UriInterface::withScheme(Stringable|string|null $scheme): self
public UriInterface::withUserInfo(Stringable|string|null $user [, string $password = null]): self
public UriInterface::withUserInfo(Stringable|string|null $user [, Stringable|string|null $password = null]): self
public UriInterface::withHost(Stringable|string|null $host): self
public UriInterface::withPort(?int $port): self
public UriInterface::withPath(Stringable|string $path): self
Expand All @@ -64,8 +66,8 @@ public UriInterface::withFragment(Stringable|string|null $fragment): self
This interface exposes the same methods as `Psr\Http\Message\UriInterface`. But, differs on the following keys:

- This interface does not require the `http` and `https` schemes to be supported.
- Setter and Getter component methods, with the exception of the path component, accept and can return the `null` value.
- If no scheme is present, you are not required to fallback to `http` and `https` schemes specific validation rules.
- Setter and Getter component methods, except the path component, accept and can return the `null` value.
- If no scheme is present, the requirement to fall back to `http` and `https` schemes specific validation rules is not enforced.

### League\Uri\Contract\UriComponentInterface

Expand All @@ -78,7 +80,7 @@ The `UriComponentInterface` interface defines the following methods to access th
~~~php
<?php
public UriComponentInterface::value(): ?string
public UriComponentInterface::toString(): ?string
public UriComponentInterface::toString(): string
public UriComponentInterface::getUriComponent(): ?string
public UriComponentInterface::jsonSerialize(): ?string
public UriComponentInterface::__toString(): string
Expand Down
41 changes: 41 additions & 0 deletions docs/interfaces/7.0/ipv6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
layout: default
title: IPv6 Converter
---

IPv6 Converter
=======

The `League\Uri\IPv6\Converter` is a IPv6 Converter.

```php
<?php

use League\Uri\IPv6\Converter;

echo Converter::expand('[::1]');
// returns '[0000:0000:0000:0000:0000:0000:0000:0001]'
echo Converter::compress('[1050:0000:0000:0000:0005:0000:300c:326b]');
// returns [1050::5:0:300c:326b]
```

Usage
--------

The `Converter::compress` method convert an expanded IPv6 host into its compressed form.
The method only parameter should represent a host value. The `Converter::exoend` method
does the opposite.

If you submit a host which is not an IPv6 one then, the submitted host value will be returned
as is.Conversely, trying to expand an IPv6 host which is already expanded or trying to compress
an already compressed IPv6 host will return the same value so nothing will be gain performing
such obvious operation.

```php
<?php

echo Converter::compress('[::1]');
// returns '[::1]'
echo Converter::expand('[1050:0000:0000:0000:0005:0000:300c:326b]');
// returns [1050:0000:0000:0000:0005:0000:300c:326b]
```
68 changes: 51 additions & 17 deletions interfaces/IPv6/Converter.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,67 @@

final class Converter
{
public static function compress(Stringable|string|null $ipv6): ?string
public static function compress(Stringable|string|null $host): ?string
{
return match (true) {
null === $ipv6 => null,
self::isValidIpv6($ipv6) => (string) inet_ntop((string) inet_pton((string) $ipv6)),
default => (string) $ipv6,
if ($host === null) {
return $host;
}

$host = (string) $host;
if ($host === '') {
return $host;
}

if (!str_starts_with($host, '[')) {
return $host;
}

if (!str_ends_with($host, ']')) {
return $host;
}

[$ipv6, $zoneIdentifier] = explode('%', substr($host, 1, -1), 2) + [1 => null];
if (!filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {

Check failure on line 40 in interfaces/IPv6/Converter.php

View workflow job for this annotation

GitHub Actions / PHP on 8.3 - prefer-stable -

Only booleans are allowed in a negated boolean, string|false given.

Check failure on line 40 in interfaces/IPv6/Converter.php

View workflow job for this annotation

GitHub Actions / PHP on 8.3 - prefer-stable -

Only booleans are allowed in a negated boolean, string|false given.
return $host;
}
$ipv6Compressed = (string) inet_ntop((string) inet_pton((string) $ipv6));

return match ($zoneIdentifier) {
null => "[$ipv6Compressed]",
default => "[$ipv6Compressed%$zoneIdentifier]",
};
}

public static function expand(Stringable|string|null $ipv6): ?string
public static function expand(Stringable|string|null $host): ?string
{
if (null === $ipv6) {
return null;
if ($host === null) {
return $host;
}

$ipv6 = (string) $ipv6;
if (!self::isValidIpv6($ipv6)) {
return $ipv6;
$host = (string) $host;
if ($host === '') {
return $host;
}

$hex = (array) unpack("H*hex", (string) inet_pton($ipv6));
if (!str_starts_with($host, '[')) {
return $host;
}

return implode(':', str_split(strtolower($hex['hex'] ?? ''), 4));
}
if (!str_ends_with($host, ']')) {
return $host;
}

private static function isValidIpv6(Stringable|string|null $ipv6): bool
{
return (bool) filter_var((string) $ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
[$ipv6, $zoneIdentifier] = explode('%', substr($host, 1, -1), 2) + [1 => null];
if (!filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {

Check failure on line 71 in interfaces/IPv6/Converter.php

View workflow job for this annotation

GitHub Actions / PHP on 8.3 - prefer-stable -

Only booleans are allowed in a negated boolean, string|false given.

Check failure on line 71 in interfaces/IPv6/Converter.php

View workflow job for this annotation

GitHub Actions / PHP on 8.3 - prefer-stable -

Only booleans are allowed in a negated boolean, string|false given.
return $host;
}

$hex = (array) unpack("H*hex", (string) inet_pton($ipv6));

Check failure on line 75 in interfaces/IPv6/Converter.php

View workflow job for this annotation

GitHub Actions / PHP on 8.3 - prefer-stable -

Parameter #1 $ip of function inet_pton expects string, string|null given.

Check failure on line 75 in interfaces/IPv6/Converter.php

View workflow job for this annotation

GitHub Actions / PHP on 8.3 - prefer-stable -

Parameter #1 $ip of function inet_pton expects string, string|null given.
$ipv6Expanded = implode(':', str_split(strtolower($hex['hex'] ?? ''), 4));

return match ($zoneIdentifier) {
null => "[$ipv6Expanded]",
default => "[$ipv6Expanded%$zoneIdentifier]",
};
}
}

0 comments on commit edac618

Please sign in to comment.