/** * @param Request $request * @param Response $response * @param callable $next * @return Response */ public function __invoke(Request $request, Response $response, callable $next) { $dispatcher = new Dispatcher($this->collector->getData()); $result = $dispatcher->dispatch($request->getMethod(), $request->getUri()->getPath()); $code = $result[0]; if ($code != Dispatcher::FOUND) { return $next($request, $response); } /** @var Route $route */ $route = $result[1]; $params = $result[2]; $request = $request->withAttribute('params', $params); foreach ($params as $key => $value) { $request[$key] = $value; } // Custom middleware handler. // We have to iterate through middleware as it was added so that they retain the proper ordering. // We have to check if the middleware is a route and if it was the route matched during dispatching. // If so, we can call the route handler, otherwise, we need to skip over it. $middleware = $this->middleware; $callable = function ($request, $response) use(&$callable, &$middleware, $route, $next) { /** @var callable $layer */ $layer = array_shift($middleware); if ($layer instanceof Route) { if ($layer !== $route) { return $callable($request, $response, $next); } $layer = $this->resolver->resolve($route->getHandler()); return $layer($request, $response); } return $layer($request, $response, $callable); }; return $callable($request, $response); }
/** * @inheritDoc */ public function parse(array $routes) : array { /** @var \Venta\Contracts\Routing\Route $route */ foreach ($routes as $route) { $this->collector->addRoute($route->getMethods(), $route->getPath(), $route); } return $this->collector->getData(); }
/** * Returns a listing of routes available. * * @return callable */ public function getRoutes() { $routes = array_merge($this->routes, $this->collector->getData()); return function (RouteCollector $collector) use($routes) { foreach ($routes as $route) { if (!empty($route)) { $collector->addRoute($route[0], $route[1], $route[2]); } } }; }
/** * @internal * @param Request $request * @param Response $response * @param callable $next * @return Response */ public function dispatchHandler(Request $request, Response $response, callable $next) { $dispatcher = new Dispatcher($this->collector->getData()); $result = $dispatcher->dispatch($request->getMethod(), $request->getUri()->getPath()); $code = $result[0]; $handler = isset($result[1]) ? $result[1] : null; $params = isset($result[2]) ? $result[2] : []; if ($code != Dispatcher::FOUND) { return $next ? $next($request, $response) : $response; } foreach ($params as $key => $value) { $request[$key] = $value; } return $this->paramHandler($request, $response, $next, $handler, $params); }
function it_parses_routes(RouteCollector $collector, Route $route) { $route->getMethods()->willReturn(['GET']); $route->getPath()->willReturn('/url'); $collector->addRoute(['GET'], '/url', $route)->shouldBeCalled(); $collector->getData()->willReturn(['parse result']); $this->parse([$route])->shouldBe(['parse result']); }
protected function generateDispatchData() { $data = $this->routeCollector->getData(); if ($this->cachePath !== null) { $filesys = new LockingFilesystem(); $php = '<?php return ' . var_export($data, true) . ";\n"; $filesys->write($this->cachePath, $php); } return $data; }
public function init() { $collector = new RouteCollector(new StdRouteParser(), new GroupCountBasedDataGenerator()); foreach ($this->routes as $route) { foreach ($route->definition($this->container) as list($method, $route_name, $handler_name)) { $collector->addRoute($method, $route_name, $handler_name); } } $this->dispatcher = new GroupCountBasedDispatcher($collector->getData()); }
/** * @param Request $request * @return RouteResult */ public function match(Request $request) { $path = $request->getUri()->getPath(); $method = $request->getMethod(); $dispatcher = $this->getDispatcher($this->router->getData()); $result = $dispatcher->dispatch($method, $path); if ($result[0] != Dispatcher::FOUND) { return $this->marshalFailedRoute($result); } return $this->marshalMatchedRoute($result, $method); }
/** * Parses the user request against the provided HTTP method verb and URI. * * Returns array (from FastRoute\Dispatcher) with one of the following formats: * * [FastRoute\Dispatcher::NOT_FOUND] * [FastRoute\Dispatcher::METHOD_NOT_ALLOWED, ['GET', 'OTHER_ALLOWED_METHODS']] * [FastRoute\Dispatcher::FOUND, $handler, ['varName' => 'value', ...]] * * @param string $method * @param string $uri * @return array */ public function parseRequest($method, $uri) { $this->buildRules(); $data = $this->routeCollector->getData(); $dispatcher = new Dispatcher($data); $routeInfo = $dispatcher->dispatch($method, $uri); if ($routeInfo[0] == Dispatcher::FOUND) { $routeInfo[2] = array_merge($this->rules[$routeInfo[1]]->getDefault(), $routeInfo[2]); } return $routeInfo; }
/** {@inheritdoc} */ public function getHttpRequestParser() : HttpRequestParserInterface { return $this->router->setRouter(new GroupCountBasedDispatcher($this->routeCollector->getData())); }
<?php use FastRoute\RouteCollector; use FastRoute\RouteParser\Std as RouteParser; use FastRoute\DataGenerator\GroupCountBased as RouteGenerator; use FastRoute\Dispatcher\GroupCountBased as Dispatcher; $r = new RouteCollector(new RouteParser(), new RouteGenerator()); $r->addRoute('GET', '/', ['ACME\\Controller\\Index', 'index']); $r->addRoute('GET', '/about[/{name}]', ['ACME\\Controller\\Index', 'about']); return new Dispatcher($r->getData());