summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArnold Daniels <arnold@jasny.net>2016-10-19 22:21:42 +0200
committerGitHub <noreply@github.com>2016-10-19 22:21:42 +0200
commitbbd7fe10d23e838271c94dbca59dd986cb7c8620 (patch)
treee88d1b3c7b5a75d0a9eda7b3476fa027fdef14e1 /src
parenteac4807a6bd68631470f99b7dc487022b9bd37f9 (diff)
parentf55bccf1c0fb060f548db7838c533755f21f493d (diff)
downloadrouter-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.php118
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);
+ }
+}