diff --git a/scripts/lang_functions.php b/scripts/lang_functions.php index a6698560c..1de87482c 100644 --- a/scripts/lang_functions.php +++ b/scripts/lang_functions.php @@ -18,7 +18,7 @@ * Helper functions converting moodle strings to json. */ -function detect_languages($languages, $keys) { +function detect_languages($languages) { echo "\n\n\n"; $all_languages = glob(LANGPACKSFOLDER.'/*' , GLOB_ONLYDIR); @@ -32,10 +32,9 @@ function detect_languages($languages, $keys) { $all_languages = array_filter($all_languages, 'get_lang_not_wp'); $detect_lang = array_diff($all_languages, $languages); - $new_langs = array(); + $new_langs = []; foreach ($detect_lang as $lang) { - reset_translations_strings(); - $new = detect_lang($lang, $keys); + $new = detect_lang($lang); if ($new) { $new_langs[$lang] = $lang; } @@ -44,12 +43,10 @@ function detect_languages($languages, $keys) { return $new_langs; } -function build_languages($languages, $keys, $added_langs = []) { +function build_languages($languages, $added_langs = []) { // Process the languages. foreach ($languages as $lang) { - reset_translations_strings(); - $ok = build_lang($lang, $keys); - if ($ok) { + if (build_lang($lang)) { $added_langs[$lang] = $lang; } } @@ -57,53 +54,70 @@ function build_languages($languages, $keys, $added_langs = []) { return $added_langs; } -function get_langindex_keys() { - $local = 0; - // Process the index file, just once. - $keys = file_get_contents('langindex.json'); - $keys = (array) json_decode($keys); +/** + * Loads lang index keys. + */ +function load_langindex() { + global $STATS; + global $LANGINDEX; - foreach ($keys as $key => $value) { - $map = new StdClass(); - if ($value == 'local_moodlemobileapp') { - $map->file = $value; - $map->string = $key; + $local = 0; + $total = 0; + // Process the index file, just once. + $langindexjson = load_json('langindex.json'); + + $LANGINDEX = []; + foreach ($langindexjson as $appkey => $value) { + if ($value == APPMODULENAME) { + $file = $value; + $lmskey = $appkey; $local++; } else { $exp = explode('/', $value, 2); - $map->file = $exp[0]; + $file = $exp[0]; if (count($exp) == 2) { - $map->string = $exp[1]; + $lmskey = $exp[1]; } else { - $exp = explode('.', $key, 3); + $exp = explode('.', $appkey, 3); if (count($exp) == 3) { - $map->string = $exp[2]; + $lmskey = $exp[2]; } else { - $map->string = $exp[1]; + $lmskey = $exp[1]; } } } - $keys[$key] = $map; + if (!isset($LANGINDEX[$file])) { + $LANGINDEX[$file] = []; + } + + $LANGINDEX[$file][$appkey] = $lmskey; + $total++; } - $total = count($keys); - echo "Total strings to translate $total ($local local)\n"; + $STATS = new StdClass(); + $STATS->local = $local; + $STATS->total = $total; - return $keys; + echo "Total strings to translate $total ($local local)\n"; } +/** + * Add lang names to config file. + * + * @param $langs Array of language codes to add. + * @param $config Loaded config file. + */ function add_langs_to_config($langs, $config) { $changed = false; $config_langs = get_object_vars($config['languages']); foreach ($langs as $lang) { if (!isset($config_langs[$lang])) { - $langfoldername = str_replace('-', '_', $lang); + $langfoldername = get_langfolder($lang); - $string = []; - include(LANGPACKSFOLDER.'/'.$langfoldername.'/langconfig.php'); - $config['languages']->$lang = $string['thislanguage']; + $lmsstring = get_translation_strings($langfoldername, 'langconfig'); + $config['languages']->$lang = $lmsstring['thislanguage']; $changed = true; } } @@ -119,11 +133,31 @@ function add_langs_to_config($langs, $config) { /** * Save json data. + * + * @param $path Path of the file to load. + * @param $content Content string to save. */ function save_json($path, $content) { file_put_contents($path, str_replace('\/', '/', json_encode($content, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT))."\n"); } +/** + * Load json data. + * + * @param $path Path of the file to load. + * @return Associative array obtained from json. + */ +function load_json($path) { + $file = file_get_contents($path); + return (array) json_decode($file); +} + +/** + * Get's lang folder from lang code. + * + * @param $lang Lang code. + * @return Folder path. + */ function get_langfolder($lang) { $folder = LANGPACKSFOLDER.'/'.str_replace('-', '_', $lang); if (!is_dir($folder) || !is_file($folder.'/langconfig.php')) { @@ -133,49 +167,56 @@ function get_langfolder($lang) { return $folder; } +/** + * Import translation file from langpack and returns it. + * + * @param $langfoldername Lang folder path. + * @param $file File name (excluding extension). + * @param $override_folder If needed, the folder of the file to override strings. + * @return String array. + */ function get_translation_strings($langfoldername, $file, $override_folder = false) { - global $strings; - - if (isset($strings[$file])) { - return $strings[$file]; + $lmsstring = import_translation_strings($langfoldername, $file); + if ($override_folder) { + $override = import_translation_strings($override_folder, $file); + $lmsstring = array_merge($lmsstring, $override); } - $string = import_translation_strings($langfoldername, $file); - $string_override = $override_folder ? import_translation_strings($override_folder, $file) : false; - - if ($string) { - $strings[$file] = $string; - if ($string_override) { - $strings[$file] = array_merge($strings[$file], $string_override); - } - } else if ($string_override) { - $strings[$file] = $string_override; - } else { - $strings[$file] = false; - } - - return $strings[$file]; + return $lmsstring; } +/** + * Import translation file from langpack and returns it. + * + * @param $langfoldername Lang folder path. + * @param $file File name (excluding extension). + * @return String array. + */ function import_translation_strings($langfoldername, $file) { + $path = $langfoldername.'/'.$file.'.php'; // Apply translations. if (!file_exists($path)) { - return false; + return []; } $string = []; + include($path); return $string; } -function reset_translations_strings() { - global $strings; - $strings = []; -} +/** + * Build translations files from langpack. + * + * @param lang Language code. + * @return Wether it succeeded. + */ +function build_lang($lang) { + global $STATS; + global $LANGINDEX; -function build_lang($lang, $keys) { $langfoldername = get_langfolder($lang); if (!$langfoldername) { echo "Cannot translate $lang, folder not found"; @@ -189,7 +230,7 @@ function build_lang($lang, $keys) { $override_langfolder = false; } - $total = count($keys); + $total = $STATS->total; $local = 0; $langparts = explode('-', $lang, 2); @@ -204,71 +245,71 @@ function build_lang($lang, $keys) { } $langFile = false; - // Not yet translated. Do not override. if (file_exists(ASSETSPATH.$lang.'.json')) { // Load lang files just once. - $langFile = file_get_contents(ASSETSPATH.$lang.'.json'); - $langFile = (array) json_decode($langFile); + $langFile = load_json(ASSETSPATH.$lang.'.json'); } $translations = []; // Add the translation to the array. - foreach ($keys as $key => $value) { - $string = get_translation_strings($langfoldername, $value->file, $override_langfolder); - // Apply translations. - if (!$string) { - if ($value->file == 'donottranslate') { - // Restore it form the json. - if ($langFile && is_array($langFile) && isset($langFile[$key])) { - $translations[$key] = $langFile[$key]; - } else { - // If not present, do not count it in the total. - $total--; + foreach ($LANGINDEX as $file => $keys) { + $lmsstring = get_translation_strings($langfoldername, $file, $override_langfolder); + foreach ($keys as $appkey => $lmskey) { + // Apply translations. + if (empty($lmsstring)) { + if ($file == 'donottranslate') { + // Restore it form the json. + if ($langFile && is_array($langFile) && isset($langFile[$appkey])) { + $translations[$appkey] = $langFile[$appkey]; + } else { + // If not present, do not count it in the total. + $total--; + } + + continue; } + if (TOTRANSLATE) { + echo "\n\t\tTo translate $lmskey on $file"; + } continue; } - if (TOTRANSLATE) { - echo "\n\t\tTo translate $value->string on $value->file"; - } - continue; - } + if (!isset($lmsstring[$lmskey]) || ($lang == 'en' && $file == APPMODULENAME)) { + // Not yet translated. Do not override. + if ($langFile && is_array($langFile) && isset($langFile[$appkey])) { + $translations[$appkey] = $langFile[$appkey]; - if (!isset($string[$value->string]) || ($lang == 'en' && $value->file == 'local_moodlemobileapp')) { - // Not yet translated. Do not override. - if ($langFile && is_array($langFile) && isset($langFile[$key])) { - $translations[$key] = $langFile[$key]; - - if ($value->file == 'local_moodlemobileapp') { - $local++; + if ($file == APPMODULENAME) { + $local++; + } } + if (TOTRANSLATE && !isset($lmsstring[$lmskey])) { + echo "\n\t\tTo translate $lmskey on $file"; + } + continue; } - if (TOTRANSLATE && !isset($string[$value->string])) { - echo "\n\t\tTo translate $value->string on $value->file"; - } - continue; - } else { - $text = $string[$value->string]; - } - if ($value->file != 'local_moodlemobileapp') { - $text = str_replace('$a->@', '$a.', $text); - $text = str_replace('$a->', '$a.', $text); - $text = str_replace('{$a', '{{$a', $text); - $text = str_replace('}', '}}', $text); - $text = preg_replace('/@@.+?@@(
)?\\s*/', '', $text); - // Prevent double. - $text = str_replace(array('{{{', '}}}'), array('{{', '}}'), $text); - } else { - // @TODO: Remove that line when core.cannotconnect and core.login.invalidmoodleversion are completelly changed to use $a - if (($key == 'core.cannotconnect' || $key == 'core.login.invalidmoodleversion') && strpos($text, '2.4') != false) { - $text = str_replace('2.4', '{{$a}}', $text); - } - $local++; - } + $text = $lmsstring[$lmskey]; - $translations[$key] = html_entity_decode($text); + if ($file != APPMODULENAME) { + $text = str_replace('$a->@', '$a.', $text); + $text = str_replace('$a->', '$a.', $text); + $text = str_replace('{$a', '{{$a', $text); + $text = str_replace('}', '}}', $text); + $text = preg_replace('/@@.+?@@(
)?\\s*/', '', $text); + // Prevent double. + $text = str_replace(['{{{', '}}}'], ['{{', '}}'], $text); + } else { + // @TODO: Remove that line when core.cannotconnect and core.login.invalidmoodleversion are completelly changed to use $a + if (($appkey == 'core.cannotconnect' || $appkey == 'core.login.invalidmoodleversion') && strpos($text, '2.4') != false) { + $text = str_replace('2.4', '{{$a}}', $text); + } + $local++; + } + + $translations[$appkey] = html_entity_decode($text); + } } if (!empty($parent)) { @@ -290,19 +331,35 @@ function build_lang($lang, $keys) { echo "\t\t$success of $total -> $percentage% $bar ($local local)\n"; if ($lang == 'en') { - generate_local_moodlemobileapp($keys, $translations); - override_component_lang_files($keys, $translations); + generate_local_module_file($LANGINDEX[APPMODULENAME], $translations); + override_component_lang_files($translations); } return true; } -function progressbar($percentage) { - $done = floor($percentage/10); - return "\t".str_repeat('=', $done) . str_repeat('-', 10-$done); +/** + * Generates an ASCII progress bar. + * + * @param $percentage Done part. + * @param $length Length of the text. + * @return Text generated. + */ +function progressbar($percentage, $length = 10) { + $done = floor($percentage / $length); + return "\t".str_repeat('=', $done) . str_repeat('-', $length - $done); } -function detect_lang($lang, $keys) { +/** + * Check translations on langpack and detects if the language should be added. + * + * @param lang Language code. + * @return If the file should be added to the app. + */ +function detect_lang($lang) { + global $STATS; + global $LANGINDEX; + $langfoldername = get_langfolder($lang); if (!$langfoldername) { echo "Cannot translate $lang, folder not found"; @@ -310,13 +367,13 @@ function detect_lang($lang, $keys) { return false; } - $total = count ($keys); + $total = $STATS->total; $success = 0; $local = 0; - $string = get_translation_strings($langfoldername, 'langconfig'); - $parent = isset($string['parentlanguage']) ? $string['parentlanguage'] : ""; - if (!isset($string['thislanguage'])) { + $lmsstring = get_translation_strings($langfoldername, 'langconfig'); + $parent = isset($lmsstring['parentlanguage']) ? $lmsstring['parentlanguage'] : ""; + if (!isset($lmsstring['thislanguage'])) { echo "Cannot translate $lang, translated name not found"; return false; } @@ -325,51 +382,66 @@ function detect_lang($lang, $keys) { if ($parent != "" && $parent != $lang) { $title .= " ($parent)"; } - $langname = $string['thislanguage']; + $langname = $lmsstring['thislanguage']; $title .= " ".$langname." -D"; - // Add the translation to the array. - foreach ($keys as $key => $value) { - $string = get_translation_strings($langfoldername, $value->file); - // Apply translations. - if (!$string) { - // Do not count non translatable in the totals. - if ($value->file == 'donottranslate') { - $total--; + $lmsstring = get_translation_strings($langfoldername, APPMODULENAME); + if (!empty($lmsstring)) { + // Add the translation to the array. + foreach ($LANGINDEX as $file => $keys) { + $lmsstring = get_translation_strings($langfoldername, $file); + + // Apply translations. + if (empty($lmsstring)) { + // Do not count non translatable in the totals. + if ($file == 'donottranslate') { + $total -= count($keys); + } + continue; } - continue; - } - if (!isset($string[$value->string])) { - continue; - } else { - $text = $string[$value->string]; - } + foreach ($keys as $lmskey) { + if (!isset($lmsstring[$lmskey])) { + continue; + } - if ($value->file == 'local_moodlemobileapp') { - $local++; - } + if ($file == APPMODULENAME) { + $local++; + } - $success++; + $success++; + } + } } - $percentage = floor($success/$total * 100); - $bar = progressbar($percentage); - echo "Checking ".$title.str_repeat("\t", 7 - floor(mb_strlen($title, 'UTF-8')/8)); - echo "\t$success of $total -> $percentage% $bar ($local local)"; - if (($percentage > 75 && $local > 50) || ($percentage > 50 && $local > 75)) { - echo " \t DETECTED\n"; - return true; + + if ($local == 0) { + echo "\tNo Mobile App strings found\n"; + } else { + $percentage = floor($success/$total * 100); + $bar = progressbar($percentage); + + echo "\t$success of $total -> $percentage% $bar ($local local)"; + if (($percentage > 75 && $local > 50) || ($percentage > 50 && $local > 75)) { + echo " \t DETECTED\n"; + return true; + } + echo "\n"; } - echo "\n"; return false; } +/** + * Save a key - value pair into a json file. + * + * @param key Key of the json object. + * @param value Value of the json object. + * @param filePath Path of the json file. + */ function save_key($key, $value, $filePath) { - $file = file_get_contents($filePath); - $file = (array) json_decode($file); + $file = load_json($filePath); $value = html_entity_decode($value); if (!isset($file[$key]) || $file[$key] != $value) { $file[$key] = $value; @@ -378,7 +450,12 @@ function save_key($key, $value, $filePath) { } } -function override_component_lang_files($keys, $translations) { +/** + * Take newer ENGLISH translations from the langpacks and applies it to the app lang.json files. + * + * @param [array] $translations English translations. + */ +function override_component_lang_files($translations) { echo "Override component lang files.\n"; foreach ($translations as $key => $value) { $path = '../src/'; @@ -424,14 +501,14 @@ function override_component_lang_files($keys, $translations) { } /** - * Generates local moodle mobile app file to update languages in AMOS. + * Generates local module file to update languages in AMOS. * - * @param [array] $keys Translation keys. - * @param [array] $translations English translations. + * @param [array] $appindex Translation appindex. + * @param [array] $translations English translations. */ -function generate_local_moodlemobileapp($keys, $translations) { +function generate_local_module_file($appindex, $translations) { echo "Generate local_moodlemobileapp.\n"; - $string = ' $value) { - if (isset($translations[$key]) && $value->file == 'local_moodlemobileapp') { - $string .= '$string[\''.$key.'\'] = \''.str_replace("'", "\'", $translations[$key]).'\';'."\n"; + foreach ($appindex as $appkey => $lmskey) { + if (isset($translations[$appkey])) { + $lmsstring .= '$string[\''.$appkey.'\'] = \''.str_replace("'", "\'", $translations[$appkey]).'\';'."\n"; } } - $string .= '$string[\'pluginname\'] = \'Moodle Mobile language strings\';'."\n"; + $lmsstring .= '$string[\'pluginname\'] = \'Moodle Mobile language strings\';'."\n"; - file_put_contents('../../moodle-local_moodlemobileapp/lang/en/local_moodlemobileapp.php', $string."\n"); + $filepath = '../../moodle-'.APPMODULENAME.'/lang/en/'.APPMODULENAME.'.php'; + + file_put_contents($filepath, $lmsstring."\n"); } diff --git a/scripts/moodle_to_json.php b/scripts/moodle_to_json.php index 4a9831796..166ba1c87 100644 --- a/scripts/moodle_to_json.php +++ b/scripts/moodle_to_json.php @@ -24,6 +24,7 @@ if (isset($_SERVER['REMOTE_ADDR'])) { } define('MOODLE_INTERNAL', 1); define('LANGPACKSFOLDER', '../../moodle-langpacks'); +define('APPMODULENAME','local_moodlemobileapp'); define('ASSETSPATH', '../src/assets/lang/'); define('CONFIG', '../moodle.config.json'); define('OVERRIDE_LANG_SUFIX', false); @@ -51,16 +52,16 @@ if (!file_exists(ASSETSPATH)) { } -$keys = get_langindex_keys(); +load_langindex(); -$added_langs = build_languages($languages, $keys); +$added_langs = build_languages($languages); if ($forcedetect) { - $new_langs = detect_languages($languages, $keys); + $new_langs = detect_languages($languages); if (!empty($new_langs)) { echo "\n\n\nThe following languages are going to be added\n\n\n"; - $added_langs = build_languages($new_langs, $keys, $added_langs); + $added_langs = build_languages($new_langs, $added_langs); } }