diff --git a/src/Core/I18n/I18n.php b/src/Core/I18n/I18n.php index 65acc178bd..78742616d9 100644 --- a/src/Core/I18n/I18n.php +++ b/src/Core/I18n/I18n.php @@ -39,6 +39,7 @@ declare(strict_types = 1); namespace App\Core\I18n; use App\Util\Common; +use App\Util\Exception\BugFoundException; use App\Util\Exception\ServerException; use App\Util\Formatting; use InvalidArgumentException; @@ -302,7 +303,7 @@ abstract class I18n * * _m(string $msg) -- simple message * _m(string $ctx, string $msg) -- message with context - * _m(string|string[] $msg, array $params) -- message + * _m(string|string[] $msg, array $params) -- parameterized message * _m(string $ctx, string|string[] $msg, array $params) -- combination of the previous two * * @throws ServerException @@ -346,3 +347,42 @@ function _m(...$args): string // @codeCoverageIgnoreEnd } } + +/** + * Convert an array into a localized list + * + * This is needed because not add languages use the form of + * `item item item item` (probably) + * + * Note that this simply generates the ICU format, doesn't magically + * perform the translation if no translation is available + * + * @example en: ['foo', 'bar', 'quux'] => "foo, bar and quux" + * @example pt: ['foo', 'bar', 'quux'] => "foo, bar e quux" + * @example ch: ['foo', 'bar', 'quux'] => "foo, bar, quux" + */ +function _m_list(array $elements): string +{ + if (\count($elements) > 5) { + // Could be generated dinamically for english, but we can't handle all languages + throw new BugFoundException('Currently only lists of 5 elements supported, as ICU does not support this natively'); + } + + $icu = I18n::formatICU( + [ + 0 => '', + 1 => '%1$s', + 2 => '%1$s and %2$s', + 3 => '%1$s, %2$s and %3$s', + 4 => '%1$s, %2$s, %3$s and %4$s', + 5 => '%1$s, %2$s, %3$s, %4$s and %5$s', + 6 => 'NULL', + ], + // this uses a string count so the generated is a select, as it's not really a pluralization thing + ['count' => (string) \count($elements)], + ); + + $format = I18n::$translator->trans($icu, ['count' => \count($elements)], I18n::_mdomain(''), Common::currentLanguage()->getLocale()); + + return sprintf($format, ...$elements); +}