diff --git a/I18n.php b/I18n.php index f6d419f..29641dd 100644 --- a/I18n.php +++ b/I18n.php @@ -4,10 +4,8 @@ use Koded\Stdlib\Config; use Throwable; -use function error_log; use function ini_set; use function strtr; -use function substr_count; use function vsprintf; interface I18nFormatter @@ -65,16 +63,16 @@ public static function translate( string $locale = null): string { try { - return static::$catalogs[$locale]->translate('messages', $string, $arguments); + return self::$catalogs[$locale]->translate('messages', $string, $arguments); } catch (Throwable) { - static::registerCatalog($locale ??= static::locale()); - return static::$catalogs[$locale]->translate('messages', $string, $arguments); + self::registerCatalog($locale ??= self::locale()); + return self::$catalogs[$locale]->translate('messages', $string, $arguments); } } public static function locale(): string { - return static::$locale ??= static::normalizeLocale(\Locale::getDefault()); + return self::$locale ??= I18nCatalog::normalizeLocale(\Locale::getDefault()); } /** @@ -82,7 +80,7 @@ public static function locale(): string */ public static function catalogs(): array { - return static::$catalogs; + return self::$catalogs; } /** @@ -91,7 +89,7 @@ public static function catalogs(): array public static function info(): array { $catalogs = []; - foreach (static::$catalogs as $locale => $instance) { + foreach (self::$catalogs as $locale => $instance) { $catalogs[$locale] = [ 'class' => $instance::class, 'formatter' => $instance->formatter()::class, @@ -100,7 +98,7 @@ public static function info(): array ]; } return [ - 'locale' => static::$locale, + 'locale' => self::$locale, 'catalogs' => $catalogs, ]; } @@ -110,52 +108,43 @@ public static function register( bool $asDefault = false): void { $locale = $catalog->locale(); - if ($asDefault || empty(static::$catalogs)) { - static::setDefaultLocale($locale); - static::$directory = $catalog->directory(); - static::$formatter = $catalog->formatter()::class; - static::$catalog = $catalog::class; + if ($asDefault || empty(self::$catalogs)) { + self::setDefaultLocale($locale); + self::$directory = $catalog->directory(); + self::$formatter = $catalog->formatter()::class; + self::$catalog = $catalog::class; } - static::$catalogs[$locale] = $catalog; + self::$catalogs[$locale] = $catalog; } public static function flush(): void { - static::$catalogs = []; - static::$directory = null; - static::$formatter = null; - static::$catalog = null; - static::$locale = null; + self::$catalogs = []; + self::$directory = null; + self::$formatter = null; + self::$catalog = null; + self::$locale = null; ini_set('intl.default_locale', ''); \Locale::setDefault(''); } private static function registerCatalog(string $locale): void { - if (isset(static::$catalogs[$locale])) { + if (isset(self::$catalogs[$locale])) { return; } - static::$catalogs[$locale] = I18nCatalog::new((new Config) + self::$catalogs[$locale] = I18nCatalog::new((new Config) ->set('translation.locale', $locale) - ->set('translation.dir', static::$directory) - ->set('translation.formatter', static::$formatter) - ->set('translation.catalog', static::$catalog) + ->set('translation.dir', self::$directory) + ->set('translation.formatter', self::$formatter) + ->set('translation.catalog', self::$catalog) ); } private static function setDefaultLocale(string $locale): void { - static::$locale = $locale; + self::$locale = $locale; ini_set('intl.default_locale', $locale); \Locale::setDefault($locale); } - - private static function normalizeLocale(string $locale): string - { - if (substr_count($locale, '_') > 1) { - $locale = explode('_', $locale); - $locale = "$locale[0]_$locale[1]"; - } - return $locale; - } } diff --git a/I18nCatalog.php b/I18nCatalog.php index 28267cc..3a6abaf 100644 --- a/I18nCatalog.php +++ b/I18nCatalog.php @@ -31,13 +31,13 @@ public static function new(Configuration $conf): I18nCatalog $instance = new $catalog( new $formatter, $directory = $conf->get('translation.dir', getcwd() . '/locales'), - $locale = $conf->get('translation.locale', I18n::DEFAULT_LOCALE) + $locale = self::normalizeLocale($conf->get('translation.locale', I18n::DEFAULT_LOCALE)) ); if ($instance->supports($locale)) { return $instance; } if ($catalog !== ArrayCatalog::class) { - error_log(" > ($locale) gettext not supported, try ArrayCatalog ..."); + error_log(" > ($locale) gettext not supported, trying ArrayCatalog ..."); $conf->set('translation.catalog', ArrayCatalog::class); return static::new($conf); } @@ -45,6 +45,16 @@ public static function new(Configuration $conf): I18nCatalog return new NoCatalog(new $formatter, $directory, $locale); } + public static function normalizeLocale(string $locale): string + { + $locale = str_replace('.', '_', $locale); + if (substr_count($locale, '_') > 1) { + $locale = explode('_', $locale); + $locale = "$locale[0]_$locale[1]"; + } + return $locale; + } + public function translate( string $domain, string $key, @@ -114,6 +124,7 @@ protected function supports(string $locale): bool { return true; } + // @codeCoverageIgnoreEnd protected function initialize(string $locale): string|false @@ -141,7 +152,7 @@ protected function initialize(string $locale): string|false try { $this->data = require($catalog = "$this->directory/$locale.php"); if (false === array_key_exists('messages', $this->data)) { - error_log("i18n catalog $catalog is missing the messages array"); + error_log("ERROR : i18n catalog $catalog is missing the messages array"); return false; } return $locale; diff --git a/functions.php b/functions.php index 604da19..32a4945 100644 --- a/functions.php +++ b/functions.php @@ -4,7 +4,7 @@ function __( string $string, - array $arguments = [], + array $arguments = [], string $locale = null): string { return I18n::translate($string, $arguments, $locale); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8b5c9ce..0337dcf 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -6,21 +6,21 @@ verbose="true" colors="true" > - - - ./ - - - vendor - tests - - - - - ./tests - - - - - + + + ./ + + + vendor + tests + + + + + ./tests + + + + + \ No newline at end of file diff --git a/tests/Fixtures/xx_XX.php b/tests/Fixtures/xx_XX.php new file mode 100644 index 0000000..25058db --- /dev/null +++ b/tests/Fixtures/xx_XX.php @@ -0,0 +1,5 @@ +set('translation.locale', 'xx_XX') + ->set('translation.dir', __DIR__ . '/../Fixtures') + ->set('translation.catalog', ArrayCatalog::class) + )); + + $this->assertInstanceOf(NoCatalog::class, I18n::catalogs()['xx_XX'], + 'Expected ArrayCatalog, but it fallback to NoCatalog (invalid array)'); + } +} diff --git a/tests/Unit/NormalizeLocaleTest.php b/tests/Unit/NormalizeLocaleTest.php new file mode 100644 index 0000000..9de0749 --- /dev/null +++ b/tests/Unit/NormalizeLocaleTest.php @@ -0,0 +1,31 @@ +assertSame('mk_MK', I18n::catalogs()['mk_MK']->locale(), + 'The locale is normalized'); + } + + protected function setUp(): void + { + I18n::register(I18nCatalog::new((new Config) + ->set('translation.catalog', NoCatalog::class) + ->set('translation.locale', 'mk_MK_UTF8') + )); + } + + protected function tearDown(): void + { + I18n::flush(); + } +}