map = []; $this->dispatcher = $dispatcher; } // ------------------------------------------------------------------------ // MethodMapInterface /** * Register a dispatchable (handler or middleware) with a method. * * $method may be: * - A single verb ("GET"), * - A comma-separated list of verbs ("GET,PUT,DELETE") * - "*" to indicate any method. * * $dispatchable may be anything a Dispatcher can dispatch. * @see DispatcherInterface::dispatch * * $dispatchable may also be null, in which case any previously set * handlers and middle for that method or methods will be unset. * * @param string $method * @param mixed $dispatchable */ public function register($method, $dispatchable) { $methods = explode(",", $method); $methods = array_map("trim", $methods); foreach ($methods as $method) { $this->map[$method] = $dispatchable; } } // ------------------------------------------------------------------------ // MiddlewareInterface /** * @param ServerRequestInterface $request * @param ResponseInterface $response * @param callable $next * @return ResponseInterface */ public function __invoke( ServerRequestInterface $request, ResponseInterface $response, $next ) { $method = $request->getMethod(); // Dispatch middleware registered with the explicitly matching method. if (isset($this->map[$method])) { $middleware = $this->map[$method]; return $this->dispatchMiddleware($middleware, $request, $response, $next); } // For HEAD, dispatch GET by default. if ($method === "HEAD" && isset($this->map["GET"])) { $middleware = $this->map["GET"]; return $this->dispatchMiddleware($middleware, $request, $response, $next); } // Dispatch * middleware, if registered. if (isset($this->map["*"])) { $middleware = $this->map["*"]; return $this->dispatchMiddleware($middleware, $request, $response, $next); } // Respond describing the allowed methods, either as a 405 response or // in response to an OPTIONS request. if ($method === "OPTIONS") { $response = $response->withStatus(200); } else { $response = $response->withStatus(405); } return $this->addAllowHeader($response); } // ------------------------------------------------------------------------ private function addAllowHeader(ResponseInterface $response) { $methods = join(",", $this->getAllowedMethods()); return $response->withHeader("Allow", $methods); } private function getAllowedMethods() { $methods = array_keys($this->map); // Add HEAD if GET is allowed and HEAD is not present. if (in_array("GET", $methods) && !in_array("HEAD", $methods)) { $methods[] = "HEAD"; } // Add OPTIONS if not already present. if (!in_array("OPTIONS", $methods)) { $methods[] = "OPTIONS"; } return $methods; } /** * @param $middleware * @param ServerRequestInterface $request * @param ResponseInterface $response * @param $next * @return ResponseInterface */ private function dispatchMiddleware( $middleware, ServerRequestInterface $request, ResponseInterface &$response, $next ) { return $this->dispatcher->dispatch($middleware, $request, $response, $next); } }