diff options
author | Arnold Daniels <arnold@jasny.net> | 2016-10-19 22:21:42 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-19 22:21:42 +0200 |
commit | bbd7fe10d23e838271c94dbca59dd986cb7c8620 (patch) | |
tree | e88d1b3c7b5a75d0a9eda7b3476fa027fdef14e1 /src | |
parent | eac4807a6bd68631470f99b7dc487022b9bd37f9 (diff) | |
parent | f55bccf1c0fb060f548db7838c533755f21f493d (diff) | |
download | router-bbd7fe10d23e838271c94dbca59dd986cb7c8620.zip router-bbd7fe10d23e838271c94dbca59dd986cb7c8620.tar.gz router-bbd7fe10d23e838271c94dbca59dd986cb7c8620.tar.bz2 |
Merge pull request #9 from Minstel/middleware-base-path
'Base Path' middleware
Diffstat (limited to 'src')
-rw-r--r-- | src/Router/Middleware/BasePath.php | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/Router/Middleware/BasePath.php b/src/Router/Middleware/BasePath.php new file mode 100644 index 0000000..a80d029 --- /dev/null +++ b/src/Router/Middleware/BasePath.php @@ -0,0 +1,118 @@ +<?php + +namespace Jasny\Router\Middleware; + +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\ResponseInterface; + +/** + * Set base path for request + */ +class BasePath +{ + /** + * Base path + * @var string + **/ + protected $basePath = ''; + + /** + * Set base path + * + * @param string $basePath + */ + public function __construct($basePath) + { + if (!$basePath || !is_string($basePath) || $basePath === '/') { + throw new \InvalidArgumentException("Base path must be a string with at list one url segment"); + } + + $this->basePath = $this->normalizePath($basePath); + } + + /** + * Get base path + * + * @return string + */ + public function getBasePath() + { + return $this->basePath; + } + + /** + * Run middleware action + * + * @param ServerRequestInterface $request + * @param ResponseInterface $response + * @param callback $next + * @return ResponseInterface + */ + public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next) + { + if (!is_callable($next)) { + throw new \InvalidArgumentException("'next' should be a callback"); + } + + $uri = $request->getUri(); + $path = $this->normalizePath($uri->getPath()); + + if (!$this->hasBasePath($path)) return $this->setError($response); + + $noBase = $this->getBaselessPath($path); + $noBaseUri = $uri->withPath($noBase); + $request = $request->withUri($noBaseUri)->withAttribute('original_uri', $uri); + + return call_user_func($next, $request, $response); + } + + /** + * Remove base path from given path + * + * @param string $path + * @return string + */ + protected function getBaselessPath($path) + { + return substr($path, strlen($this->getBasePath())) ?: '/'; + } + + /** + * Normalize path + * + * @param string $path + * @return string + */ + protected function normalizePath($path) + { + return '/' . ltrim($path, '/'); + } + + /** + * Check that path starts with base path + * + * @param string $path + * @return boolean + */ + protected function hasBasePath($path) + { + return strpos($path . '/', $this->getBasePath() . '/') === 0; + } + + /** + * Set error response + * + * @param ResponseInterface $response + * @return ResponseInterface + */ + protected function setError($response) + { + $message = 'Not Found'; + + $body = $response->getBody(); + $body->rewind(); + $body->write($message); + + return $response->withStatus(404, $message)->withBody($body); + } +} |