Skip to content

Commit

Permalink
Fix #163: Allow multiple separate hosts with new Route::hosts method
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerych1984 committed Jun 22, 2022
1 parent 62af22f commit 823bafa
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 19 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Expand Up @@ -2,8 +2,8 @@

## 1.0.1 under development

- no changes in this release.
- Enh #163: Allow multiple separate hosts with new `Route::hosts` method (Gerych1984)

## 1.0.0 December 30, 2021

- Initial release.
- Initial release.
62 changes: 47 additions & 15 deletions src/Route.php
Expand Up @@ -25,7 +25,11 @@ final class Route
private array $methods;

private string $pattern;
private ?string $host = null;

/**
* @var string[]
*/
private array $hosts = [];
private bool $override = false;
private ?MiddlewareDispatcher $dispatcher;
private bool $actionAdded = false;
Expand Down Expand Up @@ -187,9 +191,26 @@ public function pattern(string $pattern): self
* @return self
*/
public function host(string $host): self
{
return $this->hosts($host);
}

/**
* @return self
*/
public function hosts(string ...$hosts): self
{
$route = clone $this;
$route->host = rtrim($host, '/');
$route->hosts = [];

foreach ($hosts as $host) {
$host = rtrim($host, '/');

if ($host !== '' && !in_array($host, $route->hosts, true)) {
$route->hosts[] = $host;
}
}

return $route;
}

Expand Down Expand Up @@ -306,27 +327,32 @@ public function disableMiddleware(...$middlewareDefinition): self
* @psalm-param T $key
* @psalm-return (
* T is ('name'|'pattern') ? string :
* (T is 'host' ? string|null :
* (T is 'methods' ? array<array-key,string> :
* (T is 'defaults' ? array<string,string> :
* (T is ('override'|'hasMiddlewares'|'hasDispatcher') ? bool :
* (T is 'dispatcherWithMiddlewares' ? MiddlewareDispatcher : mixed)
* (T is 'host' ? string|null :
* (T is 'hosts' ? array<array-key, string> :
* (T is 'methods' ? array<array-key,string> :
* (T is 'defaults' ? array<string,string> :
* (T is ('override'|'hasMiddlewares'|'hasDispatcher') ? bool :
* (T is 'dispatcherWithMiddlewares' ? MiddlewareDispatcher : mixed)
* )
* )
* )
* )
* )
* )
* )
* )
* )
*/
public function getData(string $key)
{
switch ($key) {
case 'name':
return $this->name ??
(implode(', ', $this->methods) . ' ' . (string) $this->host . $this->pattern);
(implode(', ', $this->methods) . ' ' . implode('|', $this->hosts) . $this->pattern);
case 'pattern':
return $this->pattern;
case 'host':
return $this->host;
/** @var string $this->hosts[0] */
return $this->hosts[0] ?? null;
case 'hosts':
return $this->hosts;
case 'methods':
return $this->methods;
case 'defaults':
Expand Down Expand Up @@ -355,9 +381,15 @@ public function __toString(): string
if ($this->methods !== []) {
$result .= implode(',', $this->methods) . ' ';
}
if ($this->host !== null && strrpos($this->pattern, $this->host) === false) {
$result .= $this->host;

if ($this->hosts) {
$quoted = array_map(static fn ($host) => preg_quote($host), $this->hosts);

if (!preg_match('/' . implode('|', $quoted) . '/', $this->pattern)) {
$result .= implode('|', $this->hosts);
}
}

$result .= $this->pattern;

return $result;
Expand All @@ -369,7 +401,7 @@ public function __debugInfo()
'name' => $this->name,
'methods' => $this->methods,
'pattern' => $this->pattern,
'host' => $this->host,
'hosts' => $this->hosts,
'defaults' => $this->defaults,
'override' => $this->override,
'actionAdded' => $this->actionAdded,
Expand Down
43 changes: 41 additions & 2 deletions tests/RouteTest.php
Expand Up @@ -122,6 +122,41 @@ public function testHost(): void
$this->assertSame('https://yiiframework.com', $route->getData('host'));
}

public function testHosts(): void
{
$route = Route::get('/')
->hosts(
'https://yiiframework.com/',
'yf.com',
'yii.com',
'yf.ru'
);

$this->assertSame(
[
'https://yiiframework.com',
'yf.com',
'yii.com',
'yf.ru',
],
$route->getData('hosts')
);
}

public function testMultipleHosts(): void
{
$route = Route::get('/')
->host('https://yiiframework.com/');
$multipleRoute = Route::get('/')
->hosts(
'https://yiiframework.com/',
'https://yiiframework.ru/'
);

$this->assertCount(1, $route->getData('hosts'));
$this->assertCount(2, $multipleRoute->getData('hosts'));
}

public function testDefaults(): void
{
$route = Route::get('/{language}')->defaults([
Expand Down Expand Up @@ -302,7 +337,11 @@ public function testDebugInfo(): void
)
[pattern] => /
[host] => example.com
[hosts] => Array
(
[0] => example.com
)
[defaults] => Array
(
[age] => 42
Expand Down Expand Up @@ -330,7 +369,7 @@ public function testDebugInfo(): void

private function getRequestHandler(): RequestHandlerInterface
{
return new class () implements RequestHandlerInterface {
return new class() implements RequestHandlerInterface {
public function handle(ServerRequestInterface $request): ResponseInterface
{
return new Response(404);
Expand Down

0 comments on commit 823bafa

Please sign in to comment.