diff --git a/Slim/App.php b/Slim/App.php index 65dab6a2a..a34a825f1 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -12,6 +12,7 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\UriInterface; use Slim\Http\Headers; use Slim\Http\Request; use Slim\Http\Response; @@ -345,6 +346,24 @@ public function map(array $methods, $pattern, $callable) return $route; } + /** + * Add a route that sends an HTTP redirect + * + * @param string $from + * @param string|UriInterface $to + * @param int $status + * + * @return RouteInterface + */ + public function redirect($from, $to, $status = 302) + { + $handler = function ($request, ResponseInterface $response) use ($to, $status) { + return $response->withHeader('Location', (string)$to)->withStatus($status); + }; + + return $this->get($from, $handler); + } + /** * Route Groups * diff --git a/tests/AppTest.php b/tests/AppTest.php index 2f82b886e..0053e9037 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -12,6 +12,7 @@ use Pimple\Container as Pimple; use Pimple\Psr11\Container as Psr11Container; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\UriInterface; use Slim\App; use Slim\CallableResolver; use Slim\Error\Renderers\HtmlErrorRenderer; @@ -253,6 +254,33 @@ public function testMapRoute() $this->assertAttributeContains('POST', 'methods', $route); } + public function testRedirectRoute() + { + $source = '/foo'; + $destination = '/bar'; + + $app = new App(); + $route = $app->redirect($source, $destination, 301); + + $this->assertInstanceOf('\Slim\Route', $route); + $this->assertAttributeContains('GET', 'methods', $route); + + $response = $route->run($this->requestFactory($source), new Response()); + $this->assertEquals(301, $response->getStatusCode()); + $this->assertEquals($destination, $response->getHeaderLine('Location')); + + $routeWithDefaultStatus = $app->redirect($source, $destination); + $response = $routeWithDefaultStatus->run($this->requestFactory($source), new Response()); + $this->assertEquals(302, $response->getStatusCode()); + + $uri = $this->getMockBuilder(UriInterface::class)->getMock(); + $uri->expects($this->once())->method('__toString')->willReturn($destination); + + $routeToUri = $app->redirect($source, $uri); + $response = $routeToUri->run($this->requestFactory($source), new Response()); + $this->assertEquals($destination, $response->getHeaderLine('Location')); + } + /******************************************************************************** * Route Patterns *******************************************************************************/