Skip to content

Commit

Permalink
Merge pull request #36 from Astrotomic/ft-auto-fallback
Browse files Browse the repository at this point in the history
Add auto fallback feature
  • Loading branch information
Gummibeer authored Aug 7, 2019
2 parents 720eaeb + 996a43b commit 4396600
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/Translatable/Locales.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public function load(): void
foreach ($localesConfig as $key => $locale) {
if (is_string($key) && is_array($locale)) {
$this->locales[$key] = $key;

foreach ($locale as $country) {
$countryLocale = $this->getCountryLocale($key, $country);
$this->locales[$countryLocale] = $countryLocale;
Expand Down
12 changes: 12 additions & 0 deletions src/Translatable/Translatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,12 @@ public function getTranslation(?string $locale = null, bool $withFallback = null
if ($translation = $this->getTranslationByLocaleKey($locale)) {
return $translation;
}

if ($withFallback && $fallbackLocale) {
if ($translation = $this->getTranslationByLocaleKey($fallbackLocale)) {
return $translation;
}

if (
is_string($configFallbackLocale)
&& $fallbackLocale !== $configFallbackLocale
Expand All @@ -190,6 +192,16 @@ public function getTranslation(?string $locale = null, bool $withFallback = null
}
}

if ($withFallback && $configFallbackLocale === null) {
$configuredLocales = $this->getLocalesHelper()->all();

foreach ($configuredLocales as $configuredLocale) {
if ($translation = $this->getTranslationByLocaleKey($configuredLocale)) {
return $translation;
}
}
}

return null;
}

Expand Down
4 changes: 4 additions & 0 deletions src/config/translatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@
| A fallback locale is the locale being used to return a translation
| when the requested translation is not existing. To disable it
| set it to false.
| If set to null it will loop through all configured locales until
| one existing is found or end of list reached. The locales are looped
| from top to bottom and for country based locales the simple one
| is used first. So "es" will be checked before "es_MX".
|
*/
'fallback_locale' => 'en',
Expand Down
67 changes: 67 additions & 0 deletions tests/TranslatableTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use Astrotomic\Translatable\Locales;
use Astrotomic\Translatable\Test\Model\Food;
use Astrotomic\Translatable\Test\Model\Person;
use Astrotomic\Translatable\Test\Model\Country;
Expand Down Expand Up @@ -851,4 +852,70 @@ public function test_can_fill_conflicting_attribute_locale()
$this->assertEquals('id:my city', $city->getTranslation('id', false)->name);
$this->assertEquals('en:my city', $city->getTranslation('en', false)->name);
}

public function test_it_returns_first_existing_translation_as_fallback()
{
/** @var Locales $helper */
$helper = $this->app->make(Locales::class);

$this->app->make('config')->set('translatable.locales', [
'xyz',
'en',
'de' => [
'DE',
'AT',
],
'fr',
'el',
]);
$this->app->make('config')->set('translatable.fallback_locale', null);
$this->app->make('config')->set('translatable.use_fallback', true);
$this->app->setLocale('xyz');
$helper->load();

CountryTranslation::create([
'country_id' => 1,
'locale' => $helper->getCountryLocale('de', 'DE'),
'name' => 'Griechenland',
]);

/** @var Country $country */
$country = Country::find(1);
$this->assertNull($country->getTranslation(null, false));

// returns first existing locale
$translation = $country->getTranslation();
$this->assertInstanceOf(CountryTranslation::class, $translation);
$this->assertEquals('en', $translation->locale);

// still returns simple locale for country based locale
$translation = $country->getTranslation($helper->getCountryLocale('de', 'AT'));
$this->assertInstanceOf(CountryTranslation::class, $translation);
$this->assertEquals('de', $translation->locale);

$this->app->make('config')->set('translatable.locales', [
'xyz',
'de' => [
'DE',
'AT',
],
'en',
'fr',
'el',
]);
$helper->load();

// returns simple locale before country based locale
$translation = $country->getTranslation();
$this->assertInstanceOf(CountryTranslation::class, $translation);
$this->assertEquals('de', $translation->locale);

$country->translations()->where('locale', 'de')->delete();
$country->unsetRelation('translations');

// returns country based locale before next simple one
$translation = $country->getTranslation();
$this->assertInstanceOf(CountryTranslation::class, $translation);
$this->assertEquals($helper->getCountryLocale('de', 'DE'), $translation->locale);
}
}
6 changes: 5 additions & 1 deletion tests/models/CountryTranslation.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ class CountryTranslation extends Eloquent
{
public $timestamps = false;

protected $fillable = ['name'];
protected $fillable = [
'country_id',
'locale',
'name',
];
}

0 comments on commit 4396600

Please sign in to comment.