Skip to content

Commit 823bafa

Browse files
authored
Fix #163: Allow multiple separate hosts with new Route::hosts method
1 parent 62af22f commit 823bafa

File tree

3 files changed

+90
-19
lines changed

3 files changed

+90
-19
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
## 1.0.1 under development
44

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

77
## 1.0.0 December 30, 2021
88

9-
- Initial release.
9+
- Initial release.

src/Route.php

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ final class Route
2525
private array $methods;
2626

2727
private string $pattern;
28-
private ?string $host = null;
28+
29+
/**
30+
* @var string[]
31+
*/
32+
private array $hosts = [];
2933
private bool $override = false;
3034
private ?MiddlewareDispatcher $dispatcher;
3135
private bool $actionAdded = false;
@@ -187,9 +191,26 @@ public function pattern(string $pattern): self
187191
* @return self
188192
*/
189193
public function host(string $host): self
194+
{
195+
return $this->hosts($host);
196+
}
197+
198+
/**
199+
* @return self
200+
*/
201+
public function hosts(string ...$hosts): self
190202
{
191203
$route = clone $this;
192-
$route->host = rtrim($host, '/');
204+
$route->hosts = [];
205+
206+
foreach ($hosts as $host) {
207+
$host = rtrim($host, '/');
208+
209+
if ($host !== '' && !in_array($host, $route->hosts, true)) {
210+
$route->hosts[] = $host;
211+
}
212+
}
213+
193214
return $route;
194215
}
195216

@@ -306,27 +327,32 @@ public function disableMiddleware(...$middlewareDefinition): self
306327
* @psalm-param T $key
307328
* @psalm-return (
308329
* T is ('name'|'pattern') ? string :
309-
* (T is 'host' ? string|null :
310-
* (T is 'methods' ? array<array-key,string> :
311-
* (T is 'defaults' ? array<string,string> :
312-
* (T is ('override'|'hasMiddlewares'|'hasDispatcher') ? bool :
313-
* (T is 'dispatcherWithMiddlewares' ? MiddlewareDispatcher : mixed)
330+
* (T is 'host' ? string|null :
331+
* (T is 'hosts' ? array<array-key, string> :
332+
* (T is 'methods' ? array<array-key,string> :
333+
* (T is 'defaults' ? array<string,string> :
334+
* (T is ('override'|'hasMiddlewares'|'hasDispatcher') ? bool :
335+
* (T is 'dispatcherWithMiddlewares' ? MiddlewareDispatcher : mixed)
336+
* )
337+
* )
338+
* )
314339
* )
315-
* )
316340
* )
317-
* )
318-
* )
341+
* )
319342
*/
320343
public function getData(string $key)
321344
{
322345
switch ($key) {
323346
case 'name':
324347
return $this->name ??
325-
(implode(', ', $this->methods) . ' ' . (string) $this->host . $this->pattern);
348+
(implode(', ', $this->methods) . ' ' . implode('|', $this->hosts) . $this->pattern);
326349
case 'pattern':
327350
return $this->pattern;
328351
case 'host':
329-
return $this->host;
352+
/** @var string $this->hosts[0] */
353+
return $this->hosts[0] ?? null;
354+
case 'hosts':
355+
return $this->hosts;
330356
case 'methods':
331357
return $this->methods;
332358
case 'defaults':
@@ -355,9 +381,15 @@ public function __toString(): string
355381
if ($this->methods !== []) {
356382
$result .= implode(',', $this->methods) . ' ';
357383
}
358-
if ($this->host !== null && strrpos($this->pattern, $this->host) === false) {
359-
$result .= $this->host;
384+
385+
if ($this->hosts) {
386+
$quoted = array_map(static fn ($host) => preg_quote($host), $this->hosts);
387+
388+
if (!preg_match('/' . implode('|', $quoted) . '/', $this->pattern)) {
389+
$result .= implode('|', $this->hosts);
390+
}
360391
}
392+
361393
$result .= $this->pattern;
362394

363395
return $result;
@@ -369,7 +401,7 @@ public function __debugInfo()
369401
'name' => $this->name,
370402
'methods' => $this->methods,
371403
'pattern' => $this->pattern,
372-
'host' => $this->host,
404+
'hosts' => $this->hosts,
373405
'defaults' => $this->defaults,
374406
'override' => $this->override,
375407
'actionAdded' => $this->actionAdded,

tests/RouteTest.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,41 @@ public function testHost(): void
122122
$this->assertSame('https://yiiframework.com', $route->getData('host'));
123123
}
124124

125+
public function testHosts(): void
126+
{
127+
$route = Route::get('/')
128+
->hosts(
129+
'https://yiiframework.com/',
130+
'yf.com',
131+
'yii.com',
132+
'yf.ru'
133+
);
134+
135+
$this->assertSame(
136+
[
137+
'https://yiiframework.com',
138+
'yf.com',
139+
'yii.com',
140+
'yf.ru',
141+
],
142+
$route->getData('hosts')
143+
);
144+
}
145+
146+
public function testMultipleHosts(): void
147+
{
148+
$route = Route::get('/')
149+
->host('https://yiiframework.com/');
150+
$multipleRoute = Route::get('/')
151+
->hosts(
152+
'https://yiiframework.com/',
153+
'https://yiiframework.ru/'
154+
);
155+
156+
$this->assertCount(1, $route->getData('hosts'));
157+
$this->assertCount(2, $multipleRoute->getData('hosts'));
158+
}
159+
125160
public function testDefaults(): void
126161
{
127162
$route = Route::get('/{language}')->defaults([
@@ -302,7 +337,11 @@ public function testDebugInfo(): void
302337
)
303338
304339
[pattern] => /
305-
[host] => example.com
340+
[hosts] => Array
341+
(
342+
[0] => example.com
343+
)
344+
306345
[defaults] => Array
307346
(
308347
[age] => 42
@@ -330,7 +369,7 @@ public function testDebugInfo(): void
330369

331370
private function getRequestHandler(): RequestHandlerInterface
332371
{
333-
return new class () implements RequestHandlerInterface {
372+
return new class() implements RequestHandlerInterface {
334373
public function handle(ServerRequestInterface $request): ResponseInterface
335374
{
336375
return new Response(404);

0 commit comments

Comments
 (0)