/** * {@inheritdoc} */ public function match(ServerRequestInterface $request) : RoutingResult { $requestPath = $request->getUri()->getPath(); $this->logger->debug(sprintf('Analysing request path "%s"', $requestPath)); $candidates = []; /** @var array $routeDefinition */ foreach ($this->routes as $routeDefinition) { $route = $routeDefinition['route']; $identifier = $this->getRouteIdentifier($route); $this->logger->debug(sprintf('Trying to match requested path to route "%s"', $identifier)); $urlVars = []; if (preg_match_all($routeDefinition['pathMatcher'], $requestPath, $urlVars)) { $method = strtoupper(trim($request->getMethod())); if (!in_array($method, $route->getMethods())) { $candidates[] = ['route' => $route, 'failure' => RoutingResult::FAILED_METHOD_NOT_ALLOWED]; continue; } // remove all elements which should not be set in the request, // e.g. the matching url string as well as all numeric items $params = $this->mapParams($urlVars); if (!$this->matchParams($route, $params)) { $candidates[] = ['route' => $route, 'failure' => RoutingResult::FAILED_BAD_REQUEST]; continue; } $this->logger->debug(sprintf('Route "%s" matches. Applying its target...', $identifier)); return RoutingResult::forSuccess($route, $params); } } $this->logger->debug('No matching route found.'); if (count($candidates)) { $candidate = $candidates[0]; return RoutingResult::forFailure($candidate['failure'], $candidate['route']); } return RoutingResult::forFailure(RoutingResult::FAILED_NOT_FOUND); }
/** * @test */ public function requestContainsRoutingResultInRoutingResultAttributeAfterRouting() { $self = $this; $route = RouteBuilder::route()->get('/test')->to('testAction')->build(); $routingResult = RoutingResult::forSuccess($route); $this->router->expects($this->any())->method('match')->will($this->returnValue($routingResult)); $next = function ($request, $response) use($routingResult, $self) { $self->assertSame($routingResult, $request->getAttribute(RoutingResult::class)); return $response; }; $this->middleware->__invoke($this->request, $this->response, $next); }
/** * Offers possibility to manipulate the request according to routing result. * Returns a new {@link \Psr\Http\Message\ServerRequestInterface}. * * @param ServerRequestInterface $request * @param RoutingResult $routingResult * @return ServerRequestInterface */ protected function applyRoutingResult(ServerRequestInterface $request, RoutingResult $routingResult) : ServerRequestInterface { $routingParams = $routingResult->getParams(); $params = array_merge($request->getQueryParams(), $routingParams); return $request->withQueryParams($params); }
/** * @test */ public function beforeEmitterMiddlewareWillBePipedBeforeEmitter() { $expectedOrder = [BasicRoutingMiddleware::class, ActionResolverMiddleware::class, ActionExecutorMiddleware::class, ResponderResolverMiddleware::class, ResponderExecutorMiddleware::class, TestMiddleware::class]; $order = []; $app = $this->getMockedAdrenaline(); $app->expects($this->any())->method('pipe')->will($this->returnCallback(function ($middleware) use(&$order) { $order[] = get_class($middleware); })); $route = RouteBuilder::route()->get('/')->to('home')->build(); $routingResult = RoutingResult::forSuccess($route); $app->beforeEmitter(new TestMiddleware()); $this->request = $this->request->withAttribute(RoutingResult::class, $routingResult); $app->__invoke($this->request, $this->response); $this->assertEquals($order, $expectedOrder); }