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
/config/config.php
/config/lang/
/test/coverage
/public/coverage
/coverage

View File

@ -8,6 +8,7 @@ use Engelsystem\Http\Request;
use Gettext\Loader\MoLoader;
use Gettext\Loader\PoLoader;
use Gettext\Translations;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Session\Session;
@ -74,19 +75,15 @@ class TranslationServiceProvider extends ServiceProvider
/** @var Translations $translations */
$translations = $this->app->call([Translations::class, 'create']);
$path = $this->app->get('path.lang');
foreach ($names as $name) {
$file = $this->getFile($locale, $name);
if (Str::endsWith($file, '.mo')) {
/** @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, $path, $name);
$translations = $this->loadFile($file, $translations);
}
$file = $this->getFile($locale, $this->app->get('path.config') . '/lang', 'custom');
$translations = $this->loadFile($file, $translations);
$translator = GettextTranslator::createFromTranslations($translations);
$this->translators[$locale] = $translator;
}
@ -94,9 +91,20 @@ class TranslationServiceProvider extends ServiceProvider
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';
if (!file_exists($file)) {
@ -105,4 +113,18 @@ class TranslationServiceProvider extends ServiceProvider
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
msgid "validation.foo.bar"
msgstr "B Arr required!"
msgid "msg.additional"
msgstr "Additional"
msgid "msg.overwritten"
msgstr "From additional"

View File

@ -1,3 +1,9 @@
# Testing content
msgid "foo.bar"
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;
use Engelsystem\Application;
use Engelsystem\Config\Config;
use Engelsystem\Helpers\Translation\TranslationServiceProvider;
use Engelsystem\Helpers\Translation\Translator;
use Engelsystem\Http\Request;
use Engelsystem\Test\Unit\ServiceProviderTest;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Rule\InvokedCount;
use Symfony\Component\HttpFoundation\Session\Session;
class TranslationServiceProviderTest extends ServiceProviderTest
@ -79,13 +79,15 @@ class TranslationServiceProviderTest extends ServiceProviderTest
/**
* @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
{
$app = $this->getApp(['get']);
$serviceProvider = new TranslationServiceProvider($app);
$app = $this->getConfiguredApp();
$this->setExpects($app, 'get', ['path.lang'], __DIR__ . '/Assets', new InvokedCount(2));
$serviceProvider = new TranslationServiceProvider($app);
// Get translator
$translator = $serviceProvider->getTranslator('fo_OO');
@ -99,11 +101,12 @@ class TranslationServiceProviderTest extends ServiceProviderTest
/**
* @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 testGetTranslatorFromPo(): void
{
$app = $this->getApp(['get']);
$this->setExpects($app, 'get', ['path.lang'], __DIR__ . '/Assets', new InvokedCount(2));
$app = $this->getConfiguredApp();
$serviceProvider = new TranslationServiceProvider($app);
@ -112,4 +115,31 @@ class TranslationServiceProviderTest extends ServiceProviderTest
$this->assertEquals('B Arr!', $translator->gettext('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;
}
}