's * 5) added error_reporting(E_ALL ^ E_NOTICE); in "compare" mode (even in debug environment * we know that missing keys are missing strings here, not bugs ;-) */ require_once('../config.php'); require_once($CFG->libdir.'/adminlib.php'); $adminroot = admin_get_root(); admin_externalpage_setup('langedit', $adminroot); define('LANG_SUBMIT_REPEAT', 1); // repeat displaying submit button? define('LANG_SUBMIT_REPEAT_EVERY', 20); // if so, after how many lines? define('LANG_DISPLAY_MISSING_LINKS', 1); // display "go to first/next missing string" links? define('LANG_DEFAULT_FILE', ''); // default file to translate. Empty allowed define('LANG_LINK_MISSING_STRINGS', 1); // create links from "missing" page to "compare" page? define('LANG_DEFAULT_USELOCAL', 0); // should *_utf8_local be used by default? $mode = optional_param('mode', '', PARAM_ALPHA); $currentfile = optional_param('currentfile', LANG_DEFAULT_FILE, PARAM_FILE); $uselocal = optional_param('uselocal', -1, PARAM_INT); if ($uselocal == -1) { if (isset($SESSION->langtranslateintolocal)) { $uselocal = $SESSION->langtranslateintolocal; } else { $uselocal = LANG_DEFAULT_USELOCAL; } } else { $SESSION->langtranslateintolocal = $uselocal; } $strlanguage = get_string("language"); $strcurrentlanguage = get_string("currentlanguage"); $strmissingstrings = get_string("missingstrings"); $streditstrings = get_string("editstrings", 'admin'); $stredithelpdocs = get_string("edithelpdocs", 'admin'); $strthislanguage = get_string("thislanguage"); $strgotofirst = get_string('gotofirstmissing','admin'); $strfilestoredin = get_string('langstorein', 'admin'); $strfilestoredinhelp = get_string('langstoreinhelp', 'admin'); $strswitchlangdirbtn = get_string('langstoreswitch', 'admin'); $strchoosefiletoedit = get_string('langchoosefile', 'admin'); $streditennotallowed = get_string('langnoeditenglish', 'admin'); $strfilecreated = get_string('langfilecreated', 'admin'); // FIXME / TODO // remove following lines after adding string into proper english lang pack $strgotofirst = 'go to first missing string'; $strfilestoredin = 'Save file into folder :'; $strfilestoredinhelp = 'Where the file will be stored'; $strswitchlangdirbtn = 'switch'; $strchoosefiletoedit = 'Choose file to edit from the box above'; $streditennotallowed = 'Language en_utf8 cannot be edited with this page - switch to local'; $strfilecreated = 'New file created'; $currentlang = current_language(); switch ($mode) { case "missing": // Missing array keys are not bugs here but missing strings error_reporting(E_ALL ^ E_NOTICE); $navigation = "$strlanguage -> $strmissingstrings"; $title = $strmissingstrings; $button = '
'. ''. '
'; break; case "compare": $navigation = "$strlanguage -> $streditstrings"; $title = $streditstrings; $button = '
'. ''. '
'; break; default: $title = $strlanguage; $navigation = $strlanguage; $button = ''; break; } admin_externalpage_print_header($adminroot); if (!$mode) { print_simple_box_start('center','80%'); echo '
'; print_string('editlang','admin'); echo '
'; $currlang = current_language(); $langs = get_list_of_languages(); echo "$strcurrentlanguage:"; echo '
'; echo popup_form ("$CFG->wwwroot/$CFG->admin/lang.php?lang=", $langs, "chooselang", $currlang, "", "", "", true); $options["lang"] = $currentlang; print_heading("$strmissingstrings"); print_heading("$streditstrings"); print_heading("$stredithelpdocs"); echo '
'; print_simple_box_end(); admin_externalpage_print_footer($adminroot); exit; } // Get a list of all the root files in the English directory $langbase = $CFG->dataroot . '/lang'; $enlangdir = "$CFG->dirroot/lang/en_utf8"; if ($currentlang == 'en_utf8') { $langdir = $enlangdir; } else { $langdir = "$langbase/$currentlang"; } $locallangdir = "$langbase/{$currentlang}_local"; if (! $stringfiles = get_directory_list($enlangdir, "", false)) { error("Could not find English language pack!"); } foreach ($stringfiles as $key => $file) { if (substr($file, -4) != ".php") { //Avoid non php files to be showed unset($stringfiles[$key]); } if ($file == "langconfig.php") { //Avoid langconfig.php to be showed unset($stringfiles[$key]); } } if ($mode == "missing") { if (!file_exists($langdir)) { error ('to edit this language pack, you need to put it in '.$CFG->dataroot.'/lang'); } // Following variables store the HTML output to be echo-ed $m = ''; $o = ''; // For each file, check that a counterpart exists, then check all the strings foreach ($stringfiles as $file) { unset($string); include("$enlangdir/$file"); $enstring = $string; ksort($enstring); unset($string); if (file_exists("$langdir/$file")) { include("$langdir/$file"); $fileismissing = 0; } else { $fileismissing = 1; // notify(get_string("filemissing", "", "$langdir/$file")); $o .= '
'.get_string("filemissing", "", "$langdir/$file").'

'; $string = array(); } $missingcounter = 0; $first = true; foreach ($enstring as $key => $value) { if (empty($string[$key]) and $string[$key] != "0") { //bug fix 4735 mits $value = htmlspecialchars($value); $value = str_replace("$"."a", "\\$"."a", $value); $value = str_replace("%%","%",$value); if ($first) { $m .= "$file"; $m .= $fileismissing ? '*' : ''; $m .= '   '; $o .= "

".get_string("stringsnotset","","$langdir/$file")."

";
                        $first = false;
                        $somethingfound = true;
                    }
                    $missingcounter++;
                    if (LANG_LINK_MISSING_STRINGS) {
                        $missinglinkstart = "";
                        $missinglinkend = '';
                    } else {
                        $missinglinkstart = '';
                        $missinglinkend = '';
                    }
                    $o .= "$"."string['".$missinglinkstart.$key.$missinglinkend."'] = \"$value\";
"; } } if (!$first) { $o .= '

'; } } if ($m <> '') { echo '
'; print_simple_box_start("center", "80%"); echo '
'; echo $m; echo '
'; print_simple_box_end(); } echo $o; if (! $files = get_directory_list("$CFG->dirroot/lang/en_utf8/help", "CVS")) { error("Could not find English language help files!"); } foreach ($files as $filekey => $file) { // check all the help files. if (!file_exists("$langdir/help/$file")) { echo "

".get_string("filemissing", "", "$langdir/help/$file")."

"; $somethingfound = true; continue; } } if (! $files = get_directory_list("$CFG->dirroot/lang/en_utf8/docs", "CVS")) { error("Could not find English language docs files!"); } foreach ($files as $filekey => $file) { // check all the docs files. if (!file_exists("$langdir/docs/$file")) { echo "

".get_string("filemissing", "", "$langdir/docs/$file")."

"; $somethingfound = true; continue; } } if (!empty($somethingfound)) { print_continue("lang.php"); } else { notice(get_string("languagegood"), "lang.php"); } } else if ($mode == "compare") { if (!file_exists($langbase) ){ if (!lang_make_directory($langbase) ){ error('ERROR: Could not create base lang directory ' . $langbase); } else { echo '
Created directory '. $langbase .'
'."
\n"; } } if (!$uselocal && !file_exists($langdir)) { if (!lang_make_directory($langdir)) { error('ERROR: Could not create directory '.$langdir); } else { echo '
Created directory '. $langdir .'
'."
\n"; } } if ($uselocal && !file_exists($locallangdir)) { if (!lang_make_directory($locallangdir)) { echo '
ERROR: Could not create directory '. $locallangdir .'
'."
\n"; $uselocal = 0; } else { echo '
Created directory '. $locallangdir .'
'."
\n"; } } if (isset($_POST['currentfile'])){ // Save a file if (!confirm_sesskey()) { error(get_string('confirmsesskeybad', 'error')); } $newstrings = array(); foreach ($_POST as $postkey => $postval) { $stringkey = lang_file_string_key($postkey); $newstrings[$stringkey] = $postval; } unset($newstrings['currentfile']); if ($uselocal) { include("$langdir/$currentfile"); if (isset($string)) { $packstring = $string; } else { $packstring = array(); } unset($string); $saveinto = $locallangdir; } else { $packstring = array(); $saveinto = $langdir; } if (lang_save_file($saveinto, $currentfile, $newstrings, $uselocal, $packstring)) { notify(get_string("changessaved")." ($saveinto/$currentfile)", "green"); } else { error("Could not save the file '$saveinto/$currentfile'!", "lang.php?mode=compare&currentfile=$currentfile"); } unset($packstring); } print_heading_with_help($streditstrings, "langedit"); print_simple_box_start("center", "80%"); echo '
'; foreach ($stringfiles as $file) { if ($file == $currentfile) { echo "$file   "; } else { echo "$file   "; } } echo '
'; print_simple_box_end(); print_simple_box_start("center", "80%"); echo '
'.$strfilestoredin.' '; echo $uselocal ? "{$currentlang}_local" : $currentlang; echo ' '; helpbutton('langswitchstorage', $strfilestoredinhelp, 'moodle'); echo '
'. ''. ''. ''. ''. '
'; print_simple_box_end(); if ($currentfile <> '') { $saveto = $uselocal ? $locallangdir : $langdir; error_reporting(0); if (!file_exists("$saveto/$currentfile")) { if (!@touch("$saveto/$currentfile")) { print_heading(get_string("filemissing", "", "$saveto/$currentfile"), "center", 4, "error"); } else { print_heading($strfilecreated, "center", 4, "notifysuccess"); } } if ($currentlang == "en_utf8" && !$uselocal) { $editable = false; print_heading($streditennotallowed, 'center', 4); } elseif ($f = fopen("$saveto/$currentfile","r+")) { $editable = true; fclose($f); } else { $editable = false; echo "

".get_string("makeeditable", "", "$saveto/$currentfile")."

"; } error_reporting($CFG->debug); print_heading("$currentfile", "center", 4); if (LANG_DISPLAY_MISSING_LINKS && $editable) { print_heading(''.$strgotofirst.'', "center", 4); } unset($string); include("$enlangdir/$currentfile"); $enstring = $string; if ($currentlang != 'en' and $currentfile == 'moodle.php') { $enstring['thislanguage'] = "<< TRANSLATORS: Specify the name of your language here. If possible use Unicode Numeric Character References >>"; $enstring['thischarset'] = "<< TRANSLATORS: Charset encoding - always use utf-8 >>"; $enstring['thisdirection'] = "<< TRANSLATORS: This string specifies the direction of your text, either left-to-right or right-to-left. Insert either 'ltr' or 'rtl' here. >>"; $enstring['parentlanguage'] = "<< TRANSLATORS: If your language has a Parent Language that Moodle should use when strings are missing from your language pack, then specify the code for it here. If you leave this blank then English will be used. Example: nl >>"; } ksort($enstring); unset($string); @include("$locallangdir/$currentfile"); $localstring = isset($string) ? $string : array(); unset($string); @include("$langdir/$currentfile"); if ($editable) { echo "
"; } echo ""; $linescounter = 0; $missingcounter = 0; foreach ($enstring as $key => $envalue) { $linescounter++ ; if (LANG_SUBMIT_REPEAT && $editable && $linescounter % LANG_SUBMIT_REPEAT_EVERY == 0) { echo ''; } $envalue = nl2br(htmlspecialchars($envalue)); $envalue = preg_replace('/(\$a\-\>[a-zA-Z0-9]*|\$a)/', '$0', $envalue); // Make variables bold. $envalue = str_replace("%%","%",$envalue); $envalue = str_replace("\\","",$envalue); // Delete all slashes echo "\n\n".''; echo ''."\n"; echo ''."\n"; // Missing array keys are not bugs here but missing strings error_reporting(E_ALL ^ E_NOTICE); if ($uselocal) { $value = lang_fix_value_from_file($localstring[$key]); $value2 = lang_fix_value_from_file($string[$key]); if ($value == '') { $value = $value2; } } else { $value = lang_fix_value_from_file($string[$key]); $value2 = lang_fix_value_from_file($localstring[$key]); } error_reporting($CFG->debug); // Color highlighting: // red #ef6868 - translation missing in both system and local pack // yellow #feff7f - translation missing in system pack but is translated in local // green #AAFFAA - translation present in both system and local but is different if (!$value) { if (!$value2) { $cellcolour = 'style="background-color: #ef6868"'; // TODO: replace by CSS class } else { $cellcolour = 'style="background-color: #feff7f"'; // TODO: replace by CSS class } $missingcounter++; if (LANG_DISPLAY_MISSING_LINKS) { $missingtarget = ''; $missingnext = ''. ''; $missingprev = ''. ''; } else { $missingtarget = ''; $missingnext = ''; $missingprev = ''; } } else { if ($value <> $value2 && $value2 <> '') { $cellcolour = 'style="background-color: #AAFFAA"'; // TODO: replace by CSS class } else { $cellcolour = ''; } $missingtarget = ''; $missingnext = ''; $missingprev = ''; } if ($editable) { echo ''; } else { echo ''; } } if ($editable) { echo ''; } echo '
 
'; echo ' '; echo '
 
'.$key.''.$envalue.''. $missingprev . $missingtarget."\n"; if (isset($string[$key])) { $valuelen = strlen($value); } else { $valuelen = strlen($envalue); } $cols=50; if (strstr($value, "\r") or strstr($value, "\n") or $valuelen > $cols) { $rows = ceil($valuelen / $cols); echo ''."\n"; } else { if ($valuelen) { $cols = $valuelen + 5; } echo ''; } if ($value2 <> '' && $value <> $value2) { echo '
'.$value2.''; } echo $missingnext . '
'.$value.'
 
'; echo ''; echo ' '; echo ' '; echo ' '; echo '
'; echo '
'; } else { // no $currentfile specified print_heading($strchoosefiletoedit, "center", 4); } } admin_externalpage_print_footer($adminroot); ////////////////////////////////////////////////////////////////////// /** * Save language translation file. * * Thanks to Petri Asikainen for the original version of code * used to save language files. * * @uses $CFG * @uses $USER * @param string $path Full pathname to the directory to use * @param string $file File to overwrite * @param array $strings Array of strings to write * @param bool $local Should *_local version be saved? * @param array $packstrings Array of default langpack strings (needed if $local) * @return bool Created successfully? */ function lang_save_file($path, $file, $strings, $local, $packstrings) { global $CFG, $USER; if (!$f = @fopen("$path/$file","w")) { return false; } fwrite($f, "release ($CFG->version)\n"); if ($local) { fwrite($f, " // local modifications from $CFG->wwwroot\n"); } fwrite($f, "\n\n"); ksort($strings); foreach ($strings as $key => $value) { @list($id, $stringname) = explode('XXX',$key); if ($CFG->lang != "zh_hk" and $CFG->lang != "zh_tw") { // Some MB languages include backslash bytes $value = str_replace("\\","",$value); // Delete all slashes } $value = str_replace("'", "\\'", $value); // Add slashes for ' $value = str_replace('"', "\\\"", $value); // Add slashes for " $value = str_replace("%","%%",$value); // Escape % characters $value = str_replace("\r", "",$value); // Remove linefeed characters $value = trim($value); // Delete leading/trailing white space if ($id == "string" and $value != ""){ if ((!$local) || (lang_fix_value_from_file($packstrings[$stringname]) <> lang_fix_value_from_file($value))) { fwrite($f,"\$string['$stringname'] = '$value';\n"); } } } fwrite($f,"\n?>\n"); fclose($f); return true; } /** * Fix value of string to translate. * * @param string $value Original string from the file * @return string Fixed value */ function lang_fix_value_from_file($value='') { $value = str_replace("\r","",$value); // Bad character caused by Windows $value = preg_replace("/\n{3,}/", "\n\n", $value); // Collapse runs of blank lines $value = trim($value); // Delete leading/trailing white space $value = str_replace("\\","",$value); // Delete all slashes $value = str_replace("%%","%",$value); $value = str_replace("<","<",$value); $value = str_replace(">",">",$value); $value = str_replace('"',""",$value); return $value; } /** * Try and create a new language directory. * * @uses $CFG * @param string $directory full path to the directory under $langbase * @return string|false Returns full path to directory if successful, false if not */ function lang_make_directory($dir, $shownotices=true) { global $CFG; umask(0000); if (! file_exists($dir)) { if (! @mkdir($dir, $CFG->directorypermissions)) { return false; } //@chmod($dir, $CFG->directorypermissions); // Just in case mkdir didn't do it } return $dir; } /// Following functions are required because '.' in form input names /// get replaced by '_' by PHP. function lang_form_string_key($keyfromfile) { return str_replace('.', '##46#', $keyfromfile); /// Derived from ., the ascii value for a period. } function lang_file_string_key($keyfromform) { return str_replace('##46#', '.', $keyfromform); } ?>