summaryrefslogtreecommitdiffstats
path: root/src/Router.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Router.php')
-rw-r--r--src/Router.php50
1 files changed, 45 insertions, 5 deletions
diff --git a/src/Router.php b/src/Router.php
index 5cc2108..7a4f5c8 100644
--- a/src/Router.php
+++ b/src/Router.php
@@ -94,22 +94,62 @@ class Router
}
/**
- * Add middleware call to router
+ * Add middleware call to router.
*
- * @param callback $middleware
+ * @param string $path Middleware is only applied for this path (including subdirectories), may be omitted
+ * @param callable $middleware
* @return Router $this
*/
- public function add($middleware)
+ public function add($path, $middleware = null)
{
+ if (!isset($middleware)) {
+ $middleware = $path;
+ $path = null;
+ }
+
+ if (!empty($path) && !ctype_digit($path) && $path[0] !== '/') {
+ trigger_error("Middleware path '$path' doesn't start with a '/'", E_USER_NOTICE);
+ }
+
if (!is_callable($middleware)) {
throw new \InvalidArgumentException("Middleware should be callable");
}
+ if (!empty($path)) {
+ $middleware = $this->wrapMiddleware($path, $middleware);
+ }
+
$this->middlewares[] = $middleware;
-
+
return $this;
}
+ /**
+ * Wrap middleware, so it's only applied to a specified path
+ *
+ * @param string $path
+ * @param callable $middleware
+ * @return callable
+ */
+ protected function wrapMiddleware($path, $middleware)
+ {
+ return function(
+ ServerRequestInterface $request,
+ ResponseInterface $response,
+ $next
+ ) use ($middleware, $path) {
+ $uriPath = $request->getUri()->getPath();
+
+ if ($uriPath === $path || strpos($uriPath, rtrim($path, '/') . '/') === 0) {
+ $ret = $middleware($request, $response, $next);
+ } else {
+ $ret = $next($request, $response);
+ }
+
+ return $ret;
+ };
+ }
+
/**
* Run the action for the request
@@ -137,7 +177,7 @@ class Router
return $this->run($request, $response, $next);
}
- $stack = array_merge([[$this, 'run']], $this->middlewares);
+ $stack = array_reverse(array_merge($this->middlewares, [[$this, 'run']]));
// Turn the stack into a call chain
foreach ($stack as $handle) {