From 352556fb00e2f4d86cece3e1a12a49357b2014eb Mon Sep 17 00:00:00 2001 From: l0gicgate Date: Sat, 20 Apr 2019 12:42:15 -0600 Subject: [PATCH 1/2] Add fullUrlFor() to RouteCollectorInterface and implementation in RouteCollector --- Slim/Interfaces/RouteCollectorInterface.php | 19 ++++++++++++++++--- Slim/Routing/RouteCollector.php | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Slim/Interfaces/RouteCollectorInterface.php b/Slim/Interfaces/RouteCollectorInterface.php index 01119b9ed..43f9db502 100644 --- a/Slim/Interfaces/RouteCollectorInterface.php +++ b/Slim/Interfaces/RouteCollectorInterface.php @@ -10,6 +10,7 @@ namespace Slim\Interfaces; use InvalidArgumentException; +use Psr\Http\Message\UriInterface; use RuntimeException; interface RouteCollectorInterface @@ -144,6 +145,8 @@ public function relativePathFor(string $name, array $data = [], array $queryPara /** * Build the path for a named route including the base path * + * This method is deprecated. Use urlFor() from now on. + * * @param string $name Route name * @param array $data Named argument replacement data * @param array $queryParams Optional query string parameters @@ -156,9 +159,7 @@ public function relativePathFor(string $name, array $data = [], array $queryPara public function pathFor(string $name, array $data = [], array $queryParams = []): string; /** - * Build the path for a named route. - * - * This method is deprecated. Use pathFor() from now on. + * Build the path for a named route including the base path * * @param string $name Route name * @param array $data Named argument replacement data @@ -170,4 +171,16 @@ public function pathFor(string $name, array $data = [], array $queryParams = []) * @throws InvalidArgumentException If required data not provided */ public function urlFor(string $name, array $data = [], array $queryParams = []): string; + + /** + * Get fully qualified URL for named route + * + * @param UriInterface $uri + * @param string $routeName Route name + * @param array $data Named argument replacement data + * @param array $queryParams Optional query string parameters + * + * @return string + */ + public function fullUrlFor(UriInterface $uri, string $routeName, array $data = [], array $queryParams = []): string; } diff --git a/Slim/Routing/RouteCollector.php b/Slim/Routing/RouteCollector.php index d648a7077..4147b5ff3 100644 --- a/Slim/Routing/RouteCollector.php +++ b/Slim/Routing/RouteCollector.php @@ -14,6 +14,7 @@ use InvalidArgumentException; use Psr\Container\ContainerInterface; use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\UriInterface; use RuntimeException; use Slim\Handlers\Strategies\RequestResponse; use Slim\Interfaces\CallableResolverInterface; @@ -376,6 +377,15 @@ public function relativePathFor(string $name, array $data = [], array $queryPara * {@inheritdoc} */ public function pathFor(string $name, array $data = [], array $queryParams = []): string + { + trigger_error('pathFor() is deprecated. Use urlFor() instead.', E_USER_DEPRECATED); + return $this->urlFor($name, $data, $queryParams); + } + + /** + * {@inheritdoc} + */ + public function urlFor(string $name, array $data = [], array $queryParams = []): string { $url = $this->relativePathFor($name, $data, $queryParams); @@ -389,9 +399,12 @@ public function pathFor(string $name, array $data = [], array $queryParams = []) /** * {@inheritdoc} */ - public function urlFor(string $name, array $data = [], array $queryParams = []): string + public function fullUrlFor(UriInterface $uri, string $routeName, array $data = [], array $queryParams = []): string { - trigger_error('urlFor() is deprecated. Use pathFor() instead.', E_USER_DEPRECATED); - return $this->pathFor($name, $data, $queryParams); + $path = $this->urlFor($routeName, $data, $queryParams); + $scheme = $uri->getScheme(); + $authority = $uri->getAuthority(); + $protocol = ($scheme ? $scheme . ':' : '') . ($authority ? '//' . $authority : ''); + return $protocol . $path; } } From e0346e6a7cd579f7f9f27c831a98d51b6f0d75e0 Mon Sep 17 00:00:00 2001 From: l0gicgate Date: Sat, 20 Apr 2019 13:00:39 -0600 Subject: [PATCH 2/2] add test coverage for fullUrlFor --- tests/Routing/RouteCollectorTest.php | 59 +++++++++++++++++++++------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/tests/Routing/RouteCollectorTest.php b/tests/Routing/RouteCollectorTest.php index d4676ee14..0448b8b1b 100644 --- a/tests/Routing/RouteCollectorTest.php +++ b/tests/Routing/RouteCollectorTest.php @@ -9,6 +9,7 @@ namespace Slim\Tests\Routing; +use Psr\Http\Message\UriInterface; use RuntimeException; use Slim\CallableResolver; use Slim\Interfaces\RouteInterface; @@ -116,7 +117,7 @@ public function testPathForWithNoBasePath() $this->assertEquals( '/hello/josh/lockhart', - $this->routeCollector->pathFor('foo', ['first' => 'josh', 'last' => 'lockhart']) + $this->routeCollector->urlFor('foo', ['first' => 'josh', 'last' => 'lockhart']) ); } @@ -133,7 +134,7 @@ public function testPathForWithBasePath() $this->assertEquals( '/base/path/hello/josh/lockhart', - $this->routeCollector->pathFor('foo', ['first' => 'josh', 'last' => 'lockhart']) + $this->routeCollector->urlFor('foo', ['first' => 'josh', 'last' => 'lockhart']) ); } @@ -149,15 +150,15 @@ public function testPathForWithOptionalParameters() $this->assertEquals( '/archive/2015', - $this->routeCollector->pathFor('foo', ['year' => '2015']) + $this->routeCollector->urlFor('foo', ['year' => '2015']) ); $this->assertEquals( '/archive/2015/07', - $this->routeCollector->pathFor('foo', ['year' => '2015', 'month' => '07']) + $this->routeCollector->urlFor('foo', ['year' => '2015', 'month' => '07']) ); $this->assertEquals( '/archive/2015/07/d/19', - $this->routeCollector->pathFor('foo', ['year' => '2015', 'month' => '07', 'day' => '19']) + $this->routeCollector->urlFor('foo', ['year' => '2015', 'month' => '07', 'day' => '19']) ); } @@ -173,7 +174,7 @@ public function testPathForWithQueryParameters() $this->assertEquals( '/hello/josh?a=b&c=d', - $this->routeCollector->pathFor('foo', ['name' => 'josh'], ['a' => 'b', 'c' => 'd']) + $this->routeCollector->urlFor('foo', ['name' => 'josh'], ['a' => 'b', 'c' => 'd']) ); } @@ -190,7 +191,7 @@ public function testPathForWithMissingSegmentData() $route = $this->routeCollector->map($methods, $pattern, $callable); $route->setName('foo'); - $this->routeCollector->pathFor('foo', ['last' => 'lockhart']); + $this->routeCollector->urlFor('foo', ['last' => 'lockhart']); } /** @@ -206,7 +207,7 @@ public function testPathForRouteNotExists() $route = $this->routeCollector->map($methods, $pattern, $callable); $route->setName('foo'); - $this->routeCollector->pathFor('bar', ['first' => 'josh', 'last' => 'lockhart']); + $this->routeCollector->urlFor('bar', ['first' => 'josh', 'last' => 'lockhart']); } public function testGetRouteInvocationStrategy() @@ -344,10 +345,10 @@ public function testCacheFileDoesNotExistsAndDirectoryIsNotWritable() } /** - * Test that the router urlFor will proxy into a pathFor method, and trigger + * Test that the router pathFor will proxy into a urlFor method, and trigger * the user deprecated warning */ - public function testUrlForAliasesPathFor() + public function testPathForAliasesUrlFor() { //create a temporary error handler, store the error str in this value $errorString = null; @@ -365,17 +366,47 @@ public function testUrlForAliasesPathFor() $routeCollector = $this ->getMockBuilder(RouteCollector::class) ->setConstructorArgs([$this->getResponseFactory(), new CallableResolver()]) - ->setMethods(['pathFor']) + ->setMethods(['urlFor']) ->getMock(); - $routeCollector->expects($this->once())->method('pathFor')->with($name, $data, $queryParams); - $routeCollector->urlFor($name, $data, $queryParams); + $routeCollector->expects($this->once())->method('urlFor')->with($name, $data, $queryParams); + $routeCollector->pathFor($name, $data, $queryParams); //check that our error was triggered - $this->assertEquals($errorString, 'urlFor() is deprecated. Use pathFor() instead.'); + $this->assertEquals($errorString, 'pathFor() is deprecated. Use urlFor() instead.'); restore_error_handler(); } + public function testFullUrlFor() + { + $uriProphecy = $this->prophesize(UriInterface::class); + $uriProphecy + ->getScheme() + ->willReturn('http') + ->shouldBeCalledOnce(); + + $uriProphecy + ->getAuthority() + ->willReturn('example.com:8080') + ->shouldBeCalledOnce(); + + $callableResolver = new CallableResolver(); + $responseFactory = $this->getResponseFactory(); + $routeCollector = new RouteCollector($responseFactory, $callableResolver); + $routeCollector->setBasePath('/app'); + + $callable = function ($request, $response) { + return $response; + }; + $route = $routeCollector->map(['GET'], '/{token}', $callable); + $route->setName('test'); + + $expectedResult = 'http://example.com:8080/app/123'; + $result = $routeCollector->fullUrlFor($uriProphecy->reveal(), 'test', ['token' => '123']); + + $this->assertEquals($expectedResult, $result); + } + /** * @expectedException \RuntimeException */