From e3563e5f66b30ffd09ff5507f5aaaacc69cc904b Mon Sep 17 00:00:00 2001 From: Andrey Helldar Date: Fri, 14 Jun 2024 10:52:30 +0300 Subject: [PATCH 1/2] Adding route groups with a locale prefix --- src/Facades/LocalizationRoute.php | 20 +++++++++++ src/Services/Route.php | 34 +++++++++++++++++++ tests/Concerns/Routes.php | 8 +++++ tests/Feature/Facades/RouteTest.php | 10 ++++++ .../Feature/{ => Middlewares}/CookieTest.php | 0 .../Feature/{ => Middlewares}/HeaderTest.php | 0 .../ParameterRedirectTest.php | 0 .../{ => Middlewares}/ParameterTest.php | 0 .../Feature/{ => Middlewares}/SessionTest.php | 0 .../Feature/{ => Middlewares}/WithoutTest.php | 0 10 files changed, 72 insertions(+) create mode 100644 src/Facades/LocalizationRoute.php create mode 100644 src/Services/Route.php create mode 100644 tests/Feature/Facades/RouteTest.php rename tests/Feature/{ => Middlewares}/CookieTest.php (100%) rename tests/Feature/{ => Middlewares}/HeaderTest.php (100%) rename tests/Feature/{ => Middlewares}/ParameterRedirectTest.php (100%) rename tests/Feature/{ => Middlewares}/ParameterTest.php (100%) rename tests/Feature/{ => Middlewares}/SessionTest.php (100%) rename tests/Feature/{ => Middlewares}/WithoutTest.php (100%) diff --git a/src/Facades/LocalizationRoute.php b/src/Facades/LocalizationRoute.php new file mode 100644 index 0000000..37b53d1 --- /dev/null +++ b/src/Facades/LocalizationRoute.php @@ -0,0 +1,20 @@ +names()->parameter)) + ->name($this->names()->parameter . '.') + ->middleware(LocalizationByParameter::class) + ->group($callback); + + BaseRoute::middleware([ + LocalizationByCookie::class, + LocalizationByHeader::class, + LocalizationBySession::class, + ])->group($callback); + } +} diff --git a/tests/Concerns/Routes.php b/tests/Concerns/Routes.php index a252640..665d625 100644 --- a/tests/Concerns/Routes.php +++ b/tests/Concerns/Routes.php @@ -5,6 +5,7 @@ namespace Tests\Concerns; use Closure; +use LaravelLang\Routes\Facades\LocalizationRoute; use LaravelLang\Routes\Middlewares\LocalizationByCookie; use LaravelLang\Routes\Middlewares\LocalizationByHeader; use LaravelLang\Routes\Middlewares\LocalizationByParameter; @@ -63,6 +64,13 @@ public function setUpRoutes(): void ->get('clean/{foo}', $this->jsonResponse()) ->name('clean'); }); + + LocalizationRoute::group(function () { + app('router') + ->middleware('web') + ->get('grouped', $this->jsonResponse()) + ->name('via.group'); + }); } protected function jsonResponse(): Closure diff --git a/tests/Feature/Facades/RouteTest.php b/tests/Feature/Facades/RouteTest.php new file mode 100644 index 0000000..c291cc6 --- /dev/null +++ b/tests/Feature/Facades/RouteTest.php @@ -0,0 +1,10 @@ +has('via.group'))->toBeTrue(); + expect(app('router')->has(Name::parameter() . '.via.group'))->toBeTrue(); +}); diff --git a/tests/Feature/CookieTest.php b/tests/Feature/Middlewares/CookieTest.php similarity index 100% rename from tests/Feature/CookieTest.php rename to tests/Feature/Middlewares/CookieTest.php diff --git a/tests/Feature/HeaderTest.php b/tests/Feature/Middlewares/HeaderTest.php similarity index 100% rename from tests/Feature/HeaderTest.php rename to tests/Feature/Middlewares/HeaderTest.php diff --git a/tests/Feature/ParameterRedirectTest.php b/tests/Feature/Middlewares/ParameterRedirectTest.php similarity index 100% rename from tests/Feature/ParameterRedirectTest.php rename to tests/Feature/Middlewares/ParameterRedirectTest.php diff --git a/tests/Feature/ParameterTest.php b/tests/Feature/Middlewares/ParameterTest.php similarity index 100% rename from tests/Feature/ParameterTest.php rename to tests/Feature/Middlewares/ParameterTest.php diff --git a/tests/Feature/SessionTest.php b/tests/Feature/Middlewares/SessionTest.php similarity index 100% rename from tests/Feature/SessionTest.php rename to tests/Feature/Middlewares/SessionTest.php diff --git a/tests/Feature/WithoutTest.php b/tests/Feature/Middlewares/WithoutTest.php similarity index 100% rename from tests/Feature/WithoutTest.php rename to tests/Feature/Middlewares/WithoutTest.php From 998625175b7a8433e6225d79544093d363a92043 Mon Sep 17 00:00:00 2001 From: Andrey Helldar Date: Mon, 17 Jun 2024 03:28:23 +0300 Subject: [PATCH 2/2] Added work with route groups --- composer.json | 3 +- .../{KeyNames.php => RouteParameters.php} | 2 +- src/Helpers/Route.php | 20 +++++++ .../LocalizationByParameterPrefix.php | 34 +++++++++++ .../LocalizationByParameterWithRedirect.php | 4 +- src/Middlewares/LocalizationBySession.php | 6 +- src/Middlewares/Middleware.php | 15 ++++- src/Services/Route.php | 23 ++++---- tests/Concerns/Routes.php | 2 +- tests/Feature/Facades/RouteTest.php | 15 ++++- .../Middlewares/ParameterPrefixTest.php | 58 +++++++++++++++++++ 11 files changed, 160 insertions(+), 22 deletions(-) rename src/Concerns/{KeyNames.php => RouteParameters.php} (91%) create mode 100644 src/Helpers/Route.php create mode 100644 src/Middlewares/LocalizationByParameterPrefix.php create mode 100644 tests/Feature/Middlewares/ParameterPrefixTest.php diff --git a/composer.json b/composer.json index 94a6a06..5e9ed45 100644 --- a/composer.json +++ b/composer.json @@ -31,8 +31,9 @@ "dragon-code/support": "^6.13", "illuminate/config": "^10.0 || ^11.0", "illuminate/http": "^10.0 || ^11.0", + "illuminate/routing": "^10.0 || ^11.0", "illuminate/support": "^10.0 || ^11.0", - "laravel-lang/config": "^1.4.2", + "laravel-lang/config": "^1.5", "laravel-lang/locales": "^2.8" }, "require-dev": { diff --git a/src/Concerns/KeyNames.php b/src/Concerns/RouteParameters.php similarity index 91% rename from src/Concerns/KeyNames.php rename to src/Concerns/RouteParameters.php index d3bd9df..fe6fffb 100644 --- a/src/Concerns/KeyNames.php +++ b/src/Concerns/RouteParameters.php @@ -7,7 +7,7 @@ use LaravelLang\Config\Data\Shared\RouteNameData; use LaravelLang\Routes\Helpers\Name; -trait KeyNames +trait RouteParameters { public function names(): RouteNameData { diff --git a/src/Helpers/Route.php b/src/Helpers/Route.php new file mode 100644 index 0000000..3afd1e2 --- /dev/null +++ b/src/Helpers/Route.php @@ -0,0 +1,20 @@ +routes->namePrefix; + } + + public static function redirect(): bool + { + return Config::shared()->routes->redirect; + } +} diff --git a/src/Middlewares/LocalizationByParameterPrefix.php b/src/Middlewares/LocalizationByParameterPrefix.php new file mode 100644 index 0000000..24514c9 --- /dev/null +++ b/src/Middlewares/LocalizationByParameterPrefix.php @@ -0,0 +1,34 @@ +route()?->parameters() ?? [], [ + $this->names()->parameter, + ]); + } + + protected function routeName(Request $request): ?string + { + if ($name = $request->route()?->getName()) { + return Str::after($name, $this->routePrefix()); + } + + return null; + } + + protected function routePrefix(): string + { + return Route::prefix(); + } +} diff --git a/src/Middlewares/LocalizationByParameterWithRedirect.php b/src/Middlewares/LocalizationByParameterWithRedirect.php index 8a647be..3dff9cf 100644 --- a/src/Middlewares/LocalizationByParameterWithRedirect.php +++ b/src/Middlewares/LocalizationByParameterWithRedirect.php @@ -8,7 +8,7 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use LaravelLang\Locales\Facades\Locales; -use LaravelLang\Routes\Concerns\KeyNames; +use LaravelLang\Routes\Concerns\RouteParameters; use function array_merge; use function in_array; @@ -16,7 +16,7 @@ class LocalizationByParameterWithRedirect extends Middleware { - use KeyNames; + use RouteParameters; public function __invoke(Request $request, Closure $next) { diff --git a/src/Middlewares/LocalizationBySession.php b/src/Middlewares/LocalizationBySession.php index 4dcd5ed..01b6659 100644 --- a/src/Middlewares/LocalizationBySession.php +++ b/src/Middlewares/LocalizationBySession.php @@ -10,6 +10,10 @@ class LocalizationBySession extends Middleware { protected function detect(Request $request): bool|float|int|string|null { - return $request->getSession()->get($this->names()->session); + if ($request->hasSession()) { + return $request->getSession()->get($this->names()->session); + } + + return null; } } diff --git a/src/Middlewares/Middleware.php b/src/Middlewares/Middleware.php index ff0b580..8f27488 100644 --- a/src/Middlewares/Middleware.php +++ b/src/Middlewares/Middleware.php @@ -8,7 +8,7 @@ use Illuminate\Http\Request; use LaravelLang\Locales\Data\LocaleData; use LaravelLang\Locales\Facades\Locales; -use LaravelLang\Routes\Concerns\KeyNames; +use LaravelLang\Routes\Concerns\RouteParameters; use LaravelLang\Routes\Events\LocaleHasBeenSetEvent; use function app; @@ -16,7 +16,7 @@ abstract class Middleware { - use KeyNames; + use RouteParameters; abstract protected function detect(Request $request): bool|float|int|string|null; @@ -27,7 +27,7 @@ public function __invoke(Request $request, Closure $next) $this->event($locale); } - return $next($request); + return $next($this->forgetParameter($request)); } protected function getLocale(Request $request): ?LocaleData @@ -53,4 +53,13 @@ protected function trim(bool|float|int|string|null $locale): string { return trim((string) $locale); } + + protected function forgetParameter(Request $request): Request + { + $request->route()->forgetParameter( + $this->names()->parameter + ); + + return $request; + } } diff --git a/src/Services/Route.php b/src/Services/Route.php index a835711..0eed673 100644 --- a/src/Services/Route.php +++ b/src/Services/Route.php @@ -6,29 +6,32 @@ use Closure; use Illuminate\Support\Facades\Route as BaseRoute; -use LaravelLang\Routes\Concerns\KeyNames; +use LaravelLang\Routes\Concerns\RouteParameters; +use LaravelLang\Routes\Helpers\Route as RouteName; use LaravelLang\Routes\Middlewares\LocalizationByCookie; use LaravelLang\Routes\Middlewares\LocalizationByHeader; -use LaravelLang\Routes\Middlewares\LocalizationByParameter; +use LaravelLang\Routes\Middlewares\LocalizationByParameterPrefix; use LaravelLang\Routes\Middlewares\LocalizationBySession; -use function sprintf; - class Route { - use KeyNames; + use RouteParameters; public function group(Closure $callback): void { - BaseRoute::prefix(sprintf('{%s}', $this->names()->parameter)) - ->name($this->names()->parameter . '.') - ->middleware(LocalizationByParameter::class) - ->group($callback); - BaseRoute::middleware([ LocalizationByCookie::class, LocalizationByHeader::class, LocalizationBySession::class, ])->group($callback); + + BaseRoute::prefix('{' . $this->names()->parameter . '}') + ->name(RouteName::prefix()) + ->middleware([ + LocalizationByParameterPrefix::class, + LocalizationByCookie::class, + LocalizationByHeader::class, + LocalizationBySession::class, + ])->group($callback); } } diff --git a/tests/Concerns/Routes.php b/tests/Concerns/Routes.php index 665d625..92ab183 100644 --- a/tests/Concerns/Routes.php +++ b/tests/Concerns/Routes.php @@ -68,7 +68,7 @@ public function setUpRoutes(): void LocalizationRoute::group(function () { app('router') ->middleware('web') - ->get('grouped', $this->jsonResponse()) + ->get('group/{foo}', $this->jsonResponse()) ->name('via.group'); }); } diff --git a/tests/Feature/Facades/RouteTest.php b/tests/Feature/Facades/RouteTest.php index c291cc6..c1c13f9 100644 --- a/tests/Feature/Facades/RouteTest.php +++ b/tests/Feature/Facades/RouteTest.php @@ -2,9 +2,18 @@ declare(strict_types=1); -use LaravelLang\Routes\Helpers\Name; +use LaravelLang\Routes\Helpers\Route as RouteName; +use Tests\Constants\LocaleValue; test('group', function () { - expect(app('router')->has('via.group'))->toBeTrue(); - expect(app('router')->has(Name::parameter() . '.via.group'))->toBeTrue(); + $foo = 'test'; + + expect(route('via.group', compact('foo'))) + ->toBeString() + ->toBe('http://localhost/group/test'); + + expect(route(RouteName::prefix() . 'via.group', [ + 'locale' => LocaleValue::LocaleMain, + 'foo' => $foo, + ]))->toBeString()->toBe('http://localhost/fr/group/test'); }); diff --git a/tests/Feature/Middlewares/ParameterPrefixTest.php b/tests/Feature/Middlewares/ParameterPrefixTest.php new file mode 100644 index 0000000..25000ec --- /dev/null +++ b/tests/Feature/Middlewares/ParameterPrefixTest.php @@ -0,0 +1,58 @@ +assertSuccessful() + ->assertJsonPath($foo, LocaleValue::TranslationFrench); +}); + +test('main locale', function (string $locale) { + $foo = 'test'; + + getJson(route(RouteName::prefix() . 'via.group', compact('foo', 'locale'))) + ->assertSuccessful() + ->assertJsonPath($foo, LocaleValue::TranslationFrench); + + assertEventDispatched(); +})->with('main-locales'); + +test('aliased locale', function (string $locale) { + $foo = 'test'; + + getJson(route(RouteName::prefix() . 'via.group', compact('foo', 'locale'))) + ->assertSuccessful() + ->assertJsonPath($foo, LocaleValue::TranslationGerman); + + assertEventDispatched(); +})->with('aliased-locales'); + +test('uninstalled locale', function (string $locale) { + $foo = 'test'; + + getJson(route(RouteName::prefix() . 'via.group', compact('foo', 'locale'))) + ->assertRedirectToRoute('via.group', [ + 'foo' => $foo, + ]); + + assertEventNotDispatched(); +})->with('uninstalled-locales'); + +test('unknown locale', function (int|string $locale) { + $foo = 'test'; + + getJson(route(RouteName::prefix() . 'via.group', compact('foo', 'locale'))) + ->assertRedirectToRoute('via.group', [ + 'foo' => $foo, + ]); + + assertEventNotDispatched(); +})->with('unknown-locales');