diff --git a/src/Http.php b/src/Http.php index c642702..e97b689 100755 --- a/src/Http.php +++ b/src/Http.php @@ -849,6 +849,17 @@ private function runInternal(Request $request, Response $response): static $this->matchedRoute = $route; $groups = ($route instanceof Route) ? $route->getGroups() : []; + if (null === $route && null !== self::$wildcardRoute) { + $route = self::$wildcardRoute; + $this->route = $route; + $path = \parse_url($request->getURI(), PHP_URL_PATH); + $route->path($path); + } + + self::setResource('route', function () use ($route, $request) { + return $route ?? new Route($request->getMethod(), $request->getURI()); + }); + if (self::REQUEST_METHOD_HEAD == $method) { $method = self::REQUEST_METHOD_GET; $response->disablePayload(); @@ -891,13 +902,6 @@ private function runInternal(Request $request, Response $response): static return $this; } - if (null === $route && null !== self::$wildcardRoute) { - $route = self::$wildcardRoute; - $this->route = $route; - $path = \parse_url($request->getURI(), PHP_URL_PATH); - $route->path($path); - } - if (null !== $route) { return $this->execute($route, $request, $response); } elseif (self::REQUEST_METHOD_OPTIONS == $method) { diff --git a/tests/HttpTest.php b/tests/HttpTest.php index c39cff1..2a61caf 100755 --- a/tests/HttpTest.php +++ b/tests/HttpTest.php @@ -447,6 +447,134 @@ public function testCanSetRoute() $this->assertEquals($this->app->getRoute(), $route); } + public function testRouteInjectionAvailableInInit(): void + { + $request = (new Request()) + ->setMethod('GET') + ->setURI('/route-inject-init'); + + Http::init() + ->inject('route') + ->inject('response') + ->action(function (Route $route, Response $response) { + $response + ->addHeader('X-Init-Route', $route->getPath()) + ->addHeader('X-Init-Method', $route->getMethod()); + }); + + Http::get('/route-inject-init') + ->action(function () { + }); + + $response = new Response(); + $this->app->run($request, $response); + $headers = $response->getHeaders(); + + $this->assertSame('/route-inject-init', $headers['X-Init-Route'] ?? null); + $this->assertSame('GET', $headers['X-Init-Method'] ?? null); + } + + public function testRouteInjectionAvailableInRouteAction(): void + { + $request = (new Request()) + ->setMethod('GET') + ->setURI('/route-inject-action'); + + Http::get('/route-inject-action') + ->inject('route') + ->inject('response') + ->action(function (Route $route, Response $response) { + $response + ->addHeader('X-Action-Route', $route->getPath()) + ->addHeader('X-Action-Method', $route->getMethod()); + }); + + $response = new Response(); + $this->app->run($request, $response); + $headers = $response->getHeaders(); + + $this->assertSame('/route-inject-action', $headers['X-Action-Route'] ?? null); + $this->assertSame('GET', $headers['X-Action-Method'] ?? null); + } + + public function testRouteInjectionAvailableForOptions(): void + { + $request = (new Request()) + ->setMethod('OPTIONS') + ->setURI('/options-route'); + + Http::options() + ->inject('route') + ->inject('response') + ->action(function (Route $route, Response $response) { + $response + ->addHeader('X-Options-Route', $route->getPath()) + ->addHeader('X-Options-Method', $route->getMethod()); + }); + + $response = new Response(); + $this->app->run($request, $response); + $headers = $response->getHeaders(); + + $this->assertSame('/options-route', $headers['X-Options-Route'] ?? null); + $this->assertSame('OPTIONS', $headers['X-Options-Method'] ?? null); + } + + public function testRouteInjectionAvailableInShutdown(): void + { + $request = (new Request()) + ->setMethod('GET') + ->setURI('/route-inject-shutdown'); + + Http::shutdown() + ->inject('route') + ->inject('response') + ->action(function (Route $route, Response $response) { + $response + ->addHeader('X-Shutdown-Route', $route->getPath()) + ->addHeader('X-Shutdown-Method', $route->getMethod()); + }); + + Http::get('/route-inject-shutdown') + ->action(function () { + }); + + $response = new Response(); + $this->app->run($request, $response); + $headers = $response->getHeaders(); + + $this->assertSame('/route-inject-shutdown', $headers['X-Shutdown-Route'] ?? null); + $this->assertSame('GET', $headers['X-Shutdown-Method'] ?? null); + } + + public function testRouteInjectionAvailableInError(): void + { + $request = (new Request()) + ->setMethod('GET') + ->setURI('/route-inject-error'); + + Http::error() + ->inject('route') + ->inject('response') + ->action(function (Route $route, Response $response) { + $response + ->addHeader('X-Error-Route', $route->getPath()) + ->addHeader('X-Error-Method', $route->getMethod()); + }); + + Http::get('/route-inject-error') + ->action(function () { + throw new Exception('Error'); + }); + + $response = new Response(); + $this->app->run($request, $response); + $headers = $response->getHeaders(); + + $this->assertSame('/route-inject-error', $headers['X-Error-Route'] ?? null); + $this->assertSame('GET', $headers['X-Error-Method'] ?? null); + } + public function providerRouteMatching(): array { return [