From f0b985831f72a896735d02bf14b1c6680e3d7092 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Tue, 22 Nov 2016 16:43:51 -0600 Subject: [PATCH] working on url generation customization --- composer.json | 3 +- src/Illuminate/Routing/UrlGenerator.php | 62 +++++++++++++++++++++-- tests/Routing/RoutingUrlGeneratorTest.php | 21 ++++++++ 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index a8417bef5a8a..29c2ea5d02a8 100644 --- a/composer.json +++ b/composer.json @@ -113,5 +113,6 @@ "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (3.2.*).", "symfony/psr-http-message-bridge": "Required to psr7 bridging features (0.2.*)." }, - "minimum-stability": "dev" + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/src/Illuminate/Routing/UrlGenerator.php b/src/Illuminate/Routing/UrlGenerator.php index ddda777bfd0c..127c9625cc32 100755 --- a/src/Illuminate/Routing/UrlGenerator.php +++ b/src/Illuminate/Routing/UrlGenerator.php @@ -2,6 +2,7 @@ namespace Illuminate\Routing; +use Closure; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Http\Request; @@ -71,6 +72,20 @@ class UrlGenerator implements UrlGeneratorContract */ protected $sessionResolver; + /** + * The callback to use to format hosts. + * + * @var \Closure + */ + protected $formatHostUsing; + + /** + * The callback to use to format paths. + * + * @var \Closure + */ + protected $formatPathUsing; + /** * Characters that should not be URL encoded. * @@ -185,7 +200,7 @@ public function to($path, $extra = [], $secure = null) $query = ''; } - return $this->trimUrl($root, $path, $tail).$query; + return $this->buildCompleteUrl($root, $path, $tail).$query; } /** @@ -330,7 +345,7 @@ protected function toRoute($route, $parameters, $absolute) $domain = $this->getRouteDomain($route, $parameters); - $uri = $this->addQueryString($this->trimUrl( + $uri = $this->addQueryString($this->buildCompleteUrl( $root = $this->replaceRoot($route, $domain, $parameters), $this->replaceRouteParameters($route->uri(), $parameters) ), $parameters); @@ -402,7 +417,7 @@ protected function replaceNamedParameters($path, &$parameters) */ protected function addQueryString($uri, array $parameters) { - // If the URI has a fragment, we will move it to the end of this URI since it will + // If the URI has a fragment we will move it to the end of this URI since it will // need to come after any query string that may be added to the URL else it is // not going to be available. We will remove it then append it back on here. if (! is_null($fragment = parse_url($uri, PHP_URL_FRAGMENT))) { @@ -636,6 +651,7 @@ protected function getRootUrl($scheme, $root = null) public function forceRootUrl($root) { $this->forcedRoot = rtrim($root, '/'); + $this->cachedRoot = null; } @@ -662,9 +678,45 @@ public function isValidUrl($path) * @param string $tail * @return string */ - protected function trimUrl($root, $path, $tail = '') + protected function buildCompleteUrl($root, $path, $tail = '') + { + $path = '/'.trim($path.'/'.$tail, '/'); + + if ($this->formatHostUsing) { + $root = call_user_func($this->formatHostUsing, $root); + } + + if ($this->formatPathUsing) { + $path = call_user_func($this->formatPathUsing, $path); + } + + return trim($root.$path, '/'); + } + + /** + * Set a callback to be used to format the host of generated URLs. + * + * @param \Closure $callback + * @return $this + */ + public function formatHostUsing(Closure $callback) + { + $this->formatHostUsing = $callback; + + return $this; + } + + /** + * Set a callback to be used to format the path of generated URLs. + * + * @param \Closure $callback + * @return $this + */ + public function formatPathUsing(Closure $callback) { - return trim($root.'/'.trim($path.'/'.$tail, '/'), '/'); + $this->formatPathUsing = $callback; + + return $this; } /** diff --git a/tests/Routing/RoutingUrlGeneratorTest.php b/tests/Routing/RoutingUrlGeneratorTest.php index 1950eb4fdf6e..9e817bc43bda 100755 --- a/tests/Routing/RoutingUrlGeneratorTest.php +++ b/tests/Routing/RoutingUrlGeneratorTest.php @@ -42,6 +42,27 @@ public function testBasicGeneration() $this->assertEquals('https://www.foo.com/foo/bar', $url->asset('foo/bar', true)); } + public function testBasicGenerationWithFormatting() + { + $url = new UrlGenerator( + $routes = new RouteCollection, + $request = Request::create('http://www.foo.com/') + ); + + /* + * Empty Named Route + */ + $route = new Route(['GET'], '/named-route', ['as' => 'plain']); + $routes->add($route); + + $url->formatPathUsing(function ($path) { + return '/something'.$path; + }); + + $this->assertEquals('http://www.foo.com/something/foo/bar', $url->to('foo/bar')); + $this->assertEquals('/something/named-route', $url->route('plain', [], false)); + } + public function testBasicRouteGeneration() { $url = new UrlGenerator(