From 5fb0f5d700dc19f8798debc1b0210f82360fe5de Mon Sep 17 00:00:00 2001 From: Laurent Calvet Date: Tue, 16 Oct 2018 16:40:54 +0200 Subject: [PATCH] fix(translation): Modify the creation of the translations files --- bin/centreon-translations.php | 151 +++++++++++++ bootstrap.php | 26 +-- www/api/class/centreon_i18n.class.php | 293 +------------------------- 3 files changed, 171 insertions(+), 299 deletions(-) create mode 100644 bin/centreon-translations.php diff --git a/bin/centreon-translations.php b/bin/centreon-translations.php new file mode 100644 index 000000000000..3bb1aebd76f7 --- /dev/null +++ b/bin/centreon-translations.php @@ -0,0 +1,151 @@ +. + * + * Linking this program statically or dynamically with other modules is making a + * combined work based on this program. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this program give Centreon + * permission to link this program with independent modules to produce an executable, + * regardless of the license terms of these independent modules, and to copy and + * distribute the resulting executable under terms of Centreon choice, provided that + * Centreon also meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module which is not + * derived from this program. If you modify this program, you may extend this + * exception to your version of the program, but you are not obliged to do so. If you + * do not wish to do so, delete this exception statement from your version. + * + * For more information : contact@centreon.com + * + */ + +if (strlen($argv[1]) !== 2) { + exit( + sprintf("The length of the language code must be 2\n") + ); +} + +$languageCode = strtolower($argv[1]); + +if ($argc === 3 || $argc === 4) { + if (!file_exists($argv[2])) { + exit( + sprintf("Translation file '%s' does not exist\n", $argv[2]) + ); + } +} else { + $currentFileInfos = pathinfo(__FILE__); + $execFile = $currentFileInfos['filename'] . '.' . $currentFileInfos['extension']; + printf("usage: {$execFile} code_language translation_file.po translated_file.ser\n" + . " code_language code of the language (ex: fr, es, de, ...)\n" + . " translation_file.po file where the translation exists\n" + . " translated_file.ser Serialized file where the translation will be converted\n"); +} + +define('TOKEN_LENGTH', 6); + +if ($argc === 3) { + $translationFileInfos = pathinfo($argv[1]); + $destinationFile = $translationFileInfos['dirname'] . '/' + . $translationFileInfos['filename'] . '.json'; + createTranslationFile($languageCode, $argv[2], $destinationFile); +} + +if ($argc === 4) { + if (file_exists($argv[3])) { + if (false === unlink($argv[3])) { + exit("Destination file already exists, impossible to delete it\n"); + } + } + $destinationFileInfos = pathinfo($argv[3]); + $destinationDirectory = $destinationFileInfos['dirname']; + if (!is_dir($destinationDirectory)) { + if (false === mkdir($destinationDirectory, 0775, true)) { + exit( + sprintf("Impossible to create directory '%s'\n", $destinationDirectory) + ); + } + } + createTranslationFile($languageCode, $argv[2], $argv[3]); +} + +/** + * Create translation file for React + * + * @param string $languageCode Code of the language (ex: fr, es, de, ...) + * @param string $translationFile File where the translation exists + * @param string $destinationFile Serialized file where the translation will be converted + */ +function createTranslationFile( + string $languageCode, + string $translationFile, + string $destinationFile +): void { + + $translations = []; + $englishTranslation = []; + $isDefaultTranslation = $languageCode === 'en'; + + if ($fleHandler = fopen($translationFile, 'r')) { + while (false !== ($line = fgets($fleHandler))) { + $line = trim($line); + + // Retrieves the token + $token = trim( + substr($line, 0, TOKEN_LENGTH) + ); + // Retrieves text after the token + $text = trim( + substr( + $line, + TOKEN_LENGTH, + strlen($line) - TOKEN_LENGTH + ) + ); + // Removes double-quotes character that surround the text + $text = substr($text, 1, strlen($text) - 2); + + switch ($token) { + case 'msgid': // Token that contains the translation label + $label = $text; + break; + case 'msgstr': // Token that contains the translation + if (!empty($label)) { + $englishTranslation[$label] = $label; + if (!$isDefaultTranslation) { + // Only if the code of language is not 'en' + $translations[$label] = $text; + } + $label = null; + } + } + } + + fclose($fleHandler); + } + $final['en'] = $englishTranslation; + if (!$isDefaultTranslation) { + // Only if the code of language is not 'en' + $final[$languageCode] = $translations; + } + if (0 === file_put_contents($destinationFile, serialize($final))) { + exit( + sprintf("Impossible to create destination file '%s'\n", $destinationFile) + ); + } + chmod($destinationFile, 0664); +} diff --git a/bootstrap.php b/bootstrap.php index 460769a603ad..0e2a0239fa35 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -106,25 +106,19 @@ function loadDependencyInjector() // Defines the web service that will transform the translation files into one json file $dependencyInjector[CentreonI18n::class] = function ($container) { - if (!is_dir($container['path.files_generation'])) { - mkdir($container['path.files_generation']); + require_once _CENTREON_PATH_ . '/www/api/class/centreon_i18n.class.php'; + $lang = getenv('LANG'); + if ($lang === false) { + // Initialize the language translator + $container['translator']; + $lang = getenv('LANG'); } - $filesGenerationPath = $container['path.files_generation'] . 'translation'; - if (!is_dir($filesGenerationPath)) { - mkdir($filesGenerationPath); + if (strstr($lang, '.UTF-8') === false) { + $lang .= '.UTF-8'; } - require_once _CENTREON_PATH_ . '/www/api/class/centreon_i18n.class.php'; + $translationFile = _CENTREON_PATH_ . "www/locale/{$lang}/LC_MESSAGES/messages.ser"; $translation = new CentreonI18n(); - $translation->setFilesGenerationPath($filesGenerationPath); - $translation->setRootTranslationPath(_CENTREON_PATH_ . 'lang'); - $translation->setTranslationFile('LC_MESSAGES/messages.po'); - $jsonFilename = 'messages.json'; - if (isset($_SESSION['centreon'])) { - $userLanguage = substr($_SESSION['centreon']->user->get_lang(), 0, 2); - $translation->setUserLanguage($userLanguage); - $jsonFilename = "{$userLanguage}_{$jsonFilename}"; - } - $translation->setJsonFilename($jsonFilename); + $translation->setFilesGenerationPath($translationFile); return $translation; }; diff --git a/www/api/class/centreon_i18n.class.php b/www/api/class/centreon_i18n.class.php index 32d57152ba41..d6bc1e8c31bf 100644 --- a/www/api/class/centreon_i18n.class.php +++ b/www/api/class/centreon_i18n.class.php @@ -43,38 +43,8 @@ class CentreonI18n extends CentreonWebService * @var string Path where the translation file will be generate. */ private $filesGenerationPath; - - /** - * @var string Json file name that will be generated. - */ - private $jsonFilename; - - /** - * @var string Root translation path where the translation files need - * to be placed. - */ - private $rootTranslationPath; - - /** - * @var string Translation file that contains translation for one language - */ - private $translationFile; - - /** - * @var int Token length used to parse lines of translation files - */ - private $tokenLength = 6; - - /** - * @var string Language of the user - */ - private $userLanguage; - - /** - * @var string Label of the default translation language to generate - */ - private $defaultLanguage = 'en'; - + + /** * Return a table containing all the translations. * @@ -83,130 +53,14 @@ class CentreonI18n extends CentreonWebService */ public function getTranslation(): array { - if (empty($this->filesGenerationPath)) { - throw new \Exception('Json destination directory not defined'); - } - $langsArray = []; - if (is_dir($this->filesGenerationPath)) { - $jsonFile = "{$this->filesGenerationPath}/{$this->jsonFilename}"; - if (file_exists($jsonFile)) { - return unserialize(file_get_contents($jsonFile)); - } else { - $langs = $this->getAvailableLanguages(); - - /** - * If the language of user is defined, we only keep this one - */ - if (!empty($this->userLanguage)) { - $userLanguage[] = $this->userLanguage; - - /** - * We only process if the language of user is available in - * the translation files - */ - $languageToProcess = array_intersect($userLanguage, $langs); - if (!empty($languageToProcess)) { - $filename = $this->rootTranslationPath - . '/' . $languageToProcess[0] - . '/' . $this->translationFile; - $langsArray[$languageToProcess[0]] = - $this->transformTranslationFileIntoArray($filename); - } - } - - /** - * We use the first translation to create the default translation. - * The default translation is in English and the process - * consists in defining the values with the values of the - * respective keys. - */ - $defaultTranslationFilename = - $this->rootTranslationPath - . '/' . $langs[0] - . '/' . $this->translationFile; - $defaultTranslation = $this->transformTranslationFileIntoArray( - $defaultTranslationFilename, - true - ); - $langsArray[$this->defaultLanguage] = $defaultTranslation; - file_put_contents($jsonFile, serialize($langsArray)); - } - } else { - throw new \Exception('Files generation path doesn\'t exist'); - } - return $langsArray; - } - - /** - * Retrieve Transform a translation definition file into an array - * - * @param string $filename File name to process - * @param bool $isDefaultTranslation - * @return array - */ - private function transformTranslationFileIntoArray( - string $filename, - bool $isDefaultTranslation = false - ): array { - $isDefaultTranslationEmpty = empty($defaultTranslation); - $translations = []; - if ($fleHandler = fopen($filename, 'r')) { - while (false !== ($line = fgets($fleHandler))) { - $line = trim($line); - - // Retrieves the token - $token = $this->getToken($line); - // Retrieves text after the token - $text = $this->getTokenTranslation($line); - - switch ($token) { - case 'msgid': // Token that contains the translation label - $label = $text; - break; - case 'msgstr': // Token that contains the translation - if (!empty($label)) { - if ($isDefaultTranslation) { - $translations[$label] = $label; - } else { - $translations[$label] = $text; - } - $label = null; - } - } - } - fclose($fleHandler); - } - return $translations; - } - - /** - * Retrieve an array that contains a list of available language. - * The process will try to find if the translation file that is - * specified exist from the root translation path. - * Each translation file need to be placed in a subdirectory whose name will - * be used to segment all translations. In our case the subdirectory name - * will be named as 'us', 'fr' or any country initials. - * - * @throws \Exception - * @return array - */ - private function getAvailableLanguages(): array - { - $directories = []; - if ($dirHandler = opendir($this->rootTranslationPath)) { - while (($file = readdir($dirHandler)) !== false) { - $filePath = - $this->rootTranslationPath - . '/' . $file . '/' . $this->translationFile; - if (file_exists($filePath)) { - $directories[] = $file; - } - } - fclose($dirHandler); + if (file_exists($this->filesGenerationPath)) { + $data = unserialize( + file_get_contents($this->filesGenerationPath) + ); + return $data; } else { - throw new \Exception('Error opening the root translation path'); + throw new \Exception("Translation files does not exists"); } - return $directories; } /** @@ -223,136 +77,9 @@ public function getFilesGenerationPath(): ?string * Defined the path where the translation file will be generate. * * @param string $filesGenerationPath - * @param bool $createDirectory Indicates if the files generation path - * should be created if it does not exist (true by default). */ - public function setFilesGenerationPath( - string $filesGenerationPath, - bool $createDirectory = true - ): void { - if ($createDirectory && !is_dir($filesGenerationPath)) { - mkdir($filesGenerationPath); - } - if (mb_substr($filesGenerationPath, -1) === DIRECTORY_SEPARATOR) { - substr($filesGenerationPath, -1); - } - $this->filesGenerationPath = $filesGenerationPath; - } - - /** - * Retrieves the json file name that will be generated. - * - * @return string - */ - public function getJsonFilename(): ?string + public function setFilesGenerationPath(string $filesGenerationPath): void { - return $this->jsonFilename; - } - - /** - * Defines the json file name that will be generated. - * - * @param string $jsonFilename - */ - public function setJsonFilename(string $jsonFilename): void - { - $this->jsonFilename = $jsonFilename; - } - - /** - * Retrieves the root translation path where the translation files need - * to be placed. - * - * @return string - */ - public function getRootTranslationPath(): ?string - { - return $this->rootTranslationPath; - } - - /** - * Defines the root translation path where the translation files need - * to be placed. - * - * @param string $rootTranslationPath - */ - public function setRootTranslationPath(string $rootTranslationPath): void - { - if (mb_substr($rootTranslationPath, -1) === DIRECTORY_SEPARATOR) { - substr($rootTranslationPath, -1); - } - $this->rootTranslationPath = $rootTranslationPath; - } - - /** - * Retrieves the translation file name. - * - * @return string - */ - public function getTranslationFile(): ?string - { - return $this->translationFile; - } - - /** - * Defines the translation file name. - * - * @param string $translationFile - */ - public function setTranslationFile($translationFile): void - { - $this->translationFile = $translationFile; - } - - /** - * Retrieves the token of the line. - * - * @param string $line Line to analyse - * @return string Token found - */ - private function getToken($line): string - { - return trim( - substr($line, 0, $this->tokenLength) - ); - } - - /** - * Retrieves the translation for the line given - * - * @param string $line Line to analyse - * @return string Translation - */ - private function getTokenTranslation($line): string - { - $text = trim( - substr( - $line, - $this->tokenLength, - strlen($line) - $this->tokenLength - ) - ); - // Removes double-quotes character that surround the text - return substr($text, 1, strlen($text) - 2); - } - - /** - * Retrieve the language of the user - * - * @return string Language of the user - */ - public function getUserLanguage(): ?string - { - return $this->userLanguage; - } - - /** - * Define the language of the user - * - * @param string $userLanguage Language of the user - */ - public function setUserLanguage(string $userLanguage): void - { - $this->userLanguage = $userLanguage; + $this->filesGenerationPath = $filesGenerationPath; } }