diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Router/Middleware/NotFound.php | 105 | ||||
-rw-r--r-- | src/Router/Routes/Glob.php | 6 |
2 files changed, 108 insertions, 3 deletions
diff --git a/src/Router/Middleware/NotFound.php b/src/Router/Middleware/NotFound.php new file mode 100644 index 0000000..97b4a51 --- /dev/null +++ b/src/Router/Middleware/NotFound.php @@ -0,0 +1,105 @@ +<?php + +namespace Jasny\Router\Middleware; + +use Jasny\Router\Routes; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * Set response to 'not found' or 'method not allowed' if route is non exist + */ +class NotFound +{ + /** + * Routes + * @var Routes + */ + protected $routes = null; + + /** + * Action for 'not found' case + * @var callback|int + **/ + protected $notFound = null; + + /** + * Action for 'method not allowed' case + * @var callback|int + **/ + protected $methodNotAllowed = null; + + /** + * Class constructor + * + * @param Routes $routes + * @param callback|int $notFound + * @param callback|int $methodNotAllowed + */ + public function __construct(Routes $routes, $notFound = 404, $methodNotAllowed = null) + { + if (!(is_numeric($notFound) && $notFound >= 100 && $notFound <= 599) && !is_callable($notFound)) { + throw new \InvalidArgumentException("'Not found' parameter should be a code in range 100-599 or a callback"); + } + + if ($methodNotAllowed && !(is_numeric($methodNotAllowed) && $methodNotAllowed >= 100 && $methodNotAllowed <= 599) && !is_callable($methodNotAllowed)) { + throw new \InvalidArgumentException("'Method not allowed' parameter should be a code in range 100-599 or a callback"); + } + + $this->routes = $routes; + $this->notFound = $notFound; + $this->methodNotAllowed = $methodNotAllowed; + } + + /** + * Get routes + * + * @return Routes + */ + public function getRoutes() + { + return $this->routes; + } + + /** + * Run middleware action + * + * @param ServerRequestInterface $request + * @param ResponseInterface $response + * @param callback $next + * @return ResponseInterface + */ + public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next = null) + { + if ($next && !is_callable($next)) { + throw new \InvalidArgumentException("'next' should be a callback"); + } + + if ($this->getRoutes()->hasRoute($request)) { + return $next ? $next($request, $response) : $response; + } + + $status = $this->methodNotAllowed && $this->getRoutes()->hasRoute($request, false) ? + $this->methodNotAllowed : $this->notFound; + + return is_numeric($status) ? $this->simpleResponse($response, $status) : call_user_func($status, $request, $response); + } + + /** + * Simple response + * + * @param ResponseInterface $response + * @param int $code + * @return ResponseInterface + */ + protected function simpleResponse(ResponseInterface $response, $code) + { + $message = 'Not Found'; + + $body = $response->getBody(); + $body->rewind(); + $body->write($message); + + return $response->withStatus($code, $message)->withBody($body); + } +} diff --git a/src/Router/Routes/Glob.php b/src/Router/Routes/Glob.php index 97483d8..a9c2148 100644 --- a/src/Router/Routes/Glob.php +++ b/src/Router/Routes/Glob.php @@ -158,7 +158,7 @@ class Glob extends ArrayObject implements Routes if ($path !== '/') $path = rtrim($path, '/'); if ($this->fnmatch($path, $url)) { - if ((empty($inc) || in_array($method, $inc)) && !in_array($method, $excl)) { + if (!$method || ((empty($inc) || in_array($method, $inc)) && !in_array($method, $excl))) { $ret = $route; break; } @@ -369,9 +369,9 @@ class Glob extends ArrayObject implements Routes * @param ServerRequestInterface $request * @return boolean */ - public function hasRoute(ServerRequestInterface $request) + public function hasRoute(ServerRequestInterface $request, $withMethod = true) { - $route = $this->findRoute($request->getUri(), $request->getMethod()); + $route = $this->findRoute($request->getUri(), $withMethod ? $request->getMethod() : null); return isset($route); } |