[I18N] Overhaul _m() implementation to support ICU message formats

This commit is contained in:
Hugo Sales 2020-06-07 16:50:11 +00:00 committed by Hugo Sales
parent a65a46f14e
commit 10ca51e72a
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
2 changed files with 62 additions and 20 deletions

View File

@ -88,28 +88,33 @@ function _m(string $msg /*, ...*/): string
$args = func_get_args(); $args = func_get_args();
switch (count($args)) { switch (count($args)) {
case 1: case 1:
// Empty parameters // Empty parameters, simple message
return I18nHelper::$translator->trans($msg, [], $domain); return I18nHelper::$translator->trans($msg, [], $domain);
case 2:
$context = $args[0];
$msg_single = $args[1];
// ASCII 4 is EOT, used to separate context from string
return I18nHelper::$translator->trans($context . '\004' . $msg_single, [], $domain);
case 3: case 3:
// '|' separates the singular from the plural version if (is_int($args[2])) {
$msg_single = $args[0]; throw new Exception('Calling `_m()` with an explicit number is deprecated, ' .
$msg_plural = $args[1]; 'use an explicit parameter');
$n = $args[2]; }
return I18nHelper::$translator->trans($msg_single . '|' . $msg_plural, ['%d' => $n], $domain); // Falthrough
case 4: // no break
// Combine both case 2:
$context = $args[0]; if (is_string($args[0]) && !is_array($args[1])) {
$msg_single = $args[1]; // ASCII 4 is EOT, used to separate context from string
$msg_plural = $args[2]; $context = array_shift($args) . '\004';
$n = $args[3]; }
return I18nHelper::$translator->trans($context . '\004' . $msg_single . '|' . $msg_plural,
['%d' => $n], $domain); if (is_array($args[0])) {
$args[0] = I18nHelper::formatICU($args[0], $args[1]);
}
if (is_string($args[0])) {
$msg = $args[0];
$params = $args[1] ?? [];
return I18nHelper::$translator->trans($context ?? '' . $msg, $params, $domain);
}
// Fallthrough
// no break
default: default:
throw new InvalidArgumentException('Bad parameter count to _m()'); throw new InvalidArgumentException('Bad parameters to `_m()`');
} }
} }

View File

@ -214,4 +214,41 @@ abstract class I18nHelper
'vi' => ['q' => 0.8, 'lang' => 'vi', 'name' => 'Vietnamese', 'direction' => 'ltr'], 'vi' => ['q' => 0.8, 'lang' => 'vi', 'name' => 'Vietnamese', 'direction' => 'ltr'],
]; ];
} }
public static function formatICU(array $messages, array $params): string
{
$msg = '';
foreach ($params as $var => $val) {
if (is_int($var)) {
$pref = '=';
$op = 'plural';
} elseif (is_string($var)) {
$pref = '';
$op = 'select,';
} else {
throw new Exception('Invalid key type. (int|string) only');
}
$res = "{{$var}, {$op} ";
$i = 1;
$cnt = count($messages);
foreach ($messages as $val => $m) {
if (is_array($m)) {
array_shift($params);
$res .= "{$pref}{$val} {" . self::formatICU($m, $params) . '} ';
} elseif (is_string($m)) {
if ($i !== $cnt) {
$res .= "{$pref}{$val} {{$m}} ";
} else {
$res .= "other {{$m}}}";
}
} else {
throw new Exception('Invalid message array');
}
++$i;
}
$msg .= $res;
}
return $msg;
}
} }