88use Psr \Http \Message \ServerRequestInterface as PsrRequest ;
99use Tempest \Container \Container ;
1010use Tempest \Core \AppConfig ;
11- use Tempest \Http \GenericRequest ;
1211use Tempest \Http \Mappers \PsrRequestToGenericRequestMapper ;
13- use Tempest \Http \Mappers \RequestToObjectMapper ;
14- use Tempest \Http \Mappers \RequestToPsrRequestMapper ;
1512use Tempest \Http \Request ;
1613use Tempest \Http \Response ;
17- use Tempest \Http \Responses \Invalid ;
18- use Tempest \Http \Responses \NotFound ;
1914use Tempest \Http \Responses \Ok ;
20- use Tempest \Mapper \ObjectFactory ;
2115use Tempest \Reflection \ClassReflector ;
2216use Tempest \Router \Exceptions \ControllerActionHasNoReturn ;
2317use Tempest \Router \Exceptions \InvalidRouteException ;
24- use Tempest \Router \Exceptions \NotFoundException ;
18+ use Tempest \Router \Exceptions \NoMatchedRoute ;
2519use Tempest \Router \Routing \Construction \DiscoveredRoute ;
2620use Tempest \Router \Routing \Matching \RouteMatcher ;
27- use Tempest \Validation \Exceptions \ValidationException ;
2821use Tempest \View \View ;
2922
3023use function Tempest \map ;
@@ -49,36 +42,28 @@ public function dispatch(Request|PsrRequest $request): Response
4942
5043 private function processRequest (Request |PsrRequest $ request ): Response
5144 {
52- if (! ($ request instanceof PsrRequest )) {
53- $ request = map ($ request )->with (RequestToPsrRequestMapper ::class)->do ();
45+ if (! ($ request instanceof Request )) {
46+ $ request = map ($ request )->with (PsrRequestToGenericRequestMapper ::class)->do ();
5447 }
5548
56- $ matchedRoute = $ this ->routeMatcher -> match ( $ request );
49+ $ callable = $ this ->getCallable ( );
5750
58- if ($ matchedRoute === null ) {
59- return new NotFound ();
60- }
61-
62- $ this ->container ->singleton (MatchedRoute::class, fn () => $ matchedRoute );
63-
64- try {
65- $ callable = $ this ->getCallable ($ matchedRoute );
66- $ request = $ this ->resolveRequest ($ request , $ matchedRoute );
67- $ response = $ callable ($ request );
68- } catch (NotFoundException ) {
69- return new NotFound ();
70- } catch (ValidationException $ validationException ) {
71- return new Invalid ($ validationException ->subject , $ validationException ->failingRules );
72- }
73-
74- return $ response ;
51+ return $ callable ($ request );
7552 }
7653
77- private function getCallable (MatchedRoute $ matchedRoute ): HttpMiddlewareCallable
54+ private function getCallable (): HttpMiddlewareCallable
7855 {
79- $ route = $ matchedRoute ->route ;
56+ $ callControllerAction = function (Request $ _ ) {
57+ $ matchedRoute = $ this ->container ->get (MatchedRoute::class);
58+
59+ if ($ matchedRoute === null ) {
60+ // At this point, the `MatchRouteMiddleware` should have run.
61+ // If that's not the case, then someone messed up by clearing all HTTP middleware
62+ throw new NoMatchedRoute ();
63+ }
64+
65+ $ route = $ matchedRoute ->route ;
8066
81- $ callControllerAction = function (Request $ _ ) use ($ route , $ matchedRoute ) {
8267 $ response = $ this ->container ->invoke (
8368 $ route ->handler ,
8469 ...$ matchedRoute ->params ,
@@ -93,10 +78,7 @@ private function getCallable(MatchedRoute $matchedRoute): HttpMiddlewareCallable
9378
9479 $ callable = new HttpMiddlewareCallable (fn (Request $ request ) => $ this ->createResponse ($ callControllerAction ($ request )));
9580
96- $ middlewareStack = $ this ->routeConfig
97- ->middleware
98- ->clone ()
99- ->add (...$ route ->middleware );
81+ $ middlewareStack = $ this ->routeConfig ->middleware ;
10082
10183 foreach ($ middlewareStack ->unwrap () as $ middlewareClass ) {
10284 $ callable = new HttpMiddlewareCallable (function (Request $ request ) use ($ middlewareClass , $ callable ) {
@@ -194,38 +176,4 @@ private function processResponse(Response $response): Response
194176
195177 return $ response ;
196178 }
197-
198- // TODO: could in theory be moved to a dynamic initializer
199- private function resolveRequest (PsrRequest |ObjectFactory $ psrRequest , MatchedRoute $ matchedRoute ): Request
200- {
201- // Let's find out if our input request data matches what the route's action needs
202- $ requestClass = GenericRequest::class;
203-
204- // We'll loop over all the handler's parameters
205- foreach ($ matchedRoute ->route ->handler ->getParameters () as $ parameter ) {
206- // If the parameter's type is an instance of Request…
207- if ($ parameter ->getType ()->matches (Request::class)) {
208- // We'll use that specific request class
209- $ requestClass = $ parameter ->getType ()->getName ();
210-
211- break ;
212- }
213- }
214-
215- // We map the original request we got into this method to the right request class
216- /** @var \Tempest\Http\GenericRequest $request */
217- $ request = map ($ psrRequest )->with (PsrRequestToGenericRequestMapper::class)->do ();
218-
219- if ($ requestClass !== Request::class && $ requestClass !== GenericRequest::class) {
220- $ request = map ($ request )->with (RequestToObjectMapper::class)->to ($ requestClass );
221- }
222-
223- // Next, we register this newly created request object in the container
224- // This makes it so that RequestInitializer is bypassed entirely when the controller action needs the request class
225- // Making it so that we don't need to set any $_SERVER variables and stuff like that
226- $ this ->container ->singleton (Request::class, fn () => $ request );
227- $ this ->container ->singleton ($ request ::class, fn () => $ request );
228-
229- return $ request ;
230- }
231179}
0 commit comments