Translation: added pluralization support
This commit is contained in:
parent
90e1a94962
commit
b443b53919
|
@ -23,10 +23,15 @@ function user_angeltypes_unconfirmed_hint()
|
||||||
. '</a>';
|
. '</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(ngettext('There is %d unconfirmed angeltype.', 'There are %d unconfirmed angeltypes.',
|
$count = count($unconfirmed_user_angeltypes);
|
||||||
count($unconfirmed_user_angeltypes)),
|
return _e(
|
||||||
count($unconfirmed_user_angeltypes)) . ' ' . __('Angel types which need approvals:') . ' ' . join(', ',
|
'There is %d unconfirmed angeltype.',
|
||||||
$unconfirmed_links);
|
'There are %d unconfirmed angeltypes.',
|
||||||
|
$count,
|
||||||
|
[$count]
|
||||||
|
)
|
||||||
|
. ' ' . __('Angel types which need approvals:')
|
||||||
|
. ' ' . join(', ', $unconfirmed_links);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -175,10 +175,8 @@ class ShiftCalendarShiftRenderer
|
||||||
$angeltype,
|
$angeltype,
|
||||||
$shift_entries
|
$shift_entries
|
||||||
);
|
);
|
||||||
$inner_text = sprintf(
|
$freeEntriesCount = $shift_signup_state->getFreeEntries();
|
||||||
ngettext('%d helper needed', '%d helpers needed', $shift_signup_state->getFreeEntries()),
|
$inner_text = _e('%d helper needed', '%d helpers needed', $freeEntriesCount, [$freeEntriesCount]);
|
||||||
$shift_signup_state->getFreeEntries()
|
|
||||||
);
|
|
||||||
|
|
||||||
switch ($shift_signup_state->getState()) {
|
switch ($shift_signup_state->getState()) {
|
||||||
case ShiftSignupState::ADMIN:
|
case ShiftSignupState::ADMIN:
|
||||||
|
|
|
@ -727,10 +727,7 @@ function User_view_state_admin($freeloader, $user_source)
|
||||||
if ($user_source['got_voucher'] > 0) {
|
if ($user_source['got_voucher'] > 0) {
|
||||||
$state[] = '<span class="text-success">'
|
$state[] = '<span class="text-success">'
|
||||||
. glyph('cutlery')
|
. glyph('cutlery')
|
||||||
. sprintf(
|
. _e('Got %s voucher', 'Got %s vouchers', $user_source['got_voucher'], [$user_source['got_voucher']])
|
||||||
ngettext('Got %s voucher', 'Got %s vouchers', $user_source['got_voucher']),
|
|
||||||
$user_source['got_voucher']
|
|
||||||
)
|
|
||||||
. '</span>';
|
. '</span>';
|
||||||
} else {
|
} else {
|
||||||
$state[] = '<span class="text-danger">' . __('Got no vouchers') . '</span>';
|
$state[] = '<span class="text-danger">' . __('Got no vouchers') . '</span>';
|
||||||
|
|
|
@ -39,11 +39,39 @@ class Translator
|
||||||
{
|
{
|
||||||
$translated = $this->translateGettext($key);
|
$translated = $this->translateGettext($key);
|
||||||
|
|
||||||
if (!empty($replace)) {
|
return $this->replaceText($translated, $replace);
|
||||||
$translated = call_user_func_array('sprintf', array_merge([$translated], $replace));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $translated;
|
/**
|
||||||
|
* Get the translation for a given key
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param string $pluralKey
|
||||||
|
* @param int $number
|
||||||
|
* @param array $replace
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function translatePlural(string $key, string $pluralKey, int $number, array $replace = []): string
|
||||||
|
{
|
||||||
|
$translated = $this->translateGettextPlural($key, $pluralKey, $number);
|
||||||
|
|
||||||
|
return $this->replaceText($translated, $replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace placeholders
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param array $replace
|
||||||
|
* @return mixed|string
|
||||||
|
*/
|
||||||
|
protected function replaceText(string $key, array $replace = [])
|
||||||
|
{
|
||||||
|
if (empty($replace)) {
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return call_user_func_array('sprintf', array_merge([$key], $replace));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,7 +83,21 @@ class Translator
|
||||||
*/
|
*/
|
||||||
protected function translateGettext(string $key): string
|
protected function translateGettext(string $key): string
|
||||||
{
|
{
|
||||||
return _($key);
|
return gettext($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the key via gettext
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param string $keyPlural
|
||||||
|
* @param int $number
|
||||||
|
* @return string
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*/
|
||||||
|
protected function translateGettextPlural(string $key, string $keyPlural, int $number): string
|
||||||
|
{
|
||||||
|
return ngettext($key, $keyPlural, $number);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -44,6 +44,7 @@ class Translation extends TwigExtension
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
new TwigFunction('__', [$this->translator, 'translate']),
|
new TwigFunction('__', [$this->translator, 'translate']),
|
||||||
|
new TwigFunction('_e', [$this->translator, 'translatePlural']),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,23 @@ function __($key, $replace = [])
|
||||||
return $translator->translate($key, $replace);
|
return $translator->translate($key, $replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the given message
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param string $keyPlural
|
||||||
|
* @param int $number
|
||||||
|
* @param array $replace
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function _e($key, $keyPlural, $number, $replace = [])
|
||||||
|
{
|
||||||
|
/** @var Translator $translator */
|
||||||
|
$translator = app('translator');
|
||||||
|
|
||||||
|
return $translator->translatePlural($key, $keyPlural, $number, $replace);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param array $parameters
|
* @param array $parameters
|
||||||
|
|
|
@ -10,12 +10,12 @@ use stdClass;
|
||||||
class TranslatorTest extends ServiceProviderTest
|
class TranslatorTest extends ServiceProviderTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @covers \Engelsystem\Helpers\Translator::__construct()
|
* @covers \Engelsystem\Helpers\Translator::__construct
|
||||||
* @covers \Engelsystem\Helpers\Translator::setLocale()
|
* @covers \Engelsystem\Helpers\Translator::setLocale
|
||||||
* @covers \Engelsystem\Helpers\Translator::setLocales()
|
* @covers \Engelsystem\Helpers\Translator::setLocales
|
||||||
* @covers \Engelsystem\Helpers\Translator::getLocale()
|
* @covers \Engelsystem\Helpers\Translator::getLocale
|
||||||
* @covers \Engelsystem\Helpers\Translator::getLocales()
|
* @covers \Engelsystem\Helpers\Translator::getLocales
|
||||||
* @covers \Engelsystem\Helpers\Translator::hasLocale()
|
* @covers \Engelsystem\Helpers\Translator::hasLocale
|
||||||
*/
|
*/
|
||||||
public function testInit()
|
public function testInit()
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,8 @@ class TranslatorTest extends ServiceProviderTest
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \Engelsystem\Helpers\Translator::translate()
|
* @covers \Engelsystem\Helpers\Translator::translate
|
||||||
|
* @covers \Engelsystem\Helpers\Translator::replaceText
|
||||||
*/
|
*/
|
||||||
public function testTranslate()
|
public function testTranslate()
|
||||||
{
|
{
|
||||||
|
@ -56,14 +57,36 @@ class TranslatorTest extends ServiceProviderTest
|
||||||
->setConstructorArgs(['de_DE.UTF-8', ['de_DE.UTF-8' => 'Deutsch']])
|
->setConstructorArgs(['de_DE.UTF-8', ['de_DE.UTF-8' => 'Deutsch']])
|
||||||
->setMethods(['translateGettext'])
|
->setMethods(['translateGettext'])
|
||||||
->getMock();
|
->getMock();
|
||||||
$translator->expects($this->once())
|
$translator->expects($this->exactly(2))
|
||||||
->method('translateGettext')
|
->method('translateGettext')
|
||||||
->with('My favourite number is %u!')
|
->withConsecutive(['Hello!'], ['My favourite number is %u!'])
|
||||||
->willReturn('Meine Lieblingszahl ist die %u!');
|
->willReturnOnConsecutiveCalls('Hallo!', 'Meine Lieblingszahl ist die %u!');
|
||||||
|
|
||||||
|
$return = $translator->translate('Hello!');
|
||||||
|
$this->assertEquals('Hallo!', $return);
|
||||||
|
|
||||||
$return = $translator->translate('My favourite number is %u!', [3]);
|
$return = $translator->translate('My favourite number is %u!', [3]);
|
||||||
$this->assertEquals('Meine Lieblingszahl ist die 3!', $return);
|
$this->assertEquals('Meine Lieblingszahl ist die 3!', $return);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Engelsystem\Helpers\Translator::translatePlural
|
||||||
|
*/
|
||||||
|
public function testTranslatePlural()
|
||||||
|
{
|
||||||
|
/** @var Translator|MockObject $translator */
|
||||||
|
$translator = $this->getMockBuilder(Translator::class)
|
||||||
|
->setConstructorArgs(['de_DE.UTF-8', ['de_DE.UTF-8' => 'Deutsch']])
|
||||||
|
->setMethods(['translateGettextPlural'])
|
||||||
|
->getMock();
|
||||||
|
$translator->expects($this->once())
|
||||||
|
->method('translateGettextPlural')
|
||||||
|
->with('%s apple', '%s apples', 2)
|
||||||
|
->willReturn('2 Äpfel');
|
||||||
|
|
||||||
|
$return = $translator->translatePlural('%s apple', '%s apples', 2, [2]);
|
||||||
|
$this->assertEquals('2 Äpfel', $return);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -218,6 +218,26 @@ class HelpersTest extends TestCase
|
||||||
$this->assertEquals('Lorem foo Ipsum', __('Lorem %s Ipsum', ['foo']));
|
$this->assertEquals('Lorem foo Ipsum', __('Lorem %s Ipsum', ['foo']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \_e
|
||||||
|
*/
|
||||||
|
public function testTranslatePlural()
|
||||||
|
{
|
||||||
|
/** @var Translator|MockObject $translator */
|
||||||
|
$translator = $this->getMockBuilder(Translator::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$this->getAppMock('translator', $translator);
|
||||||
|
|
||||||
|
$translator->expects($this->once())
|
||||||
|
->method('translatePlural')
|
||||||
|
->with('One: %u', 'Multiple: %u', 4, [4])
|
||||||
|
->willReturn('Multiple: 4');
|
||||||
|
|
||||||
|
$this->assertEquals('Multiple: 4', _e('One: %u', 'Multiple: %u', 4, [4]));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \url
|
* @covers \url
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -40,6 +40,7 @@ class TranslationTest extends ExtensionTest
|
||||||
$functions = $extension->getFunctions();
|
$functions = $extension->getFunctions();
|
||||||
|
|
||||||
$this->assertExtensionExists('__', [$translator, 'translate'], $functions);
|
$this->assertExtensionExists('__', [$translator, 'translate'], $functions);
|
||||||
|
$this->assertExtensionExists('_e', [$translator, 'translatePlural'], $functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue