Skip to content

Commit 7467479

Browse files
committed
Validate route aliases before registration
1 parent fdf42af commit 7467479

3 files changed

Lines changed: 37 additions & 0 deletions

File tree

src/Http/Route.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ public function path(string $path): self
8787
*/
8888
public function alias(string $path): self
8989
{
90+
Router::validateRouteAlias($path, [$this->method, ...$this->additionalMethods]);
91+
9092
Router::addRouteAlias($path, $this);
9193

9294
foreach ($this->additionalMethods as $method) {

src/Http/Router.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,28 @@ public static function addRoute(Route $route): void
108108
}
109109
}
110110

111+
/**
112+
* Validate that a route alias can be registered for every supplied method.
113+
*
114+
* @param array<int, string> $methods
115+
*
116+
* @throws Exception
117+
*/
118+
public static function validateRouteAlias(string $path, array $methods): void
119+
{
120+
[$alias] = self::preparePath($path);
121+
122+
foreach ($methods as $method) {
123+
if (!\array_key_exists($method, self::$routes)) {
124+
throw new Exception("Method ({$method}) not supported.");
125+
}
126+
127+
if (\array_key_exists($alias, self::$routes[$method]) && !self::$allowOverride) {
128+
throw new Exception("Route for ({$method}:{$alias}) already registered.");
129+
}
130+
}
131+
}
132+
111133
/**
112134
* Add route to router.
113135
*

tests/RouterTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,19 @@ public function testRoutesCrossPathAliases(): void
180180
$this->assertEquals($route, Router::match(Http::REQUEST_METHOD_POST, '/a')?->route);
181181
$this->assertEquals($route, Router::match(Http::REQUEST_METHOD_GET, '/a-old')?->route);
182182
$this->assertEquals($route, Router::match(Http::REQUEST_METHOD_POST, '/a-old')?->route);
183+
184+
$routePOST = Http::routes(Http::REQUEST_METHOD_POST, '/b')->alias('/b-old');
185+
$routeGETPOST = Http::routes([Http::REQUEST_METHOD_GET, Http::REQUEST_METHOD_POST], '/c');
186+
187+
try {
188+
$routeGETPOST->alias('/b-old');
189+
$this->fail('Expected duplicate route alias exception.');
190+
} catch (\Exception $exception) {
191+
$this->assertSame('Route for (POST:b-old) already registered.', $exception->getMessage());
192+
}
193+
194+
$this->assertNull(Router::match(Http::REQUEST_METHOD_GET, '/b-old'));
195+
$this->assertEquals($routePOST, Router::match(Http::REQUEST_METHOD_POST, '/b-old')?->route);
183196
}
184197

185198
public function testCannotRegisterDuplicateRouteMethod(): void

0 commit comments

Comments
 (0)