Skip to content

Commit 25365bf

Browse files
committed
Handle optional route parameters with Route::localizedUrl()
1 parent fbd34fe commit 25365bf

File tree

2 files changed

+63
-15
lines changed

2 files changed

+63
-15
lines changed

src/LocalizedUrlGenerator.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ protected function updateLocaleInSlugs(array $slugs, $locale)
306306
*/
307307
protected function extractQueryParameters($uri, $parameters)
308308
{
309-
preg_match_all('/{([a-z_.-]+)}/', $uri, $matches);
309+
preg_match_all('/{([a-z_.-]+\??)}/', $uri, $matches);
310310
$paramKeys = $matches[1] ?? [];
311311

312312
$slugs = [];
@@ -347,6 +347,8 @@ protected function replaceParameters($uri, $parameters)
347347
$uri = str_replace($placeholder, $value, $uri);
348348
}
349349

350+
$uri = preg_replace('/{[a-z_.-]+\?}/', '', $uri);
351+
350352
return $uri;
351353
}
352354

tests/Unit/Macros/LocalizedUrlMacroTest.php

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -685,20 +685,20 @@ public function it_accepts_query_string_parameters_using_named_routes()
685685
$this->withoutExceptionHandling();
686686
$this->setSupportedLocales(['en', 'nl']);
687687

688-
Route::get('route/{slug}', function () {
688+
Route::get('route/{slug}/{optional?}', function () {
689689
return [
690-
'current' => Route::localizedUrl(null, ['another-slug', 'new' => 'value']),
691-
'en' => Route::localizedUrl('en', ['another-slug', 'new' => 'value']),
692-
'nl' => Route::localizedUrl('nl', ['another-slug', 'new' => 'value']),
690+
'current' => Route::localizedUrl(null, ['another-slug', 'optional-slug', 'new' => 'value']),
691+
'en' => Route::localizedUrl('en', ['another-slug', 'optional-slug', 'new' => 'value']),
692+
'nl' => Route::localizedUrl('nl', ['another-slug', 'optional-slug', 'new' => 'value']),
693693
];
694694
})->name('route');
695695

696696
$response = $this->call('GET', '/route/some-slug?param=value');
697697
$response->assertOk();
698698
$this->assertEquals([
699-
'current' => url('/route/another-slug?new=value'),
700-
'en' => url('/route/another-slug?new=value'),
701-
'nl' => url('/route/another-slug?new=value'),
699+
'current' => url('/route/another-slug/optional-slug?new=value'),
700+
'en' => url('/route/another-slug/optional-slug?new=value'),
701+
'nl' => url('/route/another-slug/optional-slug?new=value'),
702702
], $response->original);
703703
}
704704

@@ -708,20 +708,66 @@ public function it_accepts_query_string_parameters_using_unnamed_routes()
708708
$this->withoutExceptionHandling();
709709
$this->setSupportedLocales(['en', 'nl']);
710710

711-
Route::get('route/{slug}', function () {
711+
Route::get('route/{slug}/{optional?}', function () {
712712
return [
713-
'current' => Route::localizedUrl(null, ['another-slug', 'new' => 'value']),
714-
'en' => Route::localizedUrl('en', ['another-slug', 'new' => 'value']),
715-
'nl' => Route::localizedUrl('nl', ['another-slug', 'new' => 'value']),
713+
'current' => Route::localizedUrl(null, ['another-slug', 'optional-slug', 'new' => 'value']),
714+
'en' => Route::localizedUrl('en', ['another-slug', 'optional-slug', 'new' => 'value']),
715+
'nl' => Route::localizedUrl('nl', ['another-slug', 'optional-slug', 'new' => 'value']),
716716
];
717717
});
718718

719719
$response = $this->call('GET', '/route/some-slug?param=value');
720720
$response->assertOk();
721721
$this->assertEquals([
722-
'current' => url('/route/another-slug?new=value'),
723-
'en' => url('/route/another-slug?new=value'),
724-
'nl' => url('/route/another-slug?new=value'),
722+
'current' => url('/route/another-slug/optional-slug?new=value'),
723+
'en' => url('/route/another-slug/optional-slug?new=value'),
724+
'nl' => url('/route/another-slug/optional-slug?new=value'),
725+
], $response->original);
726+
}
727+
728+
/** @test */
729+
public function it_allows_optional_parameters_with_named_routes()
730+
{
731+
$this->withoutExceptionHandling();
732+
$this->setSupportedLocales(['en', 'nl']);
733+
734+
Route::get('route/{slug}/{one?}/{two?}', function () {
735+
return [
736+
'current' => Route::localizedUrl(null, ['another-slug']),
737+
'en' => Route::localizedUrl('en', ['another-slug']),
738+
'nl' => Route::localizedUrl('nl', ['another-slug']),
739+
];
740+
})->name('route');
741+
742+
$response = $this->call('GET', '/route/some-slug');
743+
$response->assertOk();
744+
$this->assertEquals([
745+
'current' => url('/route/another-slug'),
746+
'en' => url('/route/another-slug'),
747+
'nl' => url('/route/another-slug'),
748+
], $response->original);
749+
}
750+
751+
/** @test */
752+
public function it_allows_optional_parameters_with_unnamed_routes()
753+
{
754+
$this->withoutExceptionHandling();
755+
$this->setSupportedLocales(['en', 'nl']);
756+
757+
Route::get('route/{slug}/{one?}/{two?}', function () {
758+
return [
759+
'current' => Route::localizedUrl(null, ['another-slug']),
760+
'en' => Route::localizedUrl('en', ['another-slug']),
761+
'nl' => Route::localizedUrl('nl', ['another-slug']),
762+
];
763+
});
764+
765+
$response = $this->call('GET', '/route/some-slug');
766+
$response->assertOk();
767+
$this->assertEquals([
768+
'current' => url('/route/another-slug'),
769+
'en' => url('/route/another-slug'),
770+
'nl' => url('/route/another-slug'),
725771
], $response->original);
726772
}
727773

0 commit comments

Comments
 (0)