[I18N] Overhaul _m() implementation to support ICU message formats
This commit is contained in:
parent
a65a46f14e
commit
10ca51e72a
|
@ -88,28 +88,33 @@ function _m(string $msg /*, ...*/): string
|
|||
$args = func_get_args();
|
||||
switch (count($args)) {
|
||||
case 1:
|
||||
// Empty parameters
|
||||
// Empty parameters, simple message
|
||||
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:
|
||||
// '|' separates the singular from the plural version
|
||||
$msg_single = $args[0];
|
||||
$msg_plural = $args[1];
|
||||
$n = $args[2];
|
||||
return I18nHelper::$translator->trans($msg_single . '|' . $msg_plural, ['%d' => $n], $domain);
|
||||
case 4:
|
||||
// Combine both
|
||||
$context = $args[0];
|
||||
$msg_single = $args[1];
|
||||
$msg_plural = $args[2];
|
||||
$n = $args[3];
|
||||
return I18nHelper::$translator->trans($context . '\004' . $msg_single . '|' . $msg_plural,
|
||||
['%d' => $n], $domain);
|
||||
if (is_int($args[2])) {
|
||||
throw new Exception('Calling `_m()` with an explicit number is deprecated, ' .
|
||||
'use an explicit parameter');
|
||||
}
|
||||
// Falthrough
|
||||
// no break
|
||||
case 2:
|
||||
if (is_string($args[0]) && !is_array($args[1])) {
|
||||
// ASCII 4 is EOT, used to separate context from string
|
||||
$context = array_shift($args) . '\004';
|
||||
}
|
||||
|
||||
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:
|
||||
throw new InvalidArgumentException('Bad parameter count to _m()');
|
||||
throw new InvalidArgumentException('Bad parameters to `_m()`');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,4 +214,41 @@ abstract class I18nHelper
|
|||
'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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user