From dd5471edb76dc29bf0b20eaa4dc16a81d25c9f71 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 18 Mar 2024 17:51:57 +0300 Subject: [PATCH 1/4] minor refactoring --- src/UrlGenerator.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/UrlGenerator.php b/src/UrlGenerator.php index e41b4da..453e10e 100644 --- a/src/UrlGenerator.php +++ b/src/UrlGenerator.php @@ -34,7 +34,7 @@ final class UrlGenerator implements UrlGeneratorInterface public function __construct( private RouteCollectionInterface $routeCollection, private ?CurrentRoute $currentRoute = null, - RouteParser $parser = null + ?RouteParser $parser = null, ) { $this->routeParser = $parser ?? new RouteParser\Std(); } @@ -88,8 +88,8 @@ public function generateAbsolute( string $name, array $arguments = [], array $queryParameters = [], - string $scheme = null, - string $host = null + ?string $scheme = null, + ?string $host = null ): string { $url = $this->generate($name, $arguments, $queryParameters); $route = $this->routeCollection->getRoute($name); @@ -114,8 +114,11 @@ public function generateAbsolute( /** * {@inheritdoc} */ - public function generateFromCurrent(array $replacedArguments, array $queryParameters = [], string $fallbackRouteName = null): string - { + public function generateFromCurrent( + array $replacedArguments, + array $queryParameters = [], + ?string $fallbackRouteName = null, + ): string { if ($this->currentRoute === null || $this->currentRoute->getName() === null) { if ($fallbackRouteName !== null) { return $this->generate($fallbackRouteName, $replacedArguments); From 11d0c3908c2ef030f22b37bcd8a47fb3e35b8c21 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 18 Mar 2024 18:27:54 +0300 Subject: [PATCH 2/4] Add optional default host and scheme to `UrlGenerator` --- CHANGELOG.md | 1 + src/UrlGenerator.php | 17 +++-- tests/UrlGeneratorTest.php | 125 +++++++++++++++++++++++++++---------- 3 files changed, 107 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31a10b5..a738802 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 3.0.2 under development +- New #144: Add optional default host and scheme to `UrlGenerator` (@vjik) - Enh #139: Add support for `psr/http-message` version `^2.0` (@vjik) ## 3.0.1 December 24, 2023 diff --git a/src/UrlGenerator.php b/src/UrlGenerator.php index 453e10e..47ba84b 100644 --- a/src/UrlGenerator.php +++ b/src/UrlGenerator.php @@ -35,6 +35,8 @@ public function __construct( private RouteCollectionInterface $routeCollection, private ?CurrentRoute $currentRoute = null, ?RouteParser $parser = null, + private ?string $scheme = null, + private ?string $host = null, ) { $this->routeParser = $parser ?? new RouteParser\Std(); } @@ -96,16 +98,23 @@ public function generateAbsolute( $uri = $this->currentRoute && $this->currentRoute->getUri() !== null ? $this->currentRoute->getUri() : null; $lastRequestScheme = $uri?->getScheme(); - if ($host !== null || ($host = $route->getData('host')) !== null) { - if ($scheme === null && !$this->isRelative($host)) { + $host = $host ?? $route->getData('host') ?? $this->host ?? null; + if ($host !== null) { + $isRelativeHost = $this->isRelative($host); + + $scheme ??= $isRelativeHost + ? $this->scheme ?? $lastRequestScheme + : null; + + if ($scheme === null && !$isRelativeHost) { return rtrim($host, '/') . $url; } - if ((empty($scheme) || $lastRequestScheme === null) && $host !== '' && $this->isRelative($host)) { + if ($host !== '' && $isRelativeHost) { $host = '//' . $host; } - return $this->ensureScheme(rtrim($host, '/') . $url, $scheme ?? $lastRequestScheme); + return $this->ensureScheme(rtrim($host, '/') . $url, $scheme); } return $uri === null ? $url : $this->generateAbsoluteFromLastMatchedRequest($url, $uri, $scheme); diff --git a/tests/UrlGeneratorTest.php b/tests/UrlGeneratorTest.php index ab3bb2a..779bbb5 100644 --- a/tests/UrlGeneratorTest.php +++ b/tests/UrlGeneratorTest.php @@ -187,7 +187,7 @@ public function testQueryParametersAddedAsQueryString(): void { $routes = [ Route::get('/test/{name}') - ->name('test'), + ->name('test'), ]; $url = $this @@ -200,7 +200,7 @@ public function testQueryParametersAddedAsQueryStringWithEmptyValues(): void { $routes = [ Route::get('/test/{name}') - ->name('test'), + ->name('test'), ]; $url = $this @@ -213,7 +213,7 @@ public function testQueryParametersOverrideExtraArguments(): void { $routes = [ Route::get('/test/{name}') - ->name('test'), + ->name('test'), ]; $url = $this @@ -226,7 +226,7 @@ public function testNotSubstitutedArgumentsRemove(): void { $routes = [ Route::get('/test/{name}') - ->name('test'), + ->name('test'), ]; $url = $this @@ -239,8 +239,8 @@ public function testDefaultNotUsedForOptionalArgument(): void { $routes = [ Route::get('/[{name}]') - ->name('defaults') - ->defaults(['name' => 'default']), + ->name('defaults') + ->defaults(['name' => 'default']), ]; $url = $this @@ -253,8 +253,8 @@ public function testValueUsedForOptionalArgument(): void { $routes = [ Route::get('/[{name}]') - ->name('defaults') - ->defaults(['name' => 'default']), + ->name('defaults') + ->defaults(['name' => 'default']), ]; $url = $this @@ -267,8 +267,8 @@ public function testDefaultNotUsedForRequiredParameter(): void { $routes = [ Route::get('/{name}') - ->name('defaults') - ->defaults(['name' => 'default']), + ->name('defaults') + ->defaults(['name' => 'default']), ]; $this->expectExceptionMessage('Route `defaults` expects at least argument values for [name], but received []'); @@ -284,8 +284,8 @@ public function testAbsoluteUrlHostOverride(): void { $routes = [ Route::get('/home/index') - ->name('index') - ->host('http://test.com'), + ->name('index') + ->host('http://test.com'), ]; $url = $this ->createUrlGenerator($routes) @@ -301,8 +301,8 @@ public function testAbsoluteUrlHostOverrideWithTrailingSlash(): void { $routes = [ Route::get('/home/index') - ->name('index') - ->host('http://test.com'), + ->name('index') + ->host('http://test.com'), ]; $url = $this ->createUrlGenerator($routes) @@ -318,8 +318,8 @@ public function testAbsoluteUrlSchemeOverrideHostInRouteScheme(): void { $routes = [ Route::get('/home/index') - ->name('index') - ->host('http://test.com'), + ->name('index') + ->host('http://test.com'), ]; $url = $this ->createUrlGenerator($routes) @@ -368,8 +368,8 @@ public function testAbsoluteUrlWithHostInRoute(): void { $routes = [ Route::get('/home/index') - ->name('index') - ->host('http://test.com'), + ->name('index') + ->host('http://test.com'), ]; $url = $this ->createUrlGenerator($routes) @@ -385,8 +385,8 @@ public function testAbsoluteUrlWithTrailingSlashHostInRoute(): void { $routes = [ Route::get('/home/index') - ->name('index') - ->host('http://test.com/'), + ->name('index') + ->host('http://test.com/'), ]; $url = $this ->createUrlGenerator($routes) @@ -443,8 +443,8 @@ public function testHostInRouteWithProtocolRelativeSchemeAbsoluteUrl(): void $request = new ServerRequest('GET', 'http://test.com/home/index'); $routes = [ Route::get('/home/index') - ->name('index') - ->host('//test.com'), + ->name('index') + ->host('//test.com'), ]; $currentRoute = new CurrentRoute(); @@ -465,8 +465,8 @@ public function testHostInMethodWithProtocolRelativeSchemeAbsoluteUrl(): void $request = new ServerRequest('GET', 'http://test.com/home/index'); $routes = [ Route::get('/home/index') - ->name('index') - ->host('//mysite.com'), + ->name('index') + ->host('//mysite.com'), ]; $currentRoute = new CurrentRoute(); @@ -483,11 +483,11 @@ public function testHostInRouteProtocolRelativeSchemeAbsoluteUrl(): void $request = new ServerRequest('GET', 'http://test.com/home/index'); $routes = [ Route::get('/home/index') - ->name('index') - ->host('http://test.com'), + ->name('index') + ->host('http://test.com'), Route::get('/home/view') - ->name('view') - ->host('test.com'), + ->name('view') + ->host('test.com'), ]; $currentRoute = new CurrentRoute(); @@ -508,8 +508,8 @@ public function testHostInMethodProtocolRelativeSchemeAbsoluteUrl(): void $request = new ServerRequest('GET', 'http://test.com/home/index'); $routes = [ Route::get('/home/index') - ->name('index') - ->host('//mysite.com'), + ->name('index') + ->host('//mysite.com'), ]; $currentRoute = new CurrentRoute(); @@ -560,8 +560,8 @@ public function testHostInRouteWithoutSchemeAbsoluteUrl(): void $request = new ServerRequest('GET', 'http://example.com/home/index'); $routes = [ Route::get('/home/index') - ->name('index') - ->host('example.com'), + ->name('index') + ->host('example.com'), ]; $currentRoute = new CurrentRoute(); @@ -853,6 +853,67 @@ public function testNotFoundRoutes(): void $urlGenerator->generate('index'); } + public function testDefaultHostAndScheme(): void + { + $urlGenerator = new UrlGenerator( + $this->createRouteCollection([Route::get('/home/index')->name('index')]), + scheme: 'https', + host: 'example.com', + ); + + $url = $urlGenerator->generateAbsolute('index'); + + $this->assertSame('https://example.com/home/index', $url); + } + + public function testOverrideDefaultHostAndSchemeFromMethodArguments(): void + { + $urlGenerator = new UrlGenerator( + $this->createRouteCollection([Route::get('/home/index')->name('index')]), + scheme: 'https', + host: 'example.com', + ); + + $url = $urlGenerator->generateAbsolute('index', scheme: 'http', host: 'example.yii'); + + $this->assertSame('http://example.yii/home/index', $url); + } + + public function testOverrideDefaultHostAndSchemeFromRoute(): void + { + $urlGenerator = new UrlGenerator( + $this->createRouteCollection([ + Route::get('/home/index') + ->host('//test.yii') + ->name('index') + ]), + scheme: 'https', + host: 'example.com', + ); + + $url = $urlGenerator->generateAbsolute('index'); + + $this->assertSame('//test.yii/home/index', $url); + } + + public function testDefaultHostAndSchemeWithUri(): void + { + $request = new ServerRequest('GET', 'http://test.com/home/index'); + $currentRoute = new CurrentRoute(); + $currentRoute->setUri($request->getUri()); + + $urlGenerator = new UrlGenerator( + $this->createRouteCollection([Route::get('/home/index')->name('index')]), + $currentRoute, + scheme: 'https', + host: 'example.com', + ); + + $url = $urlGenerator->generateAbsolute('index'); + + $this->assertSame('https://example.com/home/index', $url); + } + private function createUrlGenerator( array $routes, CurrentRoute $currentRoute = null, From b221b1b099170e04267231aec5785682f3eacda9 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Mon, 18 Mar 2024 15:28:40 +0000 Subject: [PATCH 3/4] Apply fixes from StyleCI --- tests/UrlGeneratorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/UrlGeneratorTest.php b/tests/UrlGeneratorTest.php index 779bbb5..a71ceef 100644 --- a/tests/UrlGeneratorTest.php +++ b/tests/UrlGeneratorTest.php @@ -885,7 +885,7 @@ public function testOverrideDefaultHostAndSchemeFromRoute(): void $this->createRouteCollection([ Route::get('/home/index') ->host('//test.yii') - ->name('index') + ->name('index'), ]), scheme: 'https', host: 'example.com', From 8e00264dbde9f4beef5a8250b46ecd2074380641 Mon Sep 17 00:00:00 2001 From: vjik Date: Mon, 18 Mar 2024 15:28:59 +0000 Subject: [PATCH 4/4] Apply Rector changes (CI) --- src/UrlGenerator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UrlGenerator.php b/src/UrlGenerator.php index 47ba84b..f661d53 100644 --- a/src/UrlGenerator.php +++ b/src/UrlGenerator.php @@ -98,7 +98,7 @@ public function generateAbsolute( $uri = $this->currentRoute && $this->currentRoute->getUri() !== null ? $this->currentRoute->getUri() : null; $lastRequestScheme = $uri?->getScheme(); - $host = $host ?? $route->getData('host') ?? $this->host ?? null; + $host ??= $route->getData('host') ?? $this->host ?? null; if ($host !== null) { $isRelativeHost = $this->isRelative($host);