Fix: Correcting Language Line fallback resolver

This commit is contained in:
2026-08-27 01:28:37 +03:00
parent 594fa41527
commit 409db9c7bf
3 changed files with 61 additions and 0 deletions
+18
View File
@@ -178,6 +178,24 @@ namespaced groups so nothing collides. `__()` resolves the translation for whate
`App::getLocale()` currently is, which `LocaleMiddleware` already sets per-request (see `App::getLocale()` currently is, which `LocaleMiddleware` already sets per-request (see
"Behavior" above) — no extra wiring needed between the two systems. "Behavior" above) — no extra wiring needed between the two systems.
### Fallback locale follows the store's default language, not `config('app.fallback_locale')`
`spatie/laravel-translation-loader`'s stock `LanguageLine::getTranslation()` falls back to
`config('app.fallback_locale')` — a static `.env` value — when a key has no text for the current
locale. That's a second, disconnected "default language" concept: an admin changing the default
language via the Filament **Languages** resource has no effect on it, so an untranslated label
could silently fall back to the wrong language.
`Modules\Core\Localization\Models\LanguageLine` overrides `getTranslation()` to fall back to
`LanguageCache::defaultLocale()` instead — the same `languages.default` flag `LocaleMiddleware`
already treats as the single source of truth. It's swapped in via
`config('translation-loader.model')` (the package's own documented extension point for
"any model that extends `LanguageLine`"), set in `LocalizationServiceProvider::register()` so it
wins regardless of provider boot order (Laravel's `mergeConfigFrom()` only fills in config keys
not already set, so an explicit `register()`-time set always beats the package's own default).
No consuming app configuration needed — this is automatic once `LocalizationServiceProvider` is
registered.
### Seeding ### Seeding
A starter set of common e-shop labels (`nav.*`, `cart.*`, `product.*`, `auth.*`, `search.*`, A starter set of common e-shop labels (`nav.*`, `cart.*`, `product.*`, `auth.*`, `search.*`,
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace Modules\Core\Localization\Models;
use Modules\Core\Localization\Services\LanguageCache;
use Spatie\TranslationLoader\LanguageLine as BaseLanguageLine;
/**
* Overrides the base package's locale fallback (config('app.fallback_locale'), a
* static .env value) with the store's actual default language — Lunar's
* `languages.default` flag, the same source LocaleMiddleware/LanguageCache already
* treat as the single source of truth for "this store's default language".
*
* Without this, changing the default language via the Filament Languages resource
* has no effect on which locale an untranslated storefront label falls back to —
* two disconnected "default locale" concepts silently drifting apart. Swapped in
* via config('translation-loader.model') (see LocalizationServiceProvider), the
* package's own documented extension point for this.
*/
class LanguageLine extends BaseLanguageLine
{
public function getTranslation(string $locale): ?string
{
if (isset($this->text[$locale])) {
return $this->text[$locale];
}
$fallback = app(LanguageCache::class)->defaultLocale();
return $fallback !== null ? ($this->text[$fallback] ?? null) : null;
}
}
@@ -16,10 +16,21 @@ use Modules\Core\Localization\Listeners\FlushTranslationCache;
use Modules\Core\Localization\Listeners\LogTranslationActivity; use Modules\Core\Localization\Listeners\LogTranslationActivity;
use Modules\Core\Localization\Listeners\MigrateTranslationsForRenamedLanguage; use Modules\Core\Localization\Listeners\MigrateTranslationsForRenamedLanguage;
use Modules\Core\Localization\Middleware\LocaleMiddleware; use Modules\Core\Localization\Middleware\LocaleMiddleware;
use Modules\Core\Localization\Models\LanguageLine;
use Modules\Core\Localization\Observers\LanguageCacheObserver; use Modules\Core\Localization\Observers\LanguageCacheObserver;
class LocalizationServiceProvider extends ServiceProvider class LocalizationServiceProvider extends ServiceProvider
{ {
public function register(): void
{
// Must run before Spatie\TranslationLoader\TranslationServiceProvider's
// register() merges its own config defaults - mergeConfigFrom() only fills
// in keys not already set, so setting this here (regardless of provider
// boot order) makes it win over the package's default
// Spatie\TranslationLoader\LanguageLine::class.
config(['translation-loader.model' => LanguageLine::class]);
}
public function boot(): void public function boot(): void
{ {
$this->app['router']->aliasMiddleware('locale', LocaleMiddleware::class); $this->app['router']->aliasMiddleware('locale', LocaleMiddleware::class);