Skip to content

Commit

Permalink
implement absolute address converter
Browse files Browse the repository at this point in the history
  • Loading branch information
yggverse committed Apr 5, 2024
1 parent 3329a90 commit 92eb9b3
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 44 deletions.
85 changes: 75 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,31 +70,96 @@ var_dump(

### Address

Includes useful methods to work with network addresses
Includes methods to work with network addresses.

#### Base address methods

Different operations with address parts:

* `scheme`
* `user`
* `password`
* `host`
* `protocol`
* `path`
* `query`
* `fragment`

#### Address conversion from relative to absolute format

**Document root**

```
$base = new \Yggverse\Net\Address(
'http://yo.ygg/a1/b1/c1'
);
$address = new \Yggverse\Net\Address(
'/a2'
);
var_dump(
$address->getAbsolute(
$base
) // return http://yo.ygg/a2
);
```

**Current folder**

```
$base = new \Yggverse\Net\Address(
'http://yo.ygg/a1/b1/c1'
);
$address = new \Yggverse\Net\Address(
'c2'
);
var_dump(
$address->getAbsolute(
$base
) // return http://yo.ygg/a1/b1/c2
);
```

**Ending slash**

```
$base = new \Yggverse\Net\Address(
'http://yo.ygg/a1/b1/c1/'
);
$address = new \Yggverse\Net\Address(
'http://yo.ygg'
'../../b2/c2'
);
var_dump(
$address->getScheme() // Scheme substring
$address->getAbsolute(
$base
) // return http://yo.ygg/a1/b2/c2
);
```

...
**All options**

$subject = new \Yggverse\Net\Address(
'./some/uri'
```
$base = new \Yggverse\Net\Address(
'http://user:password@yo.ygg/a1/b1/c1?attribute=value#anchor'
);
$address = new \Yggverse\Net\Address(
'../../a2/b2?attribute2=value2#anchor2'
);
var_dump(
$address->absolute(
$subject
) // return http://yo.ygg/some/uri
$address->getAbsolute(
$base
) // return http://user:password@yo.ygg/a2/b2?attribute2=value2#anchor2
);
```

## Integrations

* [Network API with native Yggdrasil/IPv6 support](https://github.com/YGGverse/web-api)
* [Yo! Search Crawler for different networks](https://github.com/YGGverse/Yo)
* [Yo! Crawler for different networks](https://github.com/YGGverse/Yo)
137 changes: 103 additions & 34 deletions src/Address.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ class Address
private ?string $_query = null;
private ?string $_fragment = null;

private array $_dirs = [];

private string $_separator = '/';

private array $_segments = [];

public function __construct(?string $address = null)
{
if ($address)
Expand All @@ -39,7 +39,7 @@ public function __construct(?string $address = null)

if ($pass = parse_url($address, PHP_URL_PASS))
{
$this->setPath(
$this->setPass(
(string) $pass
);
}
Expand Down Expand Up @@ -150,20 +150,22 @@ public function setPath(?string $value): void
{
if (false !== strpos($value, '\\'))
{
$this->_separator = '\\';
$this->setSeparator(
'\\'
);
}

$this->_dirs = explode(
$this->_segments = explode(
$this->_separator,
$value
);

$this->_path = $value;
}

public function getDirs(): array
public function getSegments(): array
{
return $this->_dirs;
return $this->_segments;
}

public function getQuery(): ?string
Expand Down Expand Up @@ -191,15 +193,22 @@ public function getSeparator(): string
return $this->_separator;
}

public function setSeparator(?string $value): void
{
$this->_separator = $value;
}

public function get(): string
{
$address = '';

if ($scheme = $this->getScheme())
{
$address .= sprintf(
'%s://',
$scheme
'%s:%s%s',
$scheme,
$this->getSeparator(),
$this->getSeparator()
);
}

Expand All @@ -210,7 +219,7 @@ public function get(): string
$address .= sprintf(
'%s:%s@',
$user,
pass
$pass
);
}

Expand Down Expand Up @@ -238,14 +247,7 @@ public function get(): string

if ($path = $this->getPath())
{
$address .= sprintf(
'%s%s',
$this->getSeparator(),
trim(
$path,
$this->getSeparator()
)
);
$address .= $path;
}

if ($query = $this->getQuery())
Expand All @@ -267,35 +269,102 @@ public function get(): string
return $address;
}

public function absolute(
\Yggverse\Net\Address $address
): string
public function getAbsolute(
\Yggverse\Net\Address $base
): ?string
{
if ($address->isAbsolute())
if ($this->isAbsolute())
{
return $this->get();
}

if ($base->isRelative())
{
return $address->get();
return null;
}

$address->setScheme(
$this->getScheme()
$this->setScheme(
$base->getScheme()
);

$address->setUser(
$this->getUser()
$this->setUser(
$base->getUser()
);

$address->setPass(
$this->getPass()
$this->setPass(
$base->getPass()
);

$address->setHost(
$this->getHost()
$this->setHost(
$base->getHost()
);

$address->setPort(
$this->getPort()
$this->setPort(
$base->getPort()
);

return ''; // @TODO
$this->setSeparator(
$base->getSeparator()
);

if (str_starts_with((string) $this->getPath(), $this->getSeparator()))
{
return $this->get();
}

if ($path = $this->getPath())
{
$prefix = array_reverse(
$base->getSegments()
);

array_shift(
$prefix
);

$navigate = true;

$postfix = [];

foreach ($this->getSegments() as $index => $segment)
{
if ($segment == '.')
{
continue;
}

if ($navigate && $segment == '..')
{
if (empty($prefix[$index]))
{
return null;
}

unset(
$prefix[$index]
);

continue;
}

$navigate = false;

$postfix[] = $segment;
}

$this->setPath(
implode(
$this->getSeparator(),
array_merge(
array_reverse(
$prefix
),
$postfix
)
)
);
}

return $this->get();
}
}

0 comments on commit 92eb9b3

Please sign in to comment.