diff --git a/flight/Engine.php b/flight/Engine.php index fb4d9e8..aaaf778 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -401,8 +401,8 @@ class Engine continue; } - $use_v3_output_buffering = - $this->response()->v2_output_buffering === false && + $use_v3_output_buffering = + $this->response()->v2_output_buffering === false && $route->is_streamed === false; if ($use_v3_output_buffering === true) { @@ -493,8 +493,8 @@ class Engine } } - $use_v3_output_buffering = - $this->response()->v2_output_buffering === false && + $use_v3_output_buffering = + $this->response()->v2_output_buffering === false && $route->is_streamed === false; if ($use_v3_output_buffering === true) { diff --git a/flight/net/Route.php b/flight/net/Route.php index baf5ea1..22c3cf0 100644 --- a/flight/net/Route.php +++ b/flight/net/Route.php @@ -193,7 +193,7 @@ class Route */ public function hydrateUrl(array $params = []): string { - $url = preg_replace_callback("/(?:@([a-zA-Z0-9]+)(?:\:([^\/]+))?\)*)/i", function ($match) use ($params) { + $url = preg_replace_callback("/(?:@([\w]+)(?:\:([^\/]+))?\)*)/i", function ($match) use ($params) { if (isset($match[1]) && isset($params[$match[1]])) { return $params[$match[1]]; } diff --git a/flight/net/Router.php b/flight/net/Router.php index 895b337..346a791 100644 --- a/flight/net/Router.php +++ b/flight/net/Router.php @@ -29,6 +29,11 @@ class Router */ protected array $routes = []; + /** + * The current route that is has been found and executed. + */ + protected ?Route $executedRoute = null; + /** * Pointer to current route. */ @@ -213,6 +218,7 @@ class Router $url_decoded = urldecode($request->url); while ($route = $this->current()) { if ($route->matchMethod($request->method) && $route->matchUrl($url_decoded, $this->case_sensitive)) { + $this->executedRoute = $route; return $route; } $this->next(); @@ -233,6 +239,11 @@ class Router foreach ($this->routes as $route) { $potential_aliases[] = $route->alias; if ($route->matchAlias($alias)) { + // This will make it so the params that already + // exist in the url will be passed in. + if (!empty($this->executedRoute->params)) { + $params = $params + $this->executedRoute->params; + } return $route->hydrateUrl($params); } } diff --git a/tests/EngineTest.php b/tests/EngineTest.php index c7e21d2..400e193 100644 --- a/tests/EngineTest.php +++ b/tests/EngineTest.php @@ -405,6 +405,34 @@ class EngineTest extends TestCase $this->assertEquals('/path1/123', $url); } + public function testGetUrlComplex() + { + $engine = new Engine(); + $engine->route('/item/@item_param:[a-z0-9]{16}/by-status/@token:[a-z0-9]{16}', function () { + echo 'I win'; + }, false, 'path_item_1'); + $url = $engine->getUrl('path_item_1', [ 'item_param' => 1234567890123456, 'token' => 6543210987654321 ]); + $this->assertEquals('/item/1234567890123456/by-status/6543210987654321', $url); + } + + public function testGetUrlInsideRoute() + { + $engine = new Engine(); + $engine->route('/path1/@param:[0-9]{3}', function () { + echo 'I win'; + }, false, 'path1'); + $found_url = ''; + $engine->route('/path1/@param:[0-9]{3}/path2', function () use ($engine, &$found_url) { + + // this should pull the param from the first route + // since the param names are the same. + $found_url = $engine->getUrl('path1'); + }); + $engine->request()->url = '/path1/123/path2'; + $engine->start(); + $this->assertEquals('/path1/123', $found_url); + } + public function testMiddlewareCallableFunction() { $engine = new Engine(); diff --git a/tests/server-v2/index.php b/tests/server-v2/index.php index d4cc385..3c1951c 100644 --- a/tests/server-v2/index.php +++ b/tests/server-v2/index.php @@ -199,7 +199,7 @@ echo '