From 6cbe0a7fc9e9a083402fd892a13a71bda444cfbe Mon Sep 17 00:00:00 2001 From: Andrey Helldar Date: Sun, 7 Jul 2024 02:51:27 +0300 Subject: [PATCH] Added automatic forwarding of the localization parameter when calling group methods --- src/ServiceProvider.php | 29 +++++++++++++++ src/Services/UrlGenerator.php | 47 ++++++++++++++++++++++++ tests/Unit/Services/UrlGeneratorTest.php | 26 +++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 src/Services/UrlGenerator.php create mode 100644 tests/Unit/Services/UrlGeneratorTest.php diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 76feab7..9628318 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -5,14 +5,43 @@ namespace LaravelLang\Routes; use Closure; +use Illuminate\Foundation\Application; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use Illuminate\Support\ServiceProvider as BaseServiceProvider; use LaravelLang\Routes\Facades\LocalizationRoute; +use LaravelLang\Routes\Services\UrlGenerator; class ServiceProvider extends BaseServiceProvider { public function boot(): void + { + $this->registerGroup(); + $this->urlGenerator(); + } + + protected function registerGroup(): void { Route::macro('localizedGroup', fn (Closure $callback) => LocalizationRoute::group($callback)); } + + protected function urlGenerator(): void + { + $this->app->singleton('url', function ($app) { + $routes = $app['router']->getRoutes(); + + $app->instance('routes', $routes); + + return new UrlGenerator( + $routes, + $app->rebinding('request', $this->requestRebinder()), + $app['config']['app.asset_url'] + ); + }); + } + + protected function requestRebinder(): Closure + { + return fn (Application $app, Request $request) => $app['url']->setRequest($request); + } } diff --git a/src/Services/UrlGenerator.php b/src/Services/UrlGenerator.php new file mode 100644 index 0000000..bd0fd2c --- /dev/null +++ b/src/Services/UrlGenerator.php @@ -0,0 +1,47 @@ +isLocalizedGroupRoute($name) && ! is_null($route = $this->routes->getByName($name))) { + return $this->toRoute($route, $this->resolveLocalizedParameters($parameters), $absolute); + } + + return parent::route($name, $parameters, $absolute); + } + + protected function isLocalizedGroupRoute(string $name): bool + { + return Str::startsWith($name, $this->localizedRoutePrefix()); + } + + protected function resolveLocalizedParameters(array $parameters): array + { + return array_merge([ + $this->localizeRouteParameter() => app()->getLocale(), + ], $parameters); + } + + protected function localizedRoutePrefix(): string + { + return Config::shared()->routes->namePrefix; + } + + protected function localizeRouteParameter(): string + { + return Config::shared()->routes->names->parameter; + } +} diff --git a/tests/Unit/Services/UrlGeneratorTest.php b/tests/Unit/Services/UrlGeneratorTest.php new file mode 100644 index 0000000..22930ba --- /dev/null +++ b/tests/Unit/Services/UrlGeneratorTest.php @@ -0,0 +1,26 @@ +routes->namePrefix; + $locale = LocaleValue::LocaleMain; + $fallback = LocaleValue::LocaleAliasParent; + + expect(route($name . 'via.group.facade', ['foo' => 'bar'])) + ->toEndWith("localhost/$locale/group/facade/bar"); + + expect(route($name . 'via.group.macro', ['foo' => 'bar', 'locale' => $fallback])) + ->toEndWith("localhost/$fallback/group/macro/bar"); +}); + +test('non-localized route generation', function () { + expect(route('via.group.facade', ['foo' => 'bar'])) + ->toEndWith('localhost/group/facade/bar'); + + expect(route('via.group.macro', ['foo' => 'bar'])) + ->toEndWith('localhost/group/macro/bar'); +});