Add Possibility for Custom Translations: config/[locale]/custom.po

This commit is contained in:
Johannes Rudolph 2022-07-15 19:14:18 +02:00 committed by Igor Scheller
parent d18185f49e
commit 64be48c646
6 changed files with 91 additions and 18 deletions

1
.gitignore vendored
View File

@ -26,6 +26,7 @@ _vimrc_local.vim
# Project files # Project files
/config/config.php /config/config.php
/config/lang/
/test/coverage /test/coverage
/public/coverage /public/coverage
/coverage /coverage

View File

@ -8,6 +8,7 @@ use Engelsystem\Http\Request;
use Gettext\Loader\MoLoader; use Gettext\Loader\MoLoader;
use Gettext\Loader\PoLoader; use Gettext\Loader\PoLoader;
use Gettext\Translations; use Gettext\Translations;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Session;
@ -74,18 +75,14 @@ class TranslationServiceProvider extends ServiceProvider
/** @var Translations $translations */ /** @var Translations $translations */
$translations = $this->app->call([Translations::class, 'create']); $translations = $this->app->call([Translations::class, 'create']);
$path = $this->app->get('path.lang');
foreach ($names as $name) { foreach ($names as $name) {
$file = $this->getFile($locale, $name); $file = $this->getFile($locale, $path, $name);
if (Str::endsWith($file, '.mo')) { $translations = $this->loadFile($file, $translations);
/** @var MoLoader $loader */
$loader = $this->app->make(MoLoader::class);
} else {
/** @var PoLoader $loader */
$loader = $this->app->make(PoLoader::class);
} }
$translations = $loader->loadFile($file, $translations); $file = $this->getFile($locale, $this->app->get('path.config') . '/lang', 'custom');
} $translations = $this->loadFile($file, $translations);
$translator = GettextTranslator::createFromTranslations($translations); $translator = GettextTranslator::createFromTranslations($translations);
$this->translators[$locale] = $translator; $this->translators[$locale] = $translator;
@ -94,9 +91,20 @@ class TranslationServiceProvider extends ServiceProvider
return $this->translators[$locale]; return $this->translators[$locale];
} }
protected function getFile(string $locale, string $name = 'default'): string protected function loadFile(string $file, Translations $translations): Translations
{ {
$filepath = $file = $this->app->get('path.lang') . '/' . $locale . '/' . $name; if (!file_exists($file)) {
return $translations;
}
$loader = $this->getFileLoader($file);
return $loader->loadFile($file, $translations);
}
protected function getFile(string $locale, string $basePath, string $name = 'default'): string
{
$filepath = $basePath . '/' . $locale . '/' . $name;
$file = $filepath . '.mo'; $file = $filepath . '.mo';
if (!file_exists($file)) { if (!file_exists($file)) {
@ -105,4 +113,18 @@ class TranslationServiceProvider extends ServiceProvider
return $file; return $file;
} }
/**
* @throws BindingResolutionException
*/
protected function getFileLoader(string $file): MoLoader|PoLoader
{
if (Str::endsWith($file, '.mo')) {
/** @var MoLoader $loader */
return $this->app->make(MoLoader::class);
} else {
/** @var PoLoader $loader */
return $this->app->make(PoLoader::class);
}
}
} }

View File

@ -1,3 +1,9 @@
# Testing content # Testing content
msgid "validation.foo.bar" msgid "validation.foo.bar"
msgstr "B Arr required!" msgstr "B Arr required!"
msgid "msg.additional"
msgstr "Additional"
msgid "msg.overwritten"
msgstr "From additional"

View File

@ -1,3 +1,9 @@
# Testing content # Testing content
msgid "foo.bar" msgid "foo.bar"
msgstr "B Arr!" msgstr "B Arr!"
msgid "msg.default"
msgstr "Default"
msgid "msg.overwritten"
msgstr "From default"

View File

@ -0,0 +1,8 @@
msgid "msg.default"
msgstr "Custom default"
msgid "msg.additional"
msgstr "Custom additional"
msgid "msg.overwritten"
msgstr "Custom overwritten"

View File

@ -2,13 +2,13 @@
namespace Engelsystem\Test\Unit\Helpers\Translation; namespace Engelsystem\Test\Unit\Helpers\Translation;
use Engelsystem\Application;
use Engelsystem\Config\Config; use Engelsystem\Config\Config;
use Engelsystem\Helpers\Translation\TranslationServiceProvider; use Engelsystem\Helpers\Translation\TranslationServiceProvider;
use Engelsystem\Helpers\Translation\Translator; use Engelsystem\Helpers\Translation\Translator;
use Engelsystem\Http\Request; use Engelsystem\Http\Request;
use Engelsystem\Test\Unit\ServiceProviderTest; use Engelsystem\Test\Unit\ServiceProviderTest;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Rule\InvokedCount;
use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Session;
class TranslationServiceProviderTest extends ServiceProviderTest class TranslationServiceProviderTest extends ServiceProviderTest
@ -79,13 +79,15 @@ class TranslationServiceProviderTest extends ServiceProviderTest
/** /**
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getFile
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getFileLoader
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::loadFile
*/ */
public function testGetTranslator(): void public function testGetTranslator(): void
{ {
$app = $this->getApp(['get']); $app = $this->getConfiguredApp();
$serviceProvider = new TranslationServiceProvider($app);
$this->setExpects($app, 'get', ['path.lang'], __DIR__ . '/Assets', new InvokedCount(2)); $serviceProvider = new TranslationServiceProvider($app);
// Get translator // Get translator
$translator = $serviceProvider->getTranslator('fo_OO'); $translator = $serviceProvider->getTranslator('fo_OO');
@ -99,11 +101,12 @@ class TranslationServiceProviderTest extends ServiceProviderTest
/** /**
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getFile * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getFile
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getFileLoader
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::loadFile
*/ */
public function testGetTranslatorFromPo(): void public function testGetTranslatorFromPo(): void
{ {
$app = $this->getApp(['get']); $app = $this->getConfiguredApp();
$this->setExpects($app, 'get', ['path.lang'], __DIR__ . '/Assets', new InvokedCount(2));
$serviceProvider = new TranslationServiceProvider($app); $serviceProvider = new TranslationServiceProvider($app);
@ -112,4 +115,31 @@ class TranslationServiceProviderTest extends ServiceProviderTest
$this->assertEquals('B Arr!', $translator->gettext('foo.bar')); $this->assertEquals('B Arr!', $translator->gettext('foo.bar'));
$this->assertEquals('B Arr required!', $translator->gettext('validation.foo.bar')); $this->assertEquals('B Arr required!', $translator->gettext('validation.foo.bar'));
} }
/**
* @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator
*/
public function testGetTranslatorCustom(): void
{
$app = $this->getConfiguredApp();
$serviceProvider = new TranslationServiceProvider($app);
// Get translation from the custom.po file
$translator = $serviceProvider->getTranslator('ba_RR');
$this->assertEquals('Custom default', $translator->gettext('msg.default'));
$this->assertEquals('Custom additional', $translator->gettext('msg.additional'));
$this->assertEquals('Custom overwritten', $translator->gettext('msg.overwritten'));
}
private function getConfiguredApp(): Application|MockObject
{
$app = $this->getApp(['get']);
$app->expects($this->exactly(2))
->method('get')
->withConsecutive(['path.lang'], ['path.config'])
->willReturn(__DIR__ . '/Assets', __DIR__ . '/Assets/config');
return $app;
}
} }