Skip to content

Commit 4396600

Browse files
authored
Merge pull request #36 from Astrotomic/ft-auto-fallback
Add auto fallback feature
2 parents 720eaeb + 996a43b commit 4396600

File tree

5 files changed

+89
-1
lines changed

5 files changed

+89
-1
lines changed

src/Translatable/Locales.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public function load(): void
9595
foreach ($localesConfig as $key => $locale) {
9696
if (is_string($key) && is_array($locale)) {
9797
$this->locales[$key] = $key;
98+
9899
foreach ($locale as $country) {
99100
$countryLocale = $this->getCountryLocale($key, $country);
100101
$this->locales[$countryLocale] = $countryLocale;

src/Translatable/Translatable.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,12 @@ public function getTranslation(?string $locale = null, bool $withFallback = null
177177
if ($translation = $this->getTranslationByLocaleKey($locale)) {
178178
return $translation;
179179
}
180+
180181
if ($withFallback && $fallbackLocale) {
181182
if ($translation = $this->getTranslationByLocaleKey($fallbackLocale)) {
182183
return $translation;
183184
}
185+
184186
if (
185187
is_string($configFallbackLocale)
186188
&& $fallbackLocale !== $configFallbackLocale
@@ -190,6 +192,16 @@ public function getTranslation(?string $locale = null, bool $withFallback = null
190192
}
191193
}
192194

195+
if ($withFallback && $configFallbackLocale === null) {
196+
$configuredLocales = $this->getLocalesHelper()->all();
197+
198+
foreach ($configuredLocales as $configuredLocale) {
199+
if ($translation = $this->getTranslationByLocaleKey($configuredLocale)) {
200+
return $translation;
201+
}
202+
}
203+
}
204+
193205
return null;
194206
}
195207

src/config/translatable.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@
7878
| A fallback locale is the locale being used to return a translation
7979
| when the requested translation is not existing. To disable it
8080
| set it to false.
81+
| If set to null it will loop through all configured locales until
82+
| one existing is found or end of list reached. The locales are looped
83+
| from top to bottom and for country based locales the simple one
84+
| is used first. So "es" will be checked before "es_MX".
8185
|
8286
*/
8387
'fallback_locale' => 'en',

tests/TranslatableTest.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use Astrotomic\Translatable\Locales;
34
use Astrotomic\Translatable\Test\Model\Food;
45
use Astrotomic\Translatable\Test\Model\Person;
56
use Astrotomic\Translatable\Test\Model\Country;
@@ -851,4 +852,70 @@ public function test_can_fill_conflicting_attribute_locale()
851852
$this->assertEquals('id:my city', $city->getTranslation('id', false)->name);
852853
$this->assertEquals('en:my city', $city->getTranslation('en', false)->name);
853854
}
855+
856+
public function test_it_returns_first_existing_translation_as_fallback()
857+
{
858+
/** @var Locales $helper */
859+
$helper = $this->app->make(Locales::class);
860+
861+
$this->app->make('config')->set('translatable.locales', [
862+
'xyz',
863+
'en',
864+
'de' => [
865+
'DE',
866+
'AT',
867+
],
868+
'fr',
869+
'el',
870+
]);
871+
$this->app->make('config')->set('translatable.fallback_locale', null);
872+
$this->app->make('config')->set('translatable.use_fallback', true);
873+
$this->app->setLocale('xyz');
874+
$helper->load();
875+
876+
CountryTranslation::create([
877+
'country_id' => 1,
878+
'locale' => $helper->getCountryLocale('de', 'DE'),
879+
'name' => 'Griechenland',
880+
]);
881+
882+
/** @var Country $country */
883+
$country = Country::find(1);
884+
$this->assertNull($country->getTranslation(null, false));
885+
886+
// returns first existing locale
887+
$translation = $country->getTranslation();
888+
$this->assertInstanceOf(CountryTranslation::class, $translation);
889+
$this->assertEquals('en', $translation->locale);
890+
891+
// still returns simple locale for country based locale
892+
$translation = $country->getTranslation($helper->getCountryLocale('de', 'AT'));
893+
$this->assertInstanceOf(CountryTranslation::class, $translation);
894+
$this->assertEquals('de', $translation->locale);
895+
896+
$this->app->make('config')->set('translatable.locales', [
897+
'xyz',
898+
'de' => [
899+
'DE',
900+
'AT',
901+
],
902+
'en',
903+
'fr',
904+
'el',
905+
]);
906+
$helper->load();
907+
908+
// returns simple locale before country based locale
909+
$translation = $country->getTranslation();
910+
$this->assertInstanceOf(CountryTranslation::class, $translation);
911+
$this->assertEquals('de', $translation->locale);
912+
913+
$country->translations()->where('locale', 'de')->delete();
914+
$country->unsetRelation('translations');
915+
916+
// returns country based locale before next simple one
917+
$translation = $country->getTranslation();
918+
$this->assertInstanceOf(CountryTranslation::class, $translation);
919+
$this->assertEquals($helper->getCountryLocale('de', 'DE'), $translation->locale);
920+
}
854921
}

tests/models/CountryTranslation.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,9 @@ class CountryTranslation extends Eloquent
88
{
99
public $timestamps = false;
1010

11-
protected $fillable = ['name'];
11+
protected $fillable = [
12+
'country_id',
13+
'locale',
14+
'name',
15+
];
1216
}

0 commit comments

Comments
 (0)