Skip to content

Commit

Permalink
Fix: keep query string when generating from current route (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
rustamwin committed Nov 3, 2022
1 parent 0152fc3 commit ca57da4
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 46 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -2,7 +2,7 @@

## 1.1.2 under development

- no changes in this release.
- Bug #107: Keep query string when generating from current route (@rustamwin)

## 1.1.1 June 28, 2022

Expand Down
14 changes: 8 additions & 6 deletions src/UrlGenerator.php
Expand Up @@ -95,8 +95,6 @@ public function generateAbsolute(
string $scheme = null,
string $host = null
): string {
$arguments = array_map('\strval', $arguments);

$url = $this->generate($name, $arguments, $queryParameters);
$route = $this->routeCollection->getRoute($name);
$uri = $this->currentRoute && $this->currentRoute->getUri() !== null ? $this->currentRoute->getUri() : null;
Expand Down Expand Up @@ -128,18 +126,22 @@ public function generateFromCurrent(array $replacedArguments, string $fallbackRo
}

if ($this->currentRoute !== null && $this->currentRoute->getUri() !== null) {
return $this->currentRoute
->getUri()
->getPath();
return $this->currentRoute->getUri()->getPath();
}

throw new RuntimeException('Current route is not detected.');
}

$queryParameters = [];
if ($this->currentRoute->getUri() !== null) {
parse_str($this->currentRoute->getUri()->getQuery(), $queryParameters);
}

/** @psalm-suppress PossiblyNullArgument Checked route name on null above. */
return $this->generate(
$this->currentRoute->getName(),
array_merge($this->currentRoute->getArguments(), $replacedArguments)
array_merge($this->currentRoute->getArguments(), $replacedArguments),
$queryParameters,
);
}

Expand Down
142 changes: 103 additions & 39 deletions tests/UrlGeneratorTest.php
Expand Up @@ -187,7 +187,7 @@ public function testQueryParametersAddedAsQueryString(): void
{
$routes = [
Route::get('/test/{name}')
->name('test'),
->name('test'),
];

$url = $this
Expand All @@ -200,7 +200,7 @@ public function testExtraArgumentsAddedAsQueryString(): void
{
$routes = [
Route::get('/test/{name}')
->name('test'),
->name('test'),
];

$url = $this
Expand All @@ -213,7 +213,7 @@ public function testQueryParametersOverrideExtraArguments(): void
{
$routes = [
Route::get('/test/{name}')
->name('test'),
->name('test'),
];

$url = $this
Expand All @@ -226,7 +226,7 @@ public function testQueryParametersMergedWithExtraArguments(): void
{
$routes = [
Route::get('/test/{name}')
->name('test'),
->name('test'),
];

$url = $this
Expand All @@ -239,8 +239,8 @@ public function testDefaultNotUsedForOptionalArgument(): void
{
$routes = [
Route::get('/[{name}]')
->name('defaults')
->defaults(['name' => 'default']),
->name('defaults')
->defaults(['name' => 'default']),
];

$url = $this
Expand All @@ -253,8 +253,8 @@ public function testValueUsedForOptionalArgument(): void
{
$routes = [
Route::get('/[{name}]')
->name('defaults')
->defaults(['name' => 'default']),
->name('defaults')
->defaults(['name' => 'default']),
];

$url = $this
Expand All @@ -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 []');
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -655,20 +655,84 @@ public function testAbsoluteWithDefaultsOverride(): void
$this->assertEquals('http://example.com/ru/home/index', $url);
}

public function testGenerateFromCurrent(): void
public function currentRouteArgumentsProvider(): array
{
$request = new ServerRequest('GET', 'http://example.com/en/home/index');
$route = Route::get('/{_locale}/home/index')->name('index');
return [
[
'http://example.com/en/home/index',
'/home/index',
Route::get('/home/index')->name('index'),
[],
[],
[],
],
[
'http://example.com/en/home/index',
'/en/home/index',
Route::get('/{_locale}/home/index')->name('index'),
['_locale' => 'en'],
[],
[],
],
[
'http://example.com/en/home/index',
'/uz/home/index',
Route::get('/{_locale}/home/index')->name('index'),
[],
['_locale', 'uz'],
[],
],
[
'http://example.com/en/home/index',
'/en/home/index',
Route::get('/{_locale}/home/index')->name('index'),
['_locale' => 'en'],
['_locale', 'en'],
[],
],
[
'http://example.com/en/home/index',
'/ru/home/index',
Route::get('/{_locale}/home/index')->name('index'),
['_locale' => 'en'],
['_locale', 'uz'],
['_locale' => 'ru'],
],
[
'http://example.com/en/home/index?test=1',
'/ru/home/index?test=1',
Route::get('/{_locale}/home/index')->name('index'),
['_locale' => 'en'],
['_locale', 'uz'],
['_locale' => 'ru'],
],
];
}

/**
* @dataProvider currentRouteArgumentsProvider
*/
public function testGenerateFromCurrentWithArguments(
string $uri,
string $expectedUrl,
Route $route,
array $routeArguments,
array $defaultArgument,
array $replacedArguments
): void {
$request = new ServerRequest('GET', $uri);

$currentRoute = new CurrentRoute();
$currentRoute->setUri($request->getUri());
$currentRoute->setRouteWithArguments($route, ['_locale' => 'en']);
$currentRoute->setRouteWithArguments($route, $routeArguments);
$urlGenerator = $this->createUrlGenerator([$route], $currentRoute);
$urlGenerator->setDefaultArgument('_locale', 'uz');
if ($defaultArgument !== []) {
$urlGenerator->setDefaultArgument($defaultArgument[0], $defaultArgument[1]);
}

$url = $urlGenerator->generateFromCurrent(['_locale' => 'ru']);
$url = $urlGenerator->generateFromCurrent($replacedArguments);

$this->assertEquals('/ru/home/index', $url);
$this->assertEquals($expectedUrl, $url);
}

public function testGenerateFromCurrentWithFallbackRoute(): void
Expand Down

0 comments on commit ca57da4

Please sign in to comment.