From c7f8c7c500ecac155a728ab0c6a6a887ef3bf1b8 Mon Sep 17 00:00:00 2001 From: Benjamin Renard Date: Fri, 17 Nov 2023 09:52:28 +0100 Subject: [PATCH] I18n: add init_locale CLI command --- src/I18n.php | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/src/I18n.php b/src/I18n.php index 72a5c17..86a388e 100644 --- a/src/I18n.php +++ b/src/I18n.php @@ -161,6 +161,14 @@ class I18n { "directories to MO files and as JS catalogs in locales directory." ) ); + + Cli :: add_command( + 'init_locale', + array('\\EesyPHP\\I18n', 'cli_init_locale'), + ___("Initialize a new locale for translation."), + "[locale]", + ___("This command could be used to initialize a new locale for translation.") + ); } } @@ -260,6 +268,32 @@ class I18n { return $return; } + /** + * Normalize a locale name + * @param string $name The locale name to normalize + * @param boolean $encoding_lower Set to true to put encoding in lowercase (optional, default: false) + * @return string|false The normalized locale of false in case of invalid provide values + */ + public static function normalize_locale_name($name, $encoding_lower=False) { + if ( + !preg_match( + "/^(?P[a-z]{2})_(?P[a-z]{2})((@(?P[a-z]+))|(\.(?P[a-z0-9\-]+)))?$/i", + $name, $m + ) + ) + return false; + $locale = strtolower($m['lang0'])."_".strtoupper($m['lang1']); + if ($m['at']) + $locale .= ".".strtolower($m['at']); + if ($m['encoding']) { + $m['encoding'] = strtoupper($m['encoding']); + if ($m['encoding'] == "UTF-8") $m['encoding'] = "UTF8"; + if ($encoding_lower) $m['encoding'] = strtolower($m['encoding']); + $locale .= ".".$m['encoding']; + } + return $locale; + } + /* ******************************************************************** * Translations CLI commands * @@ -318,6 +352,93 @@ class I18n { )); } + /** + * Command to initialize a new locale. + * + * @param array $command_args The command arguments + * @return void + */ + public static function cli_init_locale($command_args) { + $root_path = Cli::core_mode()?self::$core_root_path:self::$root_path; + if (!is_dir($root_path)) + Log :: fatal(self::_("Root locales directory does not exists ($root_path).")); + $domain = Cli::core_mode()?self::CORE_TEXT_DOMAIN:self::TEXT_DOMAIN; + if (count($command_args) != 1) + Cli::usage(self::_("You must provide the locale to initialize as unique and first argument.")); + $locale = self::normalize_locale_name($command_args[0], true); + if (!$locale) + Log :: fatal(self::_("Invalid locale %s.", $command_args[0])); + + // Validate locale + $result = run_external_command(["locale", "-a"]); + if (!is_array($result) || $result[0] != 0) + Log :: fatal(self::_("Fail to list valid locales.")); + if (!in_array($locale, explode("\n", $result[1]))) + Log :: fatal(self::_("Invalid locale %s.", $locale)); + + // Continue with locale with encoding as uppercase + $locale = self::normalize_locale_name($locale); + + // Check and create locale directory + $locale_dir = "$root_path/$locale"; + if (!is_dir($locale_dir)) { + if (mkdir($locale_dir)) + Log::info(I18n::_("Locale %s directory created (%s)."), $locale, $locale_dir); + else + Log::fatal(I18n::_("Fail to create locale %s directory (%s)."), $locale, $locale_dir); + } + else + Log::debug(I18n::_("Locale %s directory already exist (%s)."), $locale, $locale_dir); + + // Check and create locale LC_MESSAGES directory + $locale_lc_dir = "$locale_dir/LC_MESSAGES"; + if (!is_dir($locale_lc_dir)) { + if (mkdir($locale_lc_dir)) + Log::info( + I18n::_("Locale %s LC_MESSAGES directory created (%s)."), $locale, $locale_lc_dir + ); + else + Log::fatal( + I18n::_("Fail to create locale %s LC_MESSAGES directory (%s)."),$locale, $locale_lc_dir + ); + } + else + Log::debug(I18n::_("Locale %s LC_MESSAGES directory already exist (%s)."), $locale, $locale_dir); + + $po_file = "$locale_lc_dir/$domain.po"; + if (!is_file($po_file)) { + $fd = fopen($po_file, 'w'); + $lines = fwrite( + $fd, + implode( + "\n", + array( + 'msgid ""', + 'msgstr ""', + '"POT-Creation-Date: '.date('Y-m-d H:iO').'\n"', + '"PO-Revision-Date: '.date('Y-m-d H:iO').'\n"', + '"Language: '.substr($locale, 0, 2).'\n"', + '"MIME-Version: 1.0\n"', + '"Content-Type: text/plain; charset=utf-8\n"', + '"Content-Transfer-Encoding: 8bit\n"', + '"Plural-Forms: nplurals=2; plural=(n > 1);\n"', + ) + ) + ); + fclose($fd); + Log::info( + I18n::_("Locale %s PO file created (%s)."), $locale, $po_file + ); + } + else + Log::debug(I18n::_("Locale %s PO file already exist (%s)."), $locale, $po_file); + + // Extract messages + self :: cli_extract_messages([]); + self :: cli_update_messages([]); + self :: cli_compile_messages([]); + } + /** * Command to extract messages from PHP/JS & template files and * generate the lang/messages.pot file.