From bb45fe62c497f20232d722f70da0faac9fc15aba Mon Sep 17 00:00:00 2001
From: tjhunt '. get_string('helpindex') .'';
+echo ' ' . get_string('showthishelpinlanguage', 'moodle', $nextlangname) . '
" . get_string('showthishelpinlanguage', 'moodle', $nextlangname) . '';
+ echo '
' . get_string($qtype . 'summary', 'qtype_' . $qtype) . "
\n\n"; } -function include_help_for_each_resource($file, $langs, $helpdir) { +function include_help_for_each_resource($forcelang, $skiplocal) { global $CFG; require_once($CFG->dirroot .'/mod/resource/lib.php'); $typelist = resource_get_types(); - + //add label type $labelType = new object(); $labelType->modclass = MOD_CLASS_RESOURCE; @@ -269,19 +189,10 @@ function include_help_for_each_resource($file, $langs, $helpdir) { $typelist[] = $labelType; foreach ($typelist as $type) { - - foreach ($langs as $lang) { - if (empty($lang)) { - continue; - } - - $filepath = "$helpdir/resource/type/".$type->name.".html"; - - if (file_exists_and_readable($filepath)) { - echo ''.$name.'
'; + echo '
- * $string['wordforstudent'] = 'Your word for Student';
- *
- * So if you want to display the string 'Your word for student'
- * in any language that supports it on your site
- * you just need to use the identifier 'wordforstudent'
- *
- * $mystring = ''. get_string('wordforstudent') .'';
-or
- *
- * If the string you want is in another file you'd take a slightly
- * different approach. Looking in moodle/lang/en/calendar.php you find
- * around line 75:
- *
- * $string['typecourse'] = 'Course event';
- *
- * If you want to display the string "Course event" in any language
- * supported you would use the identifier 'typecourse' and the module 'calendar'
- * (because it is in the file calendar.php):
- *
- * $mystring = ''. get_string('typecourse', 'calendar') .'
';
- *
- *
- * As a last resort, should the identifier fail to map to a string
- * the returned string will be [[ $identifier ]]
- *
- * @uses $CFG
- * @param string $identifier The key identifier for the localized string
- * @param string $module The module where the key identifier is stored,
- * usually expressed as the filename in the language pack without the
- * .php on the end but can also be written as mod/forum or grade/export/xls.
- * If none is specified then moodle.php is used.
- * @param mixed $a An object, string or number that can be used
- * within translation strings
- * @param array $extralocations DEPRICATED. An array of strings with other
- * locations to look for string files. This used to be used by plugins so
- * they could package their language strings in the plugin folder, however,
- * There is now a better way to achieve this. See
- * http://docs.moodle.org/en/Development:Places_to_search_for_lang_strings.
- * @return string The localized string.
- */
-function get_string($identifier, $module='', $a=NULL, $extralocations=NULL) {
- global $CFG;
-
-/// originally these special strings were stored in moodle.php now we are only in langconfig.php
- $langconfigstrs = array('alphabet', 'backupnameformat', 'decsep', 'firstdayofweek', 'listsep', 'locale',
- 'localewin', 'localewincharset', 'oldcharset', 'parentlanguage',
- 'strftimedate', 'strftimedateshort', 'strftimedatefullshort', 'strftimedatetime',
- 'strftimedaydate', 'strftimedaydatetime', 'strftimedayshort', 'strftimedaytime',
- 'strftimemonthyear', 'strftimerecent', 'strftimerecentfull', 'strftimetime',
- 'thischarset', 'thisdirection', 'thislanguage', 'strftimedatetimeshort', 'thousandssep');
-
- $filetocheck = 'langconfig.php';
- $defaultlang = 'en_utf8';
- if (in_array($identifier, $langconfigstrs)) {
- $module = 'langconfig'; //This strings are under langconfig.php for 1.6 lang packs
- }
-
- $lang = current_language();
-
- if ($module == '') {
- $module = 'moodle';
- }
-
-/// If the "module" is actually a pathname, then automatically derive the proper module name
- if (strpos($module, '/') !== false) {
+ protected function fix_deprecated_module_name($module) {
+ debugging('The module name you passed to get_string is the deprecated format ' .
+ 'like mod/mymod or block/myblock. The correct form looks like mymod, or block_myblock.' , DEBUG_DEVELOPER);
$modulepath = split('/', $module);
switch ($modulepath[0]) {
-
case 'mod':
- $module = $modulepath[1];
- break;
-
+ return $modulepath[1];
case 'blocks':
case 'block':
- $module = 'block_'.$modulepath[1];
- break;
-
+ return 'block_'.$modulepath[1];
case 'enrol':
- $module = 'enrol_'.$modulepath[1];
- break;
-
+ return 'enrol_'.$modulepath[1];
case 'format':
- $module = 'format_'.$modulepath[1];
- break;
-
+ return 'format_'.$modulepath[1];
case 'grade':
- $module = 'grade'.$modulepath[1].'_'.$modulepath[2];
- break;
+ return 'grade'.$modulepath[1].'_'.$modulepath[2];
+ default:
+ return $module;
}
}
-/// if $a happens to have % in it, double it so sprintf() doesn't break
- if ($a) {
- $a = clean_getstring_data( $a );
+ protected function locations_to_search($module) {
+ if (isset($this->searchpathsformodule[$module])) {
+ return $this->searchpathsformodule[$module];
+ }
+
+ $locations = $this->corelocations;
+
+ if (!array_key_exists($module, $this->nonpluginfiles)) {
+ foreach ($locations as $location => $ignored) {
+ $locations[$location] = $module . '/';
+ }
+ if ($module == 'local') {
+ $locations[$this->dirroot . '/local/lang/'] = 'local/';
+ } else {
+ list($type, $plugin) = $this->parse_module_name($module);
+ if (isset($this->searchplacesbyplugintype[$type])) {
+ foreach ($this->searchplacesbyplugintype[$type] as $location) {
+ $locations[$this->dirroot . "/$location/$plugin/lang/"] = $plugin . '/';
+ }
+ }
+ }
+ }
+
+ $this->searchpathsformodule[$module] = $locations;
+ return $locations;
}
-/// Define the two or three major locations of language strings for this module
- $locations = array();
+ protected function parse_module_name($module) {
+ $dividerpos = strpos($module, '_');
+ if ($dividerpos === false) {
+ $type = '';
+ $plugin = $module;
+ } else {
+ $type = substr($module, 0, $dividerpos + 1);
+ $plugin = substr($module, $dividerpos + 1);
+ }
+ return array($type, $plugin);
+ }
- if (!empty($extralocations)) {
+ protected function add_extra_locations($locations, $extralocations) {
// This is an old, deprecated mechanism that predates the
// places_to_search_for_lang_strings mechanism that comes later in
// this function. So tell people who use it to change.
@@ -5394,197 +5354,224 @@ function get_string($identifier, $module='', $a=NULL, $extralocations=NULL) {
'See http://docs.moodle.org/en/Development:Places_to_search_for_lang_strings ' .
'for a better way to package language strings with your plugin.', DEBUG_DEVELOPER);
if (is_array($extralocations)) {
- $locations += $extralocations;
+ $locations = array_merge($locations, $extralocations);
} else if (is_string($extralocations)) {
$locations[] = $extralocations;
} else {
debugging('Bad lang path provided');
}
+ return $locations;
}
- if (!empty($CFG->running_installer) and $lang !== 'en_utf8') {
- static $stringnames = null;
- if (!$stringnames) {
- $stringnames = file($CFG->dirroot.'/install/stringnames.txt');
- $stringnames = array_map('trim', $stringnames);
+ protected function get_parent_language($lang) {
+ if (array_key_exists($lang, $this->parentlangs)) {
+ return $this->parentlangs[$lang];
}
- if (array_search($identifier, $stringnames) !== false) {
- $module = 'installer';
- $filetocheck = 'installer.php';
- $defaultlang = 'en_utf8';
- $locations[] = $CFG->dirroot.'/install/lang/';
+ $parent = 'en_utf8'; // Will be used if nothing is specified explicitly.
+ foreach ($this->corelocations as $location => $ignored) {
+ foreach (array('_local', '') as $suffix) {
+ $file = $location . $lang . $suffix . '/' . $this->parentlangfile;
+ if ($result = $this->get_string_from_file('parentlanguage', $file, NULL)) {
+ $parent = $result;
+ break 2;
+ }
+ }
}
+ $this->parentlangs[$lang] = $parent;
+ return $parent;
}
- $locations[] = $CFG->dataroot.'/lang/';
- $locations[] = $CFG->dirroot.'/lang/';
- $locations[] = $CFG->dirroot.'/local/lang/';
-
-/// Add extra places to look for strings for particular plugin types.
- $rules = places_to_search_for_lang_strings();
- $exceptions = $rules['__exceptions'];
- unset($rules['__exceptions']);
-
- if (!in_array($module, $exceptions)) {
- $dividerpos = strpos($module, '_');
- if ($dividerpos === false) {
- $type = '';
- $plugin = $module;
- } else {
- $type = substr($module, 0, $dividerpos + 1);
- $plugin = substr($module, $dividerpos + 1);
+ protected function load_lang_file($langfile) {
+ if (isset($this->strings[$langfile])) {
+ return $this->strings[$langfile];
}
- if (!empty($rules[$type])) {
- foreach ($rules[$type] as $location) {
- $locations[] = $CFG->dirroot . "/$location/$plugin/lang/";
- }
+ $string = array();
+ if (file_exists($langfile)) {
+ include($langfile);
}
+ $this->strings[$langfile] = $string;
+ return $string;
}
-/// First check all the normal locations for the string in the current language
- $resultstring = '';
- foreach ($locations as $location) {
- $locallangfile = $location.$lang.'_local'.'/'.$module.'.php'; //first, see if there's a local file
- if (file_exists($locallangfile)) {
- if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
- if (eval($result) === FALSE) {
- trigger_error('Lang error: '.$identifier.':'.$locallangfile, E_USER_NOTICE);
- }
- return $resultstring;
- }
+ protected function get_string_from_file($identifier, $langfile, $a) {
+ $string = &$this->load_lang_file($langfile);
+ if (!isset($string[$identifier])) {
+ return false;
}
- //if local directory not found, or particular string does not exist in local direcotry
- $langfile = $location.$lang.'/'.$module.'.php';
- if (file_exists($langfile)) {
- if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
- if (eval($result) === FALSE) {
- trigger_error('Lang error: '.$identifier.':'.$langfile, E_USER_NOTICE);
- }
- return $resultstring;
- }
- }
+ $result = $string[$identifier];
+ // Skip the eval if we can - slight performance win. Pity there are 3
+ // different problem characters, so we have to use preg_match,
+ // rather than a faster str... function.
+ if (!preg_match('/[%$\\\\]/', $result)) {
+ return $result;
+ }
+ // Moodle used to use $code = '$result = sprintf("' . $result . ')";' for no good reason,
+ // (it had done that since revision 1.1 of moodllib.php if you check CVS). However, this
+ // meant you had to double up '%' chars in $a first. We now skip that. However, lang strings
+ // still contain %% as a result, so we need to fix those.
+ $result = str_replace('%%', '%', $result);
+ $code = '$result = "' . $result . '";';
+ if (eval($code) === FALSE) { // Means parse error.
+ debugging('Parse error while trying to load string "'.$identifier.'" from file "' . $langfile . '".', DEBUG_DEVELOPER);
+ }
+ return $result;
}
-/// If the preferred language was English (utf8) we can abort now
-/// saving some checks beacuse it's the only "root" lang
- if ($lang == 'en_utf8') {
- return '[['. $identifier .']]';
- }
+ public function find_help_file($file, $module, $forcelang, $skiplocal) {
+ if ($forcelang) {
+ $langs = array($forcelang, 'en_utf8');
+ } else {
+ $langs = array();
+ for ($lang = current_language(); $lang; $lang = $this->get_parent_language($lang)) {
+ $langs[] = $lang;
+ }
+ }
-/// Is a parent language defined? If so, try to find this string in a parent language file
+ $locations = $this->locations_to_search($module);
- foreach ($locations as $location) {
- $langfile = $location.$lang.'/'.$filetocheck;
- if (file_exists($langfile)) {
- if ($result = get_string_from_file('parentlanguage', $langfile, "\$parentlang")) {
- if (eval($result) === FALSE) {
- trigger_error('Lang error: '.$identifier.':'.$langfile, E_USER_NOTICE);
- }
- if (!empty($parentlang) and strpos($parentlang, '<') === false) { // found it!
-
- //first, see if there's a local file for parent
- $locallangfile = $location.$parentlang.'_local'.'/'.$module.'.php';
- if (file_exists($locallangfile)) {
- if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
- if (eval($result) === FALSE) {
- trigger_error('Lang error: '.$identifier.':'.$locallangfile, E_USER_NOTICE);
- }
- return $resultstring;
- }
- }
+ if ($skiplocal) {
+ $localsuffices = array('');
+ } else {
+ $localsuffices = array('_local', '');
+ }
- //if local directory not found, or particular string does not exist in local direcotry
- $langfile = $location.$parentlang.'/'.$module.'.php';
- if (file_exists($langfile)) {
- if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
- eval($result);
- return $resultstring;
- }
+ foreach ($langs as $lang) {
+ foreach ($locations as $location => $locationsuffix) {
+ foreach ($localsuffices as $localsuffix) {
+ $filepath = $location . $lang . $localsuffix . '/help/' . $locationsuffix . $file;
+ // Now, try to include the help text from this file, if we can.
+ if (file_exists_and_readable($filepath)) {
+ return array($filepath, $lang);
}
}
}
}
+
+ return array('', '');
}
-/// Our only remaining option is to try English
+ private function start_logging() {
+ $this->logtofile = true;
+ }
- foreach ($locations as $location) {
- $locallangfile = $location.$defaultlang.'_local/'.$module.'.php'; //first, see if there's a local file
- if (file_exists($locallangfile)) {
- if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
- eval($result);
- return $resultstring;
- }
+ private function log_get_string_call($identifier, $module, $a) {
+ global $CFG;
+ if ($this->logtofile === true) {
+ $logdir = $CFG->dataroot . '/temp/getstringlog';
+ $filename = strtr(str_replace($CFG->wwwroot . '/', '', qualified_me()), ':/', '__') . '_get_string.log.php';
+ @mkdir($logdir, $CFG->directorypermissions, true);
+ $this->logtofile = fopen("$logdir/$filename", 'w');
+ fwrite($this->logtofile, "logtofile, "get_string('$identifier', '$module', " . var_export($a, true) . ");\n");
+ }
- //if local_en not found, or string not found in local_en
- $langfile = $location.$defaultlang.'/'.$module.'.php';
+ public function get_string($identifier, $module='', $a=NULL, $extralocations=NULL) {
+ if ($this->logtofile) {
+ $this->log_get_string_call($identifier, $module, $a);
+ }
- if (file_exists($langfile)) {
- if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
- eval($result);
- return $resultstring;
- }
+ /// Preprocess the arguments.
+ if ($module == '') {
+ $module = 'moodle';
}
- }
-/// And, because under 1.6 en is defined as en_utf8 child, me must try
-/// if it hasn't been queried before.
- if ($defaultlang == 'en') {
- $defaultlang = 'en_utf8';
- foreach ($locations as $location) {
- $locallangfile = $location.$defaultlang.'_local/'.$module.'.php'; //first, see if there's a local file
- if (file_exists($locallangfile)) {
- if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
- eval($result);
- return $resultstring;
- }
- }
+ if ($module == 'moodle' && array_key_exists($identifier, $this->langconfigstrs)) {
+ $module = 'langconfig';
+ }
+
+ if (strpos($module, '/') !== false) {
+ $module = $this->fix_deprecated_module_name($module);
+ }
- //if local_en not found, or string not found in local_en
- $langfile = $location.$defaultlang.'/'.$module.'.php';
+ $locations = $this->locations_to_search($module);
- if (file_exists($langfile)) {
- if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
- eval($result);
- return $resultstring;
+ if (!is_null($this->installstrings) && in_array($identifier, $this->installstrings)) {
+ $module = 'installer';
+ array_unshift($locations, $this->dirroot . '/install/lang/');
+ }
+
+ if ($extralocations) {
+ $locations = $this->add_extra_locations($locations, $extralocations);
+ }
+
+ /// Now do the search.
+ for ($lang = current_language(); $lang; $lang = $this->get_parent_language($lang)) {
+ foreach ($locations as $location => $ignored) {
+ foreach (array('_local', '') as $suffix) {
+ $file = $location . $lang . $suffix . '/' . $module . '.php';
+ if ($result = $this->get_string_from_file($identifier, $file, $a)) {
+ return $result;
+ }
}
}
}
- }
- return '[['.$identifier.']]'; // Last resort
+ return '[[' . $identifier . ']]'; // Last resort.
+ }
}
/**
- * This function is only used from {@link get_string()}.
+ * Returns a localized string.
+ *
+ * Returns the translated string specified by $identifier as
+ * for $module. Uses the same format files as STphp.
+ * $a is an object, string or number that can be used
+ * within translation strings
+ *
+ * eg "hello \$a->firstname \$a->lastname"
+ * or "hello \$a"
+ *
+ * If you would like to directly echo the localized string use
+ * the function {@link print_string()}
*
- * @internal Only used from get_string, not meant to be public API
- * @param string $identifier ?
- * @param string $langfile ?
- * @param string $destination ?
- * @return string|false ?
- * @staticvar array $strings Localized strings
- * @access private
- * @todo Finish documenting this function.
+ * Example usage of this function involves finding the string you would
+ * like a local equivalent of and using its identifier and module information
+ * to retrive it.
+ * $string['wordforstudent'] = 'Your word for Student';
+ *
+ * So if you want to display the string 'Your word for student'
+ * in any language that supports it on your site
+ * you just need to use the identifier 'wordforstudent'
+ *
+ * $mystring = ''. get_string('wordforstudent') .'';
+or
+ *
+ * If the string you want is in another file you'd take a slightly
+ * different approach. Looking in moodle/lang/en/calendar.php you find
+ * around line 75:
+ *
+ * $string['typecourse'] = 'Course event';
+ *
+ * If you want to display the string "Course event" in any language
+ * supported you would use the identifier 'typecourse' and the module 'calendar'
+ * (because it is in the file calendar.php):
+ *
+ * $mystring = ''. get_string('typecourse', 'calendar') .'
';
+ *
+ *
+ * As a last resort, should the identifier fail to map to a string
+ * the returned string will be [[ $identifier ]]
+ *
+ * @param string $identifier The key identifier for the localized string
+ * @param string $module The module where the key identifier is stored,
+ * usually expressed as the filename in the language pack without the
+ * .php on the end but can also be written as mod/forum or grade/export/xls.
+ * If none is specified then moodle.php is used.
+ * @param mixed $a An object, string or number that can be used
+ * within translation strings
+ * @param array $extralocations DEPRICATED. An array of strings with other
+ * locations to look for string files. This used to be used by plugins so
+ * they could package their language strings in the plugin folder, however,
+ * There is now a better way to achieve this. See
+ * http://docs.moodle.org/en/Development:Places_to_search_for_lang_strings.
+ * @return string The localized string.
*/
-function get_string_from_file($identifier, $langfile, $destination) {
-
- static $strings; // Keep the strings cached in memory.
-
- if (empty($strings[$langfile])) {
- $string = array();
- include ($langfile);
- $strings[$langfile] = $string;
- } else {
- $string = &$strings[$langfile];
- }
-
- if (!isset ($string[$identifier])) {
- return false;
- }
-
- return $destination .'= sprintf("'. $string[$identifier] .'");';
+function get_string($identifier, $module='', $a=NULL, $extralocations=NULL) {
+ return string_manager::instance()->get_string($identifier, $module, $a, $extralocations);
}
/**
@@ -5592,13 +5579,12 @@ function get_string_from_file($identifier, $langfile, $destination) {
*
* @param array $array An array of strings
* @param string $module The language module that these strings can be found in.
- * @return string
+ * @return array and array of translated strings.
*/
function get_strings($array, $module='') {
-
- $string = NULL;
+ $string = new stdClass;
foreach ($array as $item) {
- $string->$item = get_string($item, $module);
+ $string->$item = string_manager::instance()->get_string($item, $module);
}
return $string;
}
diff --git a/lib/simpletest/get_string_fixtures/moodle/blocks/mrbs/lang/en_utf8/block_mrbs.php b/lib/simpletest/get_string_fixtures/moodle/blocks/mrbs/lang/en_utf8/block_mrbs.php
new file mode 100644
index 0000000000..a82aff4f06
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodle/blocks/mrbs/lang/en_utf8/block_mrbs.php
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/moodle/blocks/mrbs/lang/fr_utf8/block_mrbs.php b/lib/simpletest/get_string_fixtures/moodle/blocks/mrbs/lang/fr_utf8/block_mrbs.php
new file mode 100644
index 0000000000..0ce399a5c1
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodle/blocks/mrbs/lang/fr_utf8/block_mrbs.php
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/moodle/lang/en_utf8/moodle.php b/lib/simpletest/get_string_fixtures/moodle/lang/en_utf8/moodle.php
new file mode 100644
index 0000000000..39a50cf8fc
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodle/lang/en_utf8/moodle.php
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/moodle/lang/en_utf8/test.php b/lib/simpletest/get_string_fixtures/moodle/lang/en_utf8/test.php
new file mode 100644
index 0000000000..e079506281
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodle/lang/en_utf8/test.php
@@ -0,0 +1,5 @@
+firstname $a->lastname,\n\nOn test \"$a->testname\" you scored $a->grade%% which earns you \$100.';
+?>
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/moodle/lang/en_utf8_local/moodle.php b/lib/simpletest/get_string_fixtures/moodle/lang/en_utf8_local/moodle.php
new file mode 100644
index 0000000000..b3d35a3f62
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodle/lang/en_utf8_local/moodle.php
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/moodle/lang/es_ar_utf8_local/langconfig.php b/lib/simpletest/get_string_fixtures/moodle/lang/es_ar_utf8_local/langconfig.php
new file mode 100644
index 0000000000..b1d732a41e
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodle/lang/es_ar_utf8_local/langconfig.php
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/moodledata/lang/es_ar_utf8/langconfig.php b/lib/simpletest/get_string_fixtures/moodledata/lang/es_ar_utf8/langconfig.php
new file mode 100644
index 0000000000..6767ae8ee1
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodledata/lang/es_ar_utf8/langconfig.php
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/moodledata/lang/fr_ca_utf8/langconfig.php b/lib/simpletest/get_string_fixtures/moodledata/lang/fr_ca_utf8/langconfig.php
new file mode 100644
index 0000000000..a0156df76f
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodledata/lang/fr_ca_utf8/langconfig.php
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/moodledata/lang/fr_ca_utf8/test.php b/lib/simpletest/get_string_fixtures/moodledata/lang/fr_ca_utf8/test.php
new file mode 100644
index 0000000000..2d728dd945
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodledata/lang/fr_ca_utf8/test.php
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/moodledata/lang/fr_utf8/test.php b/lib/simpletest/get_string_fixtures/moodledata/lang/fr_utf8/test.php
new file mode 100644
index 0000000000..0a0fbd1d6d
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/moodledata/lang/fr_utf8/test.php
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/lib/simpletest/get_string_fixtures/pagelogs/admin_index.php_get_string.log.php b/lib/simpletest/get_string_fixtures/pagelogs/admin_index.php_get_string.log.php
new file mode 100644
index 0000000000..e73150d3a0
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/pagelogs/admin_index.php_get_string.log.php
@@ -0,0 +1,2010 @@
+Admin User');
+get_string('logout', '', NULL);
+get_string('thisdirection', '', NULL);
+get_string('thisdirection', '', NULL);
+get_string('administrationsite', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderopened', '', NULL);
+get_string('folderclosed', '', NULL);
+get_string('searchinsettings', 'admin', NULL);
+get_string('search', '', NULL);
+get_string('showblocka', 'access', 'Site Administration');
+get_string('hideblocka', 'access', 'Site Administration');
+get_string('skipa', 'access', 'Site Administration');
+get_string('showblocka', 'access', 'Site Administration');
+get_string('hideblocka', 'access', 'Site Administration');
+get_string('adminbookmarks', '', NULL);
+get_string('bookmarkthispage', 'admin', NULL);
+get_string('showblocka', 'access', 'Admin bookmarks');
+get_string('hideblocka', 'access', 'Admin bookmarks');
+get_string('skipa', 'access', 'Admin bookmarks');
+get_string('showblocka', 'access', 'Admin bookmarks');
+get_string('hideblocka', 'access', 'Admin bookmarks');
+get_string('displayerrorswarning', 'admin', NULL);
+get_string('installation', 'install', NULL);
+get_string('helpprefix2', '', 'Installation');
+get_string('newwindow', '', NULL);
+get_string('cronwarning', 'admin', NULL);
+get_string('home', '', NULL);
+get_string('loggedinas', 'moodle', 'Admin User');
+get_string('logout', '', NULL);
+get_string('moodledocslink', '', NULL);
diff --git a/lib/simpletest/get_string_fixtures/pagelogs/admin_index.php_old_get_string.log.php b/lib/simpletest/get_string_fixtures/pagelogs/admin_index.php_old_get_string.log.php
new file mode 100644
index 0000000000..ba1eb44a15
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/pagelogs/admin_index.php_old_get_string.log.php
@@ -0,0 +1,2010 @@
+Admin User');
+old_get_string('logout', '', NULL);
+old_get_string('thisdirection', '', NULL);
+old_get_string('thisdirection', '', NULL);
+old_get_string('administrationsite', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderopened', '', NULL);
+old_get_string('folderclosed', '', NULL);
+old_get_string('searchinsettings', 'admin', NULL);
+old_get_string('search', '', NULL);
+old_get_string('showblocka', 'access', 'Site Administration');
+old_get_string('hideblocka', 'access', 'Site Administration');
+old_get_string('skipa', 'access', 'Site Administration');
+old_get_string('showblocka', 'access', 'Site Administration');
+old_get_string('hideblocka', 'access', 'Site Administration');
+old_get_string('adminbookmarks', '', NULL);
+old_get_string('bookmarkthispage', 'admin', NULL);
+old_get_string('showblocka', 'access', 'Admin bookmarks');
+old_get_string('hideblocka', 'access', 'Admin bookmarks');
+old_get_string('skipa', 'access', 'Admin bookmarks');
+old_get_string('showblocka', 'access', 'Admin bookmarks');
+old_get_string('hideblocka', 'access', 'Admin bookmarks');
+old_get_string('displayerrorswarning', 'admin', NULL);
+old_get_string('installation', 'install', NULL);
+old_get_string('helpprefix2', '', 'Installation');
+old_get_string('newwindow', '', NULL);
+old_get_string('cronwarning', 'admin', NULL);
+old_get_string('home', '', NULL);
+old_get_string('loggedinas', 'moodle', 'Admin User');
+old_get_string('logout', '', NULL);
+old_get_string('moodledocslink', '', NULL);
diff --git a/lib/simpletest/get_string_fixtures/pagelogs/course_view.php_get_string.log.php b/lib/simpletest/get_string_fixtures/pagelogs/course_view.php_get_string.log.php
new file mode 100644
index 0000000000..c5f812d846
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/pagelogs/course_view.php_get_string.log.php
@@ -0,0 +1,353 @@
+Admin User');
+get_string('logout', '', NULL);
+get_string('thisdirection', '', NULL);
+get_string('thisdirection', '', NULL);
+get_string('tocontent', 'access', NULL);
+get_string('modulenameplural', 'forum', NULL);
+get_string('modulenameplural', 'quiz', NULL);
+get_string('modulenameplural', 'choice', NULL);
+get_string('modulename', 'assignment', NULL);
+get_string('modulenameplural', 'assignment', NULL);
+get_string('modulename', 'choice', NULL);
+get_string('modulenameplural', 'choice', NULL);
+get_string('modulename', 'data', NULL);
+get_string('modulenameplural', 'data', NULL);
+get_string('modulename', 'forum', NULL);
+get_string('modulenameplural', 'forum', NULL);
+get_string('modulename', 'glossary', NULL);
+get_string('modulenameplural', 'glossary', NULL);
+get_string('modulename', 'label', NULL);
+get_string('modulenameplural', 'label', NULL);
+get_string('modulename', 'resource', NULL);
+get_string('modulenameplural', 'resource', NULL);
+get_string('modulename', 'scorm', NULL);
+get_string('modulenameplural', 'scorm', NULL);
+get_string('modulename', 'survey', NULL);
+get_string('modulenameplural', 'survey', NULL);
+get_string('modulename', 'lesson', NULL);
+get_string('modulenameplural', 'lesson', NULL);
+get_string('modulename', 'quiz', NULL);
+get_string('modulenameplural', 'quiz', NULL);
+get_string('modulename', 'chat', NULL);
+get_string('modulenameplural', 'chat', NULL);
+get_string('modulename', 'feedback', NULL);
+get_string('modulenameplural', 'feedback', NULL);
+get_string('editsummary', '', NULL);
+get_string('add', '', NULL);
+get_string('activities', '', NULL);
+get_string('showallweeks', '', NULL);
+get_string('week', '', NULL);
+get_string('groups', '', NULL);
+get_string('groupmy', '', NULL);
+get_string('hideweekfromothers', '', NULL);
+get_string('showweekfromothers', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('people', '', NULL);
+get_string('listofallpeople', '', NULL);
+get_string('participants', '', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('listofallpeople', '', NULL);
+get_string('participants', '', NULL);
+get_string('showblocka', 'access', 'People');
+get_string('hideblocka', 'access', 'People');
+get_string('skipa', 'access', 'People');
+get_string('showblocka', 'access', 'People');
+get_string('hideblocka', 'access', 'People');
+get_string('activities', '', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('showblocka', 'access', 'Activities');
+get_string('hideblocka', 'access', 'Activities');
+get_string('skipa', 'access', 'Activities');
+get_string('showblocka', 'access', 'Activities');
+get_string('hideblocka', 'access', 'Activities');
+get_string('blocktitle', 'block_search_forums', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('advancedsearch', 'block_search_forums', NULL);
+get_string('search', '', NULL);
+get_string('helpprefix2', '', 'Advanced search');
+get_string('newwindow', '', NULL);
+get_string('showblocka', 'access', 'Search Forums');
+get_string('hideblocka', 'access', 'Search Forums');
+get_string('skipa', 'access', 'Search Forums');
+get_string('showblocka', 'access', 'Search Forums');
+get_string('hideblocka', 'access', 'Search Forums');
+get_string('administration', '', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('turneditingoff', '', NULL);
+get_string('settings', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('grades', '', NULL);
+get_string('outcomes', 'grades', NULL);
+get_string('groups', '', NULL);
+get_string('backup', '', NULL);
+get_string('restore', '', NULL);
+get_string('import', '', NULL);
+get_string('reset', '', NULL);
+get_string('reports', '', NULL);
+get_string('questions', 'quiz', NULL);
+get_string('files', '', NULL);
+get_string('profile', '', NULL);
+get_string('showblocka', 'access', 'Administration');
+get_string('hideblocka', 'access', 'Administration');
+get_string('skipa', 'access', 'Administration');
+get_string('showblocka', 'access', 'Administration');
+get_string('hideblocka', 'access', 'Administration');
+get_string('courses', '', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('coursecategory', '', NULL);
+get_string('fulllistofcourses', '', NULL);
+get_string('categories', '', NULL);
+get_string('showblocka', 'access', 'Course categories');
+get_string('hideblocka', 'access', 'Course categories');
+get_string('skipa', 'access', 'Course categories');
+get_string('showblocka', 'access', 'Course categories');
+get_string('hideblocka', 'access', 'Course categories');
+get_string('latestnews', '', NULL);
+get_string('addanewtopic', 'forum', NULL);
+get_string('strftimerecent', '', NULL);
+get_string('more', 'forum', NULL);
+get_string('oldertopics', 'forum', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('showblocka', 'access', 'Latest News');
+get_string('hideblocka', 'access', 'Latest News');
+get_string('skipa', 'access', 'Latest News');
+get_string('showblocka', 'access', 'Latest News');
+get_string('hideblocka', 'access', 'Latest News');
+get_string('blockname', 'block_online_users', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('periodnminutes', 'block_online_users', 5);
+get_string('day', '', NULL);
+get_string('days', '', NULL);
+get_string('hour', '', NULL);
+get_string('hours', '', NULL);
+get_string('min', '', NULL);
+get_string('mins', '', NULL);
+get_string('sec', '', NULL);
+get_string('secs', '', NULL);
+get_string('year', '', NULL);
+get_string('years', '', NULL);
+get_string('showblocka', 'access', 'Online Users');
+get_string('hideblocka', 'access', 'Online Users');
+get_string('skipa', 'access', 'Online Users');
+get_string('showblocka', 'access', 'Online Users');
+get_string('hideblocka', 'access', 'Online Users');
+get_string('recentactivity', '', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('strftimedaydatetime', 'langconfig', NULL);
+get_string('activitysince', '', 'Wednesday, 25 March 2009, 02:39 PM');
+get_string('recentactivityreport', '', NULL);
+get_string('publishanonymous', 'choice', NULL);
+get_string('publishnames', 'choice', NULL);
+get_string('publishnot', 'choice', NULL);
+get_string('publishafteranswer', 'choice', NULL);
+get_string('publishafterclose', 'choice', NULL);
+get_string('publishalways', 'choice', NULL);
+get_string('displayhorizontal', 'choice', NULL);
+get_string('displayvertical', 'choice', NULL);
+get_string('nothingnew', '', NULL);
+get_string('showblocka', 'access', 'Recent Activity');
+get_string('hideblocka', 'access', 'Recent Activity');
+get_string('skipa', 'access', 'Recent Activity');
+get_string('showblocka', 'access', 'Recent Activity');
+get_string('hideblocka', 'access', 'Recent Activity');
+get_string('feedstitle', 'block_rss_client', NULL);
+get_string('remotenewsfeed', 'block_rss_client', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('feedsconfigurenewinstance', 'block_rss_client', NULL);
+get_string('feedsconfigurenewinstance', 'block_rss_client', NULL);
+get_string('showblocka', 'access', 'Remote News Feed');
+get_string('hideblocka', 'access', 'Remote News Feed');
+get_string('skipa', 'access', 'Remote News Feed');
+get_string('showblocka', 'access', 'Remote News Feed');
+get_string('hideblocka', 'access', 'Remote News Feed');
+get_string('html', 'block_html', NULL);
+get_string('newhtmlblock', 'block_html', NULL);
+get_string('delete', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('configuration', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('showblocka', 'access', '(new HTML block)');
+get_string('hideblocka', 'access', '(new HTML block)');
+get_string('skipa', 'access', '(new HTML block)');
+get_string('showblocka', 'access', '(new HTML block)');
+get_string('hideblocka', 'access', '(new HTML block)');
+get_string('blocks', '', NULL);
+get_string('add', '', NULL);
+get_string('adminbookmarks', '', NULL);
+get_string('blockmenutitle', 'blog', NULL);
+get_string('blocktagstitle', 'blog', NULL);
+get_string('calendar', 'calendar', NULL);
+get_string('upcomingevents', 'calendar', NULL);
+get_string('pagedescription', 'block_course_summary', NULL);
+get_string('blockname', 'block_glossary_random', NULL);
+get_string('html', 'block_html', NULL);
+get_string('loancalc', 'block_loancalc', NULL);
+get_string('blockname', 'block_mentees', NULL);
+get_string('messages', 'message', NULL);
+get_string('mnet_hosts', 'block_mnet_hosts', NULL);
+get_string('formaltitle', 'block_quiz_results', NULL);
+get_string('feedstitle', 'block_rss_client', NULL);
+get_string('blockname', 'block_search', NULL);
+get_string('blockname', 'block_section_links', NULL);
+get_string('blocktagstitle', 'tag', NULL);
+get_string('skipa', 'access', '');
+get_string('showblocka', 'access', '');
+get_string('hideblocka', 'access', '');
+get_string('weeklyoutline', '', NULL);
+get_string('assignroles', 'role', NULL);
+get_string('delete', '', NULL);
+get_string('move', '', NULL);
+get_string('moveup', '', NULL);
+get_string('movedown', '', NULL);
+get_string('moveright', '', NULL);
+get_string('moveleft', '', NULL);
+get_string('update', '', NULL);
+get_string('duplicate', '', NULL);
+get_string('hide', '', NULL);
+get_string('show', '', NULL);
+get_string('clicktochange', '', NULL);
+get_string('forcedmode', '', NULL);
+get_string('groupsnone', '', NULL);
+get_string('groupsseparate', '', NULL);
+get_string('groupsvisible', '', NULL);
+get_string('modulenameplural', 'assignment', NULL);
+get_string('typeupload', 'assignment', NULL);
+get_string('typeonline', 'assignment', NULL);
+get_string('typeuploadsingle', 'assignment', NULL);
+get_string('typeoffline', 'assignment', NULL);
+get_string('resourcetypelabel', 'resource', NULL);
+get_string('resourcetypetext', 'resource', NULL);
+get_string('resourcetypehtml', 'resource', NULL);
+get_string('resourcetypefile', 'resource', NULL);
+get_string('resourcetypedirectory', 'resource', NULL);
+get_string('resourcetypeims', 'resource', NULL);
+get_string('addactivity', '', NULL);
+get_string('addresource', '', NULL);
+get_string('helpprefix2', '', 'Add a resource');
+get_string('newwindow', '', NULL);
+get_string('helpprefix2', '', 'Add an activity');
+get_string('newwindow', '', NULL);
+get_string('strftimedateshort', '', NULL);
+get_string('showonlyweek', '', 1);
+get_string('addactivity', '', NULL);
+get_string('addresource', '', NULL);
+get_string('helpprefix2', '', 'Add a resource');
+get_string('newwindow', '', NULL);
+get_string('helpprefix2', '', 'Add an activity');
+get_string('newwindow', '', NULL);
+get_string('showonlyweek', '', 2);
+get_string('addactivity', '', NULL);
+get_string('addresource', '', NULL);
+get_string('helpprefix2', '', 'Add a resource');
+get_string('newwindow', '', NULL);
+get_string('helpprefix2', '', 'Add an activity');
+get_string('newwindow', '', NULL);
+get_string('currentweek', 'access', NULL);
+get_string('showonlyweek', '', 3);
+get_string('addactivity', '', NULL);
+get_string('addresource', '', NULL);
+get_string('helpprefix2', '', 'Add a resource');
+get_string('newwindow', '', NULL);
+get_string('helpprefix2', '', 'Add an activity');
+get_string('newwindow', '', NULL);
+get_string('home', '', NULL);
+get_string('loggedinas', 'moodle', 'Admin User');
+get_string('logout', '', NULL);
+get_string('sizegb', '', NULL);
+get_string('sizemb', '', NULL);
+get_string('sizekb', '', NULL);
+get_string('sizeb', '', NULL);
+get_string('moodledocslink', '', NULL);
diff --git a/lib/simpletest/get_string_fixtures/pagelogs/course_view.php_old_get_string.log.php b/lib/simpletest/get_string_fixtures/pagelogs/course_view.php_old_get_string.log.php
new file mode 100644
index 0000000000..e6694038ae
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/pagelogs/course_view.php_old_get_string.log.php
@@ -0,0 +1,353 @@
+Admin User');
+old_get_string('logout', '', NULL);
+old_get_string('thisdirection', '', NULL);
+old_get_string('thisdirection', '', NULL);
+old_get_string('tocontent', 'access', NULL);
+old_get_string('modulenameplural', 'forum', NULL);
+old_get_string('modulenameplural', 'quiz', NULL);
+old_get_string('modulenameplural', 'choice', NULL);
+old_get_string('modulename', 'assignment', NULL);
+old_get_string('modulenameplural', 'assignment', NULL);
+old_get_string('modulename', 'choice', NULL);
+old_get_string('modulenameplural', 'choice', NULL);
+old_get_string('modulename', 'data', NULL);
+old_get_string('modulenameplural', 'data', NULL);
+old_get_string('modulename', 'forum', NULL);
+old_get_string('modulenameplural', 'forum', NULL);
+old_get_string('modulename', 'glossary', NULL);
+old_get_string('modulenameplural', 'glossary', NULL);
+old_get_string('modulename', 'label', NULL);
+old_get_string('modulenameplural', 'label', NULL);
+old_get_string('modulename', 'resource', NULL);
+old_get_string('modulenameplural', 'resource', NULL);
+old_get_string('modulename', 'scorm', NULL);
+old_get_string('modulenameplural', 'scorm', NULL);
+old_get_string('modulename', 'survey', NULL);
+old_get_string('modulenameplural', 'survey', NULL);
+old_get_string('modulename', 'lesson', NULL);
+old_get_string('modulenameplural', 'lesson', NULL);
+old_get_string('modulename', 'quiz', NULL);
+old_get_string('modulenameplural', 'quiz', NULL);
+old_get_string('modulename', 'chat', NULL);
+old_get_string('modulenameplural', 'chat', NULL);
+old_get_string('modulename', 'feedback', NULL);
+old_get_string('modulenameplural', 'feedback', NULL);
+old_get_string('editsummary', '', NULL);
+old_get_string('add', '', NULL);
+old_get_string('activities', '', NULL);
+old_get_string('showallweeks', '', NULL);
+old_get_string('week', '', NULL);
+old_get_string('groups', '', NULL);
+old_get_string('groupmy', '', NULL);
+old_get_string('hideweekfromothers', '', NULL);
+old_get_string('showweekfromothers', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('people', '', NULL);
+old_get_string('listofallpeople', '', NULL);
+old_get_string('participants', '', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('listofallpeople', '', NULL);
+old_get_string('participants', '', NULL);
+old_get_string('showblocka', 'access', 'People');
+old_get_string('hideblocka', 'access', 'People');
+old_get_string('skipa', 'access', 'People');
+old_get_string('showblocka', 'access', 'People');
+old_get_string('hideblocka', 'access', 'People');
+old_get_string('activities', '', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('showblocka', 'access', 'Activities');
+old_get_string('hideblocka', 'access', 'Activities');
+old_get_string('skipa', 'access', 'Activities');
+old_get_string('showblocka', 'access', 'Activities');
+old_get_string('hideblocka', 'access', 'Activities');
+old_get_string('blocktitle', 'block_search_forums', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('advancedsearch', 'block_search_forums', NULL);
+old_get_string('search', '', NULL);
+old_get_string('helpprefix2', '', 'Advanced search');
+old_get_string('newwindow', '', NULL);
+old_get_string('showblocka', 'access', 'Search Forums');
+old_get_string('hideblocka', 'access', 'Search Forums');
+old_get_string('skipa', 'access', 'Search Forums');
+old_get_string('showblocka', 'access', 'Search Forums');
+old_get_string('hideblocka', 'access', 'Search Forums');
+old_get_string('administration', '', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('turneditingoff', '', NULL);
+old_get_string('settings', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('grades', '', NULL);
+old_get_string('outcomes', 'grades', NULL);
+old_get_string('groups', '', NULL);
+old_get_string('backup', '', NULL);
+old_get_string('restore', '', NULL);
+old_get_string('import', '', NULL);
+old_get_string('reset', '', NULL);
+old_get_string('reports', '', NULL);
+old_get_string('questions', 'quiz', NULL);
+old_get_string('files', '', NULL);
+old_get_string('profile', '', NULL);
+old_get_string('showblocka', 'access', 'Administration');
+old_get_string('hideblocka', 'access', 'Administration');
+old_get_string('skipa', 'access', 'Administration');
+old_get_string('showblocka', 'access', 'Administration');
+old_get_string('hideblocka', 'access', 'Administration');
+old_get_string('courses', '', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('coursecategory', '', NULL);
+old_get_string('fulllistofcourses', '', NULL);
+old_get_string('categories', '', NULL);
+old_get_string('showblocka', 'access', 'Course categories');
+old_get_string('hideblocka', 'access', 'Course categories');
+old_get_string('skipa', 'access', 'Course categories');
+old_get_string('showblocka', 'access', 'Course categories');
+old_get_string('hideblocka', 'access', 'Course categories');
+old_get_string('latestnews', '', NULL);
+old_get_string('addanewtopic', 'forum', NULL);
+old_get_string('strftimerecent', '', NULL);
+old_get_string('more', 'forum', NULL);
+old_get_string('oldertopics', 'forum', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('showblocka', 'access', 'Latest News');
+old_get_string('hideblocka', 'access', 'Latest News');
+old_get_string('skipa', 'access', 'Latest News');
+old_get_string('showblocka', 'access', 'Latest News');
+old_get_string('hideblocka', 'access', 'Latest News');
+old_get_string('blockname', 'block_online_users', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('periodnminutes', 'block_online_users', 5);
+old_get_string('day', '', NULL);
+old_get_string('days', '', NULL);
+old_get_string('hour', '', NULL);
+old_get_string('hours', '', NULL);
+old_get_string('min', '', NULL);
+old_get_string('mins', '', NULL);
+old_get_string('sec', '', NULL);
+old_get_string('secs', '', NULL);
+old_get_string('year', '', NULL);
+old_get_string('years', '', NULL);
+old_get_string('showblocka', 'access', 'Online Users');
+old_get_string('hideblocka', 'access', 'Online Users');
+old_get_string('skipa', 'access', 'Online Users');
+old_get_string('showblocka', 'access', 'Online Users');
+old_get_string('hideblocka', 'access', 'Online Users');
+old_get_string('recentactivity', '', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('strftimedaydatetime', 'langconfig', NULL);
+old_get_string('activitysince', '', 'Wednesday, 25 March 2009, 02:39 PM');
+old_get_string('recentactivityreport', '', NULL);
+old_get_string('publishanonymous', 'choice', NULL);
+old_get_string('publishnames', 'choice', NULL);
+old_get_string('publishnot', 'choice', NULL);
+old_get_string('publishafteranswer', 'choice', NULL);
+old_get_string('publishafterclose', 'choice', NULL);
+old_get_string('publishalways', 'choice', NULL);
+old_get_string('displayhorizontal', 'choice', NULL);
+old_get_string('displayvertical', 'choice', NULL);
+old_get_string('nothingnew', '', NULL);
+old_get_string('showblocka', 'access', 'Recent Activity');
+old_get_string('hideblocka', 'access', 'Recent Activity');
+old_get_string('skipa', 'access', 'Recent Activity');
+old_get_string('showblocka', 'access', 'Recent Activity');
+old_get_string('hideblocka', 'access', 'Recent Activity');
+old_get_string('feedstitle', 'block_rss_client', NULL);
+old_get_string('remotenewsfeed', 'block_rss_client', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('feedsconfigurenewinstance', 'block_rss_client', NULL);
+old_get_string('feedsconfigurenewinstance', 'block_rss_client', NULL);
+old_get_string('showblocka', 'access', 'Remote News Feed');
+old_get_string('hideblocka', 'access', 'Remote News Feed');
+old_get_string('skipa', 'access', 'Remote News Feed');
+old_get_string('showblocka', 'access', 'Remote News Feed');
+old_get_string('hideblocka', 'access', 'Remote News Feed');
+old_get_string('html', 'block_html', NULL);
+old_get_string('newhtmlblock', 'block_html', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('configuration', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('showblocka', 'access', '(new HTML block)');
+old_get_string('hideblocka', 'access', '(new HTML block)');
+old_get_string('skipa', 'access', '(new HTML block)');
+old_get_string('showblocka', 'access', '(new HTML block)');
+old_get_string('hideblocka', 'access', '(new HTML block)');
+old_get_string('blocks', '', NULL);
+old_get_string('add', '', NULL);
+old_get_string('adminbookmarks', '', NULL);
+old_get_string('blockmenutitle', 'blog', NULL);
+old_get_string('blocktagstitle', 'blog', NULL);
+old_get_string('calendar', 'calendar', NULL);
+old_get_string('upcomingevents', 'calendar', NULL);
+old_get_string('pagedescription', 'block_course_summary', NULL);
+old_get_string('blockname', 'block_glossary_random', NULL);
+old_get_string('html', 'block_html', NULL);
+old_get_string('loancalc', 'block_loancalc', NULL);
+old_get_string('blockname', 'block_mentees', NULL);
+old_get_string('messages', 'message', NULL);
+old_get_string('mnet_hosts', 'block_mnet_hosts', NULL);
+old_get_string('formaltitle', 'block_quiz_results', NULL);
+old_get_string('feedstitle', 'block_rss_client', NULL);
+old_get_string('blockname', 'block_search', NULL);
+old_get_string('blockname', 'block_section_links', NULL);
+old_get_string('blocktagstitle', 'tag', NULL);
+old_get_string('skipa', 'access', '');
+old_get_string('showblocka', 'access', '');
+old_get_string('hideblocka', 'access', '');
+old_get_string('weeklyoutline', '', NULL);
+old_get_string('assignroles', 'role', NULL);
+old_get_string('delete', '', NULL);
+old_get_string('move', '', NULL);
+old_get_string('moveup', '', NULL);
+old_get_string('movedown', '', NULL);
+old_get_string('moveright', '', NULL);
+old_get_string('moveleft', '', NULL);
+old_get_string('update', '', NULL);
+old_get_string('duplicate', '', NULL);
+old_get_string('hide', '', NULL);
+old_get_string('show', '', NULL);
+old_get_string('clicktochange', '', NULL);
+old_get_string('forcedmode', '', NULL);
+old_get_string('groupsnone', '', NULL);
+old_get_string('groupsseparate', '', NULL);
+old_get_string('groupsvisible', '', NULL);
+old_get_string('modulenameplural', 'assignment', NULL);
+old_get_string('typeupload', 'assignment', NULL);
+old_get_string('typeonline', 'assignment', NULL);
+old_get_string('typeuploadsingle', 'assignment', NULL);
+old_get_string('typeoffline', 'assignment', NULL);
+old_get_string('resourcetypelabel', 'resource', NULL);
+old_get_string('resourcetypetext', 'resource', NULL);
+old_get_string('resourcetypehtml', 'resource', NULL);
+old_get_string('resourcetypefile', 'resource', NULL);
+old_get_string('resourcetypedirectory', 'resource', NULL);
+old_get_string('resourcetypeims', 'resource', NULL);
+old_get_string('addactivity', '', NULL);
+old_get_string('addresource', '', NULL);
+old_get_string('helpprefix2', '', 'Add a resource');
+old_get_string('newwindow', '', NULL);
+old_get_string('helpprefix2', '', 'Add an activity');
+old_get_string('newwindow', '', NULL);
+old_get_string('strftimedateshort', '', NULL);
+old_get_string('showonlyweek', '', 1);
+old_get_string('addactivity', '', NULL);
+old_get_string('addresource', '', NULL);
+old_get_string('helpprefix2', '', 'Add a resource');
+old_get_string('newwindow', '', NULL);
+old_get_string('helpprefix2', '', 'Add an activity');
+old_get_string('newwindow', '', NULL);
+old_get_string('showonlyweek', '', 2);
+old_get_string('addactivity', '', NULL);
+old_get_string('addresource', '', NULL);
+old_get_string('helpprefix2', '', 'Add a resource');
+old_get_string('newwindow', '', NULL);
+old_get_string('helpprefix2', '', 'Add an activity');
+old_get_string('newwindow', '', NULL);
+old_get_string('currentweek', 'access', NULL);
+old_get_string('showonlyweek', '', 3);
+old_get_string('addactivity', '', NULL);
+old_get_string('addresource', '', NULL);
+old_get_string('helpprefix2', '', 'Add a resource');
+old_get_string('newwindow', '', NULL);
+old_get_string('helpprefix2', '', 'Add an activity');
+old_get_string('newwindow', '', NULL);
+old_get_string('home', '', NULL);
+old_get_string('loggedinas', 'moodle', 'Admin User');
+old_get_string('logout', '', NULL);
+old_get_string('sizegb', '', NULL);
+old_get_string('sizemb', '', NULL);
+old_get_string('sizekb', '', NULL);
+old_get_string('sizeb', '', NULL);
+old_get_string('moodledocslink', '', NULL);
diff --git a/lib/simpletest/get_string_fixtures/pagelogs/empty.log.php b/lib/simpletest/get_string_fixtures/pagelogs/empty.log.php
new file mode 100644
index 0000000000..860a37d223
--- /dev/null
+++ b/lib/simpletest/get_string_fixtures/pagelogs/empty.log.php
@@ -0,0 +1,2 @@
+libdir . '/moodlelib.php');
+
+define('NUM_CALLS', 20000);
+define('NUM_REPITITIONS', 3);
+$TEST_LANGUAGES = array('en_utf8', 'fr_utf8', 'fr_ca_utf8', 'nonexistant');
+
+require_login();
+require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+
+$title = 'get_string performance test';
+print_header($title, $title, build_navigation($title));
+
+$installedlangs = get_list_of_languages();
+$requiredlangs = $TEST_LANGUAGES;
+array_pop($requiredlangs);
+foreach ($requiredlangs as $lang) {
+ if (!isset($installedlangs[$lang])) {
+ notify('You must install the following language packs to run these test: ' . implode(', ', $requiredlangs));
+ print_footer();
+ die;
+ }
+}
+
+time_for_loop();
+print_heading('Timing calling functions');
+time_function_call('dummy_function');
+time_function_call('simple_eval');
+time_function_call('simple_eval_with_interp');
+time_function_call('sprintf_eval');
+time_function_call('sprintf_eval_with_interp');
+time_function_call('strtr_eval');
+time_function_call('strtr_eval_with_interp');
+time_function_call('proposed');
+time_function_call('proposed_with_interp');
+time_log_file('empty.log.php');
+
+unset($COURSE->lang);
+if (isset($SESSION->lang)) {
+ $originalsessionlang = $SESSION->lang;
+} else {
+ $originalsessionlang = null;
+}
+try {
+
+ foreach ($TEST_LANGUAGES as $lang) {
+ print_heading("Language '$lang'");
+ $SESSION->lang = $lang;
+
+ time_log_file('admin_index.php_get_string.log.php');
+ time_log_file('course_view.php_get_string.log.php');
+ time_log_file('admin_index.php_old_get_string.log.php');
+ time_log_file('course_view.php_old_get_string.log.php');
+
+// test_one_case('info', '', null);
+// test_one_case('attemptquiznow', 'quiz', null);
+// $a = new stdClass;
+// $a->firstname = 'Martin';
+// $a->lastname = 'Dougiamas';
+// test_one_case('fullnamedisplay', '', $a);
+// test_one_case('stringthatdoesnotexistinanyfile', 'qtype_shortanswer', null);
+ }
+
+} catch(Exception $e) { // Did they really leave finally out of PHP?
+ if (is_null($originalsessionlang)) {
+ unset($SESSION->lang);
+ } else {
+ $SESSION->lang = $originalsessionlang;
+ }
+}
+
+print_footer();
+
+/**
+ * plays back one of the files recored by turning on the logging option in string_manager.
+ * @param $filename
+ * @return unknown_type
+ */
+function time_log_file($filename) {
+ global $CFG;
+ print_heading("Playing back calls from $filename", '', 3);
+ $fullpath = $CFG->libdir . '/simpletest/get_string_fixtures/pagelogs/' . $filename;
+ for ($i = 0; $i < NUM_REPITITIONS; ++$i) {
+ set_time_limit(60);
+ $startime = microtime(true);
+ include($fullpath);
+ $duration = microtime(true) - $startime;
+ echo 'Time for ' . $filename . ': ' . format_float($duration, 3) . "s.
\n"; + flush(); + } +} + +/** + * Repeat one call to get_string NUM_CALLS times. + * @param $string + * @param $module + * @param $a + */ +function test_one_case($string, $module, $a) { + print_heading("get_string('$string', '$module', " . print_r($a, true) . ")", '', 3); + echo 'Resulting string: ' . get_string($string, $module, $a) . "
\n"; + for ($i = 0; $i < NUM_REPITITIONS; ++$i) { + set_time_limit(60); + $startime = microtime(true); + for ($j = 0; $j < NUM_CALLS; $j++) { + get_string($string, $module, $a); + } + $duration = microtime(true) - $startime; + print_result_line($duration, 'calls to get_string'); + } +} + +function time_for_loop() { + print_heading('Timing an empty for loop'); + $startime = microtime(true); + for ($i = 0; $i < NUM_CALLS; $i++) { + } + $duration = microtime(true) - $startime; + print_result_line($duration, 'trips through an empty for loop', 'iterations per second'); +} + +function simple_eval($string, $module, $a) { + $result = ''; + $code = '$result = "Language string";'; + if (eval($code) === FALSE) { // Means parse error. + debugging('Parse error while trying to load string "'.$identifier.'" from file "' . $langfile . '".', DEBUG_DEVELOPER); + } + return $result; +} +function simple_eval_with_interp($string, $module, $a) { + $result = ''; + $code = '$result = "Language string $a->field.";'; + if (eval($code) === FALSE) { // Means parse error. + debugging('Parse error while trying to load string "'.$identifier.'" from file "' . $langfile . '".', DEBUG_DEVELOPER); + } + return $result; +} +function sprintf_eval($string, $module, $a) { + $result = ''; + $code = '$result = sprintf("Language string");'; + if (eval($code) === FALSE) { // Means parse error. + debugging('Parse error while trying to load string "'.$identifier.'" from file "' . $langfile . '".', DEBUG_DEVELOPER); + } + return $result; + } +function sprintf_eval_with_interp($string, $module, $a) { + $result = ''; + $code = '$result = sprintf("Language string $a->field.");'; + if (eval($code) === FALSE) { // Means parse error. + debugging('Parse error while trying to load string "'.$identifier.'" from file "' . $langfile . '".', DEBUG_DEVELOPER); + } + return $result; +} +function strtr_eval($string, $module, $a) { + $result = ''; + $code = '$result = strtr("Language string", "", "");'; + if (eval($code) === FALSE) { // Means parse error. + debugging('Parse error while trying to load string "'.$identifier.'" from file "' . $langfile . '".', DEBUG_DEVELOPER); + } + return $result; +} +function strtr_eval_with_interp($string, $module, $a) { + $result = ''; + $code = '$result = strtr("Language string $a->field.", "", "");'; + if (eval($code) === FALSE) { // Means parse error. + debugging('Parse error while trying to load string "'.$identifier.'" from file "' . $langfile . '".', DEBUG_DEVELOPER); + } + return $result; +} +function proposed($string, $module, $a) { + $result = 'Language string'; + if (strpos($result, '$') !== false) { + $code = '$result = strtr("' . $result . '", "", "");'; + if (eval($code) === FALSE) { // Means parse error. + debugging('Parse error while trying to load string "'.$identifier.'" from file "' . $langfile . '".', DEBUG_DEVELOPER); + } + } + return $result; +} +function proposed_with_interp($string, $module, $a) { + $result = 'Language string $a->field.'; + if (strpos($result, '$') !== false) { + $code = '$result = strtr("' . $result . '", "", "");'; + if (eval($code) === FALSE) { // Means parse error. + debugging('Parse error while trying to load string "'.$identifier.'" from file "' . $langfile . '".', DEBUG_DEVELOPER); + } + } + return $result; +} +function dummy_function($string, $module, $a) { +} +function time_function_call($functionname) { + $string = 'string'; + $module = 'module'; + $a = new stdClass; + $a->field = 'value'; + $startime = microtime(true); + for ($i = 0; $i < NUM_CALLS; $i++) { + $functionname($string, $module, $a); + } + $duration = microtime(true) - $startime; + print_result_line($duration, 'calls to ' . $functionname); +} + +function print_result_line($duration, $action1, $action2 = 'calls per second') { + echo 'Time for ' . format_float(NUM_CALLS, 0) . ' ' . $action1 . ': ' . + format_float($duration, 3) . 's which is ' . + format_float((NUM_CALLS / $duration), 0) . ' ' . $action2 . ".
\n"; + flush(); +} + +// ============================================================================= +// The rest of this file is the old implementation of get_string, with get_string +// renamed to old_get_string, so we can do comparative timings. + +/** + * fix up the optional data in get_string()/print_string() etc + * ensure possible sprintf() format characters are escaped correctly + * needs to handle arbitrary strings and objects + * @param mixed $a An object, string or number that can be used + * @return mixed the supplied parameter 'cleaned' + */ +function clean_getstring_data( $a ) { + if (is_string($a)) { + return str_replace( '%','%%',$a ); + } + elseif (is_object($a)) { + $a_vars = get_object_vars( $a ); + $new_a_vars = array(); + foreach ($a_vars as $fname => $a_var) { + $new_a_vars[$fname] = clean_getstring_data( $a_var ); + } + return (object)$new_a_vars; + } + else { + return $a; + } +} + +/** + * @return array places to look for lang strings based on the prefix to the + * module name. For example qtype_ in question/type. Used by get_string and + * help.php. + */ +function places_to_search_for_lang_strings() { + global $CFG; + + return array( + '__exceptions' => array('moodle', 'langconfig'), + 'assignment_' => array('mod/assignment/type'), + 'auth_' => array('auth'), + 'block_' => array('blocks'), + 'datafield_' => array('mod/data/field'), + 'datapreset_' => array('mod/data/preset'), + 'enrol_' => array('enrol'), + 'filter_' => array('filter'), + 'format_' => array('course/format'), + 'quiz_' => array('mod/quiz/report'), + 'qtype_' => array('question/type'), + 'qformat_' => array('question/format'), + 'report_' => array($CFG->admin.'/report', 'course/report'), + 'repository_'=>array('repository'), + 'resource_' => array('mod/resource/type'), + 'gradereport_' => array('grade/report'), + 'gradeimport_' => array('grade/import'), + 'gradeexport_' => array('grade/export'), + 'profilefield_' => array('user/profile/field'), + 'portfolio_' => array('portfolio/type'), + '' => array('mod') + ); +} + +/** + * Returns a localized string. + * + * Returns the translated string specified by $identifier as + * for $module. Uses the same format files as STphp. + * $a is an object, string or number that can be used + * within translation strings + * + * eg "hello \$a->firstname \$a->lastname" + * or "hello \$a" + * + * If you would like to directly echo the localized string use + * the function {@link print_string()} + * + * Example usage of this function involves finding the string you would + * like a local equivalent of and using its identifier and module information + * to retrive it.
+ * $string['wordforstudent'] = 'Your word for Student';
+ *
+ * So if you want to display the string 'Your word for student'
+ * in any language that supports it on your site
+ * you just need to use the identifier 'wordforstudent'
+ *
+ * $mystring = ''. get_string('wordforstudent') .'';
+or
+ *
+ * If the string you want is in another file you'd take a slightly
+ * different approach. Looking in moodle/lang/en/calendar.php you find
+ * around line 75:
+ *
+ * $string['typecourse'] = 'Course event';
+ *
+ * If you want to display the string "Course event" in any language
+ * supported you would use the identifier 'typecourse' and the module 'calendar'
+ * (because it is in the file calendar.php):
+ *
+ * $mystring = ''. get_string('typecourse', 'calendar') .'
';
+ *
+ *
+ * As a last resort, should the identifier fail to map to a string
+ * the returned string will be [[ $identifier ]]
+ *
+ * @uses $CFG
+ * @param string $identifier The key identifier for the localized string
+ * @param string $module The module where the key identifier is stored,
+ * usually expressed as the filename in the language pack without the
+ * .php on the end but can also be written as mod/forum or grade/export/xls.
+ * If none is specified then moodle.php is used.
+ * @param mixed $a An object, string or number that can be used
+ * within translation strings
+ * @param array $extralocations DEPRICATED. An array of strings with other
+ * locations to look for string files. This used to be used by plugins so
+ * they could package their language strings in the plugin folder, however,
+ * There is now a better way to achieve this. See
+ * http://docs.moodle.org/en/Development:Places_to_search_for_lang_strings.
+ * @return string The localized string.
+ */
+function old_get_string($identifier, $module='', $a=NULL, $extralocations=NULL) {
+ global $CFG;
+
+/// originally these special strings were stored in moodle.php now we are only in langconfig.php
+ $langconfigstrs = array('alphabet', 'backupnameformat', 'decsep', 'firstdayofweek', 'listsep', 'locale',
+ 'localewin', 'localewincharset', 'oldcharset', 'parentlanguage',
+ 'strftimedate', 'strftimedateshort', 'strftimedatefullshort', 'strftimedatetime',
+ 'strftimedaydate', 'strftimedaydatetime', 'strftimedayshort', 'strftimedaytime',
+ 'strftimemonthyear', 'strftimerecent', 'strftimerecentfull', 'strftimetime',
+ 'thischarset', 'thisdirection', 'thislanguage', 'strftimedatetimeshort', 'thousandssep');
+
+ $filetocheck = 'langconfig.php';
+ $defaultlang = 'en_utf8';
+ if (in_array($identifier, $langconfigstrs)) {
+ $module = 'langconfig'; //This strings are under langconfig.php for 1.6 lang packs
+ }
+
+ $lang = current_language();
+
+ if ($module == '') {
+ $module = 'moodle';
+ }
+
+/// If the "module" is actually a pathname, then automatically derive the proper module name
+ if (strpos($module, '/') !== false) {
+ $modulepath = split('/', $module);
+
+ switch ($modulepath[0]) {
+
+ case 'mod':
+ $module = $modulepath[1];
+ break;
+
+ case 'blocks':
+ case 'block':
+ $module = 'block_'.$modulepath[1];
+ break;
+
+ case 'enrol':
+ $module = 'enrol_'.$modulepath[1];
+ break;
+
+ case 'format':
+ $module = 'format_'.$modulepath[1];
+ break;
+
+ case 'grade':
+ $module = 'grade'.$modulepath[1].'_'.$modulepath[2];
+ break;
+ }
+ }
+
+/// if $a happens to have % in it, double it so sprintf() doesn't break
+ if ($a) {
+ $a = clean_getstring_data( $a );
+ }
+
+/// Define the two or three major locations of language strings for this module
+ $locations = array();
+
+ if (!empty($extralocations)) {
+ // This is an old, deprecated mechanism that predates the
+ // places_to_search_for_lang_strings mechanism that comes later in
+ // this function. So tell people who use it to change.
+ debugging('The fourth, $extralocations parameter to get_string is deprecated. ' .
+ 'See http://docs.moodle.org/en/Development:Places_to_search_for_lang_strings ' .
+ 'for a better way to package language strings with your plugin.', DEBUG_DEVELOPER);
+ if (is_array($extralocations)) {
+ $locations += $extralocations;
+ } else if (is_string($extralocations)) {
+ $locations[] = $extralocations;
+ } else {
+ debugging('Bad lang path provided');
+ }
+ }
+
+ if (!empty($CFG->running_installer) and $lang !== 'en_utf8') {
+ static $stringnames = null;
+ if (!$stringnames) {
+ $stringnames = file($CFG->dirroot.'/install/stringnames.txt');
+ $stringnames = array_map('trim', $stringnames);
+ }
+ if (array_search($identifier, $stringnames) !== false) {
+ $module = 'installer';
+ $filetocheck = 'installer.php';
+ $defaultlang = 'en_utf8';
+ $locations[] = $CFG->dirroot.'/install/lang/';
+ }
+ }
+
+ $locations[] = $CFG->dataroot.'/lang/';
+ $locations[] = $CFG->dirroot.'/lang/';
+ $locations[] = $CFG->dirroot.'/local/lang/';
+
+/// Add extra places to look for strings for particular plugin types.
+ $rules = places_to_search_for_lang_strings();
+ $exceptions = $rules['__exceptions'];
+ unset($rules['__exceptions']);
+
+ if (!in_array($module, $exceptions)) {
+ $dividerpos = strpos($module, '_');
+ if ($dividerpos === false) {
+ $type = '';
+ $plugin = $module;
+ } else {
+ $type = substr($module, 0, $dividerpos + 1);
+ $plugin = substr($module, $dividerpos + 1);
+ }
+ if (!empty($rules[$type])) {
+ foreach ($rules[$type] as $location) {
+ $locations[] = $CFG->dirroot . "/$location/$plugin/lang/";
+ }
+ }
+ }
+
+/// First check all the normal locations for the string in the current language
+ $resultstring = '';
+ foreach ($locations as $location) {
+ $locallangfile = $location.$lang.'_local'.'/'.$module.'.php'; //first, see if there's a local file
+ if (file_exists($locallangfile)) {
+ if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
+ if (eval($result) === FALSE) {
+ trigger_error('Lang error: '.$identifier.':'.$locallangfile, E_USER_NOTICE);
+ }
+ return $resultstring;
+ }
+ }
+ //if local directory not found, or particular string does not exist in local direcotry
+ $langfile = $location.$lang.'/'.$module.'.php';
+ if (file_exists($langfile)) {
+ if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
+ if (eval($result) === FALSE) {
+ trigger_error('Lang error: '.$identifier.':'.$langfile, E_USER_NOTICE);
+ }
+ return $resultstring;
+ }
+ }
+ }
+
+/// If the preferred language was English (utf8) we can abort now
+/// saving some checks beacuse it's the only "root" lang
+ if ($lang == 'en_utf8') {
+ return '[['. $identifier .']]';
+ }
+
+/// Is a parent language defined? If so, try to find this string in a parent language file
+
+ foreach ($locations as $location) {
+ $langfile = $location.$lang.'/'.$filetocheck;
+ if (file_exists($langfile)) {
+ if ($result = get_string_from_file('parentlanguage', $langfile, "\$parentlang")) {
+ if (eval($result) === FALSE) {
+ trigger_error('Lang error: '.$identifier.':'.$langfile, E_USER_NOTICE);
+ }
+ if (!empty($parentlang) and strpos($parentlang, '<') === false) { // found it!
+
+ //first, see if there's a local file for parent
+ $locallangfile = $location.$parentlang.'_local'.'/'.$module.'.php';
+ if (file_exists($locallangfile)) {
+ if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
+ if (eval($result) === FALSE) {
+ trigger_error('Lang error: '.$identifier.':'.$locallangfile, E_USER_NOTICE);
+ }
+ return $resultstring;
+ }
+ }
+
+ //if local directory not found, or particular string does not exist in local direcotry
+ $langfile = $location.$parentlang.'/'.$module.'.php';
+ if (file_exists($langfile)) {
+ if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
+ eval($result);
+ return $resultstring;
+ }
+ }
+ }
+ }
+ }
+ }
+
+/// Our only remaining option is to try English
+
+ foreach ($locations as $location) {
+ $locallangfile = $location.$defaultlang.'_local/'.$module.'.php'; //first, see if there's a local file
+ if (file_exists($locallangfile)) {
+ if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
+ eval($result);
+ return $resultstring;
+ }
+ }
+
+ //if local_en not found, or string not found in local_en
+ $langfile = $location.$defaultlang.'/'.$module.'.php';
+
+ if (file_exists($langfile)) {
+ if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
+ eval($result);
+ return $resultstring;
+ }
+ }
+ }
+
+/// And, because under 1.6 en is defined as en_utf8 child, me must try
+/// if it hasn't been queried before.
+ if ($defaultlang == 'en') {
+ $defaultlang = 'en_utf8';
+ foreach ($locations as $location) {
+ $locallangfile = $location.$defaultlang.'_local/'.$module.'.php'; //first, see if there's a local file
+ if (file_exists($locallangfile)) {
+ if ($result = get_string_from_file($identifier, $locallangfile, "\$resultstring")) {
+ eval($result);
+ return $resultstring;
+ }
+ }
+
+ //if local_en not found, or string not found in local_en
+ $langfile = $location.$defaultlang.'/'.$module.'.php';
+
+ if (file_exists($langfile)) {
+ if ($result = get_string_from_file($identifier, $langfile, "\$resultstring")) {
+ eval($result);
+ return $resultstring;
+ }
+ }
+ }
+ }
+
+ return '[['.$identifier.']]'; // Last resort
+}
+
+/**
+ * This function is only used from {@link get_string()}.
+ *
+ * @internal Only used from get_string, not meant to be public API
+ * @param string $identifier ?
+ * @param string $langfile ?
+ * @param string $destination ?
+ * @return string|false ?
+ * @staticvar array $strings Localized strings
+ * @access private
+ * @todo Finish documenting this function.
+ */
+function get_string_from_file($identifier, $langfile, $destination) {
+
+ static $strings; // Keep the strings cached in memory.
+
+ if (empty($strings[$langfile])) {
+ $string = array();
+ include ($langfile);
+ $strings[$langfile] = $string;
+ } else {
+ $string = &$strings[$langfile];
+ }
+
+ if (!isset ($string[$identifier])) {
+ return false;
+ }
+
+ return $destination .'= sprintf("'. $string[$identifier] .'");';
+}
+
+?>
\ No newline at end of file
diff --git a/lib/simpletest/testmoodlelib.php b/lib/simpletest/testmoodlelib.php
index 4300698b9a..f3bcdb779d 100644
--- a/lib/simpletest/testmoodlelib.php
+++ b/lib/simpletest/testmoodlelib.php
@@ -26,6 +26,8 @@
/**
* Unit tests for (some of) ../moodlelib.php.
*
+ * Note, tests for get_string are in the separate file testgetstring.php.
+ *
* @copyright © 2006 The Open University
* @author T.J.Hunt@open.ac.uk
* @author nicolas@moodle.com
@@ -68,12 +70,6 @@ class moodlelib_test extends UnitTestCase {
)
);
- function setUp() {
- }
-
- function tearDown() {
- }
-
function test_cleanremoteaddr() {
//IPv4
$this->assertEqual(cleanremoteaddr('1023.121.234.1'), null);
diff --git a/lib/simpletest/teststringmanager.php b/lib/simpletest/teststringmanager.php
new file mode 100644
index 0000000000..b091e7fc87
--- /dev/null
+++ b/lib/simpletest/teststringmanager.php
@@ -0,0 +1,291 @@
+libdir . '/moodlelib.php');
+
+/**
+ * Test subclass that makes all the protected methods we want to test pubic.
+ */
+class testable_string_manager extends string_manager {
+ public function __construct($dirroot, $dataroot, $admin, $runninginstaller) {
+ parent::__construct($dirroot, $dataroot, $admin, $runninginstaller);
+ }
+ public function locations_to_search($module) {
+ return parent::locations_to_search($module);
+ }
+ public function parse_module_name($module) {
+ return parent::parse_module_name($module);
+ }
+ public function get_parent_language($lang) {
+ return parent::get_parent_language($lang);
+ }
+ public function load_lang_file($langfile) {
+ return parent::load_lang_file($langfile);
+ }
+ public function get_string_from_file($identifier, $langfile, $a) {
+ return parent::get_string_from_file($identifier, $langfile, $a);
+ }
+}
+
+/*
+These tests use a shared fixture comprising language files in
+./get_string_fixtures/moodle, which the test class treats as $CFG->dirroot and
+./get_string_fixtures/moodledata, which the test class treats as $CFG->dataroot.
+
+The files we have, and their contents, are
+
+.../moodle/lang/en_utf8/moodle.php:
+$string['test'] = 'Test';
+$string['locallyoverridden'] = 'Not used';
+
+.../moodle/lang/en_utf8/test.php:
+$string['hello'] = 'Hello \'world\'!';
+$string['hellox'] = 'Hello $a!';
+$string['results'] = 'Dear $a->firstname $a->lastname,\n\nOn test \"$a->testname\" you scored $a->grade%% which earns you \$100.';
+
+.../moodle/lang/en_utf8_local/moodle.php:
+$string['locallyoverridden'] = 'Should see this';
+
+.../moodledata/lang/fr_ca_utf8/langconfig.php
+$string['parentlanguage'] = 'fr_utf8';
+
+.../moodledata/lang/es_ar_utf8/langconfig.php
+$string['parentlanguage'] = 'es_utf8';
+
+.../moodle/lang/es_ar_utf8_local/langconfig.php
+$string['parentlanguage'] = 'es_mx_utf8';
+
+.../moodledata/lang/fr_utf8/test.php
+$string['hello'] = 'Bonjour tout le monde!';
+$string['hellox'] = 'Bonjour $a!';
+
+.../moodledata/lang/fr_ca_utf8/test.php
+$string['hello'] = 'Bonjour Québec!';
+
+.../moodle/blocks/mrbs/lang/en_utf8/block_mrbs.php:
+$string['yes'] = 'Yes';
+
+.../moodle/blocks/mrbs/lang/fr_utf8/block_mrbs.php:
+$string['yes'] = 'Oui';
+
+*/
+
+class string_manager_test extends UnitTestCase {
+ protected $originallang;
+ protected $basedir;
+ protected $stringmanager;
+
+ public function setUp() {
+ global $CFG, $SESSION;
+ if (isset($SESSION->lang)) {
+ $this->originallang = $SESSION->lang;
+ } else {
+ $this->originallang = null;
+ }
+ $this->basedir = $CFG->libdir . '/simpletest/get_string_fixtures/';
+ $this->stringmanager = new testable_string_manager($this->basedir . 'moodle',
+ $this->basedir . 'moodledata', 'adminpath', false);
+ }
+
+ public function tearDown() {
+ global $SESSION;
+ if (is_null($this->originallang)) {
+ unset($SESSION->lang);
+ } else {
+ $SESSION->lang = $this->originallang;
+ }
+ }
+
+ public function test_locations_to_search_moodle() {
+ $this->assertEqual($this->stringmanager->locations_to_search('moodle'), array(
+ $this->basedir . 'moodle/lang/' => '',
+ $this->basedir . 'moodledata/lang/' => '',
+ ));
+ }
+
+ public function test_locations_to_search_langconfig() {
+ $this->assertEqual($this->stringmanager->locations_to_search('langconfig'), array(
+ $this->basedir . 'moodle/lang/' => '',
+ $this->basedir . 'moodledata/lang/' => '',
+ ));
+ }
+
+ public function test_locations_to_search_module() {
+ $this->assertEqual($this->stringmanager->locations_to_search('forum'), array(
+ $this->basedir . 'moodle/lang/' => 'forum/',
+ $this->basedir . 'moodledata/lang/' => 'forum/',
+ $this->basedir . 'moodle/mod/forum/lang/' => 'forum/',
+ ));
+ }
+
+ public function test_locations_to_search_question_type() {
+ $this->assertEqual($this->stringmanager->locations_to_search('qtype_matrix'), array(
+ $this->basedir . 'moodle/lang/' => 'qtype_matrix/',
+ $this->basedir . 'moodledata/lang/' => 'qtype_matrix/',
+ $this->basedir . 'moodle/question/type/matrix/lang/' => 'matrix/',
+ ));
+ }
+
+ public function test_locations_to_search_local() {
+ $this->assertEqual($this->stringmanager->locations_to_search('local'), array(
+ $this->basedir . 'moodle/lang/' => 'local/',
+ $this->basedir . 'moodledata/lang/' => 'local/',
+ $this->basedir . 'moodle/local/lang/' => 'local/',
+ ));
+ }
+
+ public function test_locations_to_search_report() {
+ $this->assertEqual($this->stringmanager->locations_to_search('report_super'), array(
+ $this->basedir . 'moodle/lang/' => 'report_super/',
+ $this->basedir . 'moodledata/lang/' => 'report_super/',
+ $this->basedir . 'moodle/adminpath/report/super/lang/' => 'super/',
+ $this->basedir . 'moodle/course/report/super/lang/' => 'super/',
+ ));
+ }
+
+ public function test_parse_module_name_module() {
+ $this->assertEqual($this->stringmanager->parse_module_name('forum'),
+ array('', 'forum'));
+ }
+
+ public function test_parse_module_name_grade_report() {
+ $this->assertEqual($this->stringmanager->parse_module_name('gradereport_magic'),
+ array('gradereport_', 'magic'));
+ }
+
+ public function test_get_parent_language_normal() {
+ // This is a standard case with parent language defined in
+ // moodledata/lang/fr_ca_utf8/langconfig.php. From the shared fixture:
+ //
+ //.../moodledata/lang/fr_ca_utf8/langconfig.php
+ //$string['parentlanguage'] = 'fr_utf8';
+ $this->assertEqual($this->stringmanager->get_parent_language('fr_ca_utf8'), 'fr_utf8');
+ }
+
+ public function test_get_parent_language_local_override() {
+ // This is an artificial case where the parent from moodledata/lang/es_ar_utf8 is overridden by
+ // a custom file in moodle/lang/es_ar_utf8_local. From the shared fixture:
+ //
+ //.../moodledata/lang/es_ar_utf8/langconfig.php
+ //$string['parentlanguage'] = 'es_utf8';
+ //
+ //.../moodle/lang/es_ar_utf8_local/langconfig.php
+ //$string['parentlanguage'] = 'es_mx_utf8';
+ $this->assertEqual($this->stringmanager->get_parent_language('es_ar_utf8'), 'es_mx_utf8');
+ }
+
+ public function test_load_lang_file() {
+ // From, the shared fixture:
+ //
+ //.../moodle/lang/en_utf8/test.php:
+ //$string['hello'] = 'Hello \'world\'!';
+ //$string['hellox'] = 'Hello $a!';
+ //$string['results'] = 'Dear $a->firstname $a->lastname,\n\nOn test \"$a->testname\" you scored $a->grade%% which earns you \$100.';
+ $this->assertEqual($this->stringmanager->load_lang_file($this->basedir . 'moodle/lang/en_utf8/test.php'), array(
+ 'hello' => "Hello 'world'!",
+ 'hellox' => 'Hello $a!',
+ 'results' => 'Dear $a->firstname $a->lastname,\n\nOn test \"$a->testname\" you scored $a->grade%% which earns you \$100.',
+ ));
+ }
+
+ public function test_get_string_from_file_simple() {
+ // From the shared fixture:
+ //.../moodle/lang/en_utf8/test.php:
+ //$string['hello'] = 'Hello \'world\'!';
+ // ...
+ $this->assertEqual($this->stringmanager->get_string_from_file(
+ 'hello', $this->basedir . 'moodle/lang/en_utf8/test.php', NULL),
+ "Hello 'world'!");
+ }
+
+ public function test_get_string_from_file_simple_interp_with_special_chars() {
+ // From the shared fixture:
+ //.../moodle/lang/en_utf8/test.php:
+ // ...
+ //$string['hellox'] = 'Hello $a!';
+ // ...
+ $this->assertEqual($this->stringmanager->get_string_from_file(
+ 'hellox', $this->basedir . 'moodle/lang/en_utf8/test.php', 'Fred. $100 = 100%'),
+ "Hello Fred. $100 = 100%!");
+ }
+
+ public function test_get_string_from_file_complex_interp() {
+ // From the shared fixture:
+ //.../moodle/lang/en_utf8/test.php:
+ // ...
+ //$string['results'] = 'Dear $a->firstname $a->lastname,\n\nOn test \"$a->testname\" you scored $a->grade%% which earns you \$100.';
+ $a = new stdClass;
+ $a->firstname = 'Tim';
+ $a->lastname = 'Hunt';
+ $a->testname = 'The song "\'Right\' said Fred"';
+ $a->grade = 75;
+ $this->assertEqual($this->stringmanager->get_string_from_file(
+ 'results', $this->basedir . 'moodle/lang/en_utf8/test.php', $a),
+ "Dear Tim Hunt,\n\nOn test \"The song \"'Right' said Fred\"\" you scored 75% which earns you $100.");
+ }
+
+ public function test_default_lang() {
+ global $SESSION;
+ $SESSION->lang = 'en_utf8';
+ $this->assertEqual($this->stringmanager->get_string('test'), 'Test');
+ $this->assertEqual($this->stringmanager->get_string('hello', 'test'), "Hello 'world'!");
+ $this->assertEqual($this->stringmanager->get_string('hellox', 'test', 'Tim'), 'Hello Tim!');
+ $this->assertEqual($this->stringmanager->get_string('yes', 'block_mrbs'), 'Yes');
+ $this->assertEqual($this->stringmanager->get_string('stringnotdefinedanywhere'), '[[stringnotdefinedanywhere]]');
+ }
+
+ public function test_non_default_no_parent() {
+ global $SESSION;
+ $SESSION->lang = 'fr_utf8';
+ $this->assertEqual($this->stringmanager->get_string('test'), 'Test');
+ $this->assertEqual($this->stringmanager->get_string('hello', 'test'), 'Bonjour tout le monde!');
+ $this->assertEqual($this->stringmanager->get_string('hellox', 'test', 'Jean-Paul'), 'Bonjour Jean-Paul!');
+ $this->assertEqual($this->stringmanager->get_string('yes', 'block_mrbs'), 'Oui');
+ $this->assertEqual($this->stringmanager->get_string('stringnotdefinedanywhere'), '[[stringnotdefinedanywhere]]');
+ }
+
+ public function test_lang_with_parent() {
+ global $SESSION;
+ $SESSION->lang = 'fr_ca_utf8';
+ $this->assertEqual($this->stringmanager->get_string('test'), 'Test');
+ $this->assertEqual($this->stringmanager->get_string('hello', 'test'), 'Bonjour Québec!');
+ $this->assertEqual($this->stringmanager->get_string('hellox', 'test', 'Jean-Paul'), 'Bonjour Jean-Paul!');
+ $this->assertEqual($this->stringmanager->get_string('yes', 'block_mrbs'), 'Oui');
+ $this->assertEqual($this->stringmanager->get_string('stringnotdefinedanywhere'), '[[stringnotdefinedanywhere]]');
+ }
+}
+
+?>
--
2.39.5