diff --git a/help.php b/help.php
index 86d07211e94..3c9844de816 100644
--- a/help.php
+++ b/help.php
@@ -14,8 +14,8 @@
require_once('config.php');
// Get URL parameters.
-$file = optional_param('file', '', PARAM_PATH);
-$text = optional_param('text', 'No text to display', PARAM_CLEAN);
+$file = optional_param('file', '', PARAM_PATH);
+$text = optional_param('text', 'No text to display', PARAM_CLEAN);
$module = optional_param('module', 'moodle', PARAM_ALPHAEXT);
$forcelang = optional_param('forcelang', '', PARAM_SAFEDIR);
$skiplocal = optional_param('skiplocal', 0, PARAM_INT); // shall _local help files be skipped?
@@ -30,89 +30,27 @@ ob_start();
if (!empty($file)) {
// The help to display is from a help file.
+ list($filepath, $foundlang) = string_manager::instance()->find_help_file($file, $module, $forcelang, $skiplocal);
- // Get the list of parent languages.
- if (empty($forcelang)) {
- $langs = array(current_language(), get_string('parentlanguage'), 'en_utf8'); // Fallback
- } else {
- $langs = array($forcelang, 'en_utf8');
- }
-
- if (!$skiplocal) {
- // _local language packs take precedence with both forced language and non-forced language settings
- $xlangs = array();
- foreach ($langs as $lang) {
- if (!empty($lang)) {
- $xlangs[] = $lang . '_local';
- $xlangs[] = $lang;
- }
+ if ($filepath) {
+ $helpfound = true;
+ @include($filepath); // The actual helpfile
+
+ // Now, we process some special cases.
+ if ($module == 'moodle' and ($file == 'index.html' or $file == 'mods.html')) {
+ include_help_for_each_module($file, $forcelang, $skiplocal);
}
- $langs = $xlangs;
- unset($xlangs);
- }
-
-// Define possible locations for help file similar to locations for language strings
-// Note: Always retain module directory as before
- $locations = array();
- if ($module == 'moodle') {
- $locations[$CFG->dataroot.'/lang/'] = $file;
- $locations[$CFG->dirroot.'/lang/'] = $file;
- } else {
- $modfile = $module.'/'.$file;
- $locations[$CFG->dataroot.'/lang/'] = $modfile;
- $locations[$CFG->dirroot.'/lang/'] = $modfile;
-
- $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/"] = "$plugin/$file";
- }
- }
+ if ($module == 'question' && $file == 'types.html') {
+ include_help_for_each_qtype();
}
- }
- // Work through the possible languages, starting with the most specific.
- while (!$helpfound && (list(,$lang) = each($langs)) && !empty($lang)) {
-
- while (!$helpfound && (list($locationprefix,$locationsuffix) = each($locations))) {
- $filepath = $locationprefix.$lang.'/help/'.$locationsuffix;
-
- // Now, try to include the help text from this file, if we can.
- if (file_exists_and_readable($filepath)) {
- $helpfound = true;
- @include($filepath); // The actual helpfile
-
- // Now, we process some special cases.
- $helpdir = $locationprefix.$lang.'/help';
- if ($module == 'moodle' and ($file == 'index.html' or $file == 'mods.html')) {
- include_help_for_each_module($file, $langs, $helpdir);
- }
- if ($module == 'question' and ($file == 'types.html')) {
- include_help_for_each_qtype();
- }
-
- // The remaining horrible hardcoded special cases should be delegated to modules somehow.
- if ($module == 'moodle' and ($file == 'resource/types.html')) { // RESOURCES
- include_help_for_each_resource($file, $langs, $helpdir);
- }
- if ($module == 'moodle' and ($file == 'assignment/types.html')) { // ASSIGNMENTS
- include_help_for_each_assignment_type();
- }
- }
+ // The remaining horrible hardcoded special cases should be delegated to modules somehow.
+ if ($module == 'moodle'&& $file == 'resource/types.html') { // RESOURCES
+ include_help_for_each_resource($forcelang, $skiplocal);
+ }
+ if ($module == 'moodle' && $file == 'assignment/types.html') { // ASSIGNMENTS
+ include_help_for_each_assignment_type($forcelang, $skiplocal);
}
- reset($locations);
}
} else {
// The help to display was given as an argument to this function.
@@ -121,26 +59,26 @@ if (!empty($file)) {
}
// Finish buffer
-$output=ob_get_contents();
+$output = ob_get_contents();
ob_end_clean();
// Determine title
-$title=get_string('help'); // Default is just 'Help'
-$matches=array();
+$title = get_string('help'); // Default is just 'Help'
+$matches = array();
// You can include a
tag to override the standard behaviour:
// 'Help - title contents'. Otherwise it looks for the text of the first
// heading: 'Help - heading text'. If there aren't even any headings
// you just get 'Help'
-if(preg_match('~^(.*?)(.*?)(.*)$~s',$output,$matches)) {
+if (preg_match('~^(.*?)(.*?)(.*)$~s', $output, $matches)) {
// Extract title
- $title=$title.' - '.$matches[2];
+ $title = $title.' - '.$matches[2];
// Strip title from output
- $output=$matches[1].$matches[3];
+ $output = $matches[1].$matches[3];
} else if(preg_match('~]*)?>(.*?)~s',$output,$matches)) {
// Use first heading as title (obviously leave it in output too). Strip
// any tags from inside
- $matches[2]=preg_replace('~<[^>]*>~s','',$matches[2]);
- $title=$title.' - '.$matches[2];
+ $matches[2] = preg_replace('~<[^>]*>~s','',$matches[2]);
+ $title = $title.' - '.$matches[2];
}
// use ##emoticons_html## to replace the emoticons documentation
@@ -161,27 +99,21 @@ if (!$helpfound) {
// End of page.
close_window_button();
-echo ''. get_string('helpindex') .'';
+echo '
'. get_string('helpindex') .'
';
// Offer a link to the alternative help file language
-if (($helpfound) and (((current_language() != 'en_utf8') and $lang != 'en_utf8') or ($forcelang === 'en_utf8'))) {
- $linklang = "{$CFG->wwwroot}/help.php?";
- $linklang .= !empty($module) ? "module=$module&" : '';
- $linklang .= !empty($file) ? "file=$file&" : '';
- $linklang .= !empty($skiplocal) ? "skiplocal=$skiplocal&" : '';
-
- if (empty($forcelang) or $forcelang === current_language()) {
- $nextlang = 'en_utf8';
- $nextlangname = 'English';
+$currentlang = current_language();
+if ($helpfound && ($foundlang != 'en_utf8' || ($forcelang == 'en_utf8' && current_language() != 'en_utf8'))) {
+ $url = new moodle_url();
+ if ($foundlang != 'en_utf8') {
+ $url->param('forcelang', 'en_utf8');
+ $nextlangname = get_string('english');
} else {
- $nextlang = current_language();
+ $url->param('forcelang', $currentlang);
$nextlangname = get_string('thislanguage');
}
-
- $linklang .= "forcelang=$nextlang";
- echo "
" . get_string('showthishelpinlanguage', 'moodle', $nextlangname) . '';
+ echo '' . get_string('showthishelpinlanguage', 'moodle', $nextlangname) . '
';
}
-echo '';
$CFG->docroot = ''; // We don't want a doc link here
print_footer('none');
@@ -192,13 +124,14 @@ function file_exists_and_readable($filepath) {
// Some functions for handling special cases ========================================
-function include_help_for_each_module($file, $langs, $helpdir) {
+function include_help_for_each_module($file, $forcelang, $skiplocal) {
global $CFG, $DB;
- if (!$modules = $DB->get_records('modules', array('visible'=>1))) {
- print_error('nomodules', 'debug'); // Should never happen
+ if (!$modules = $DB->get_records('modules', array('visible'=> 1))) {
+ print_error('nomodules', 'debug'); // Should never happen
}
-
+
+ // Horrible hack to show the help about grades here too.
$grade = new stdClass();
$grade->name = 'grade';
$modules[] = $grade;
@@ -210,23 +143,10 @@ function include_help_for_each_module($file, $langs, $helpdir) {
ksort($modulebyname, SORT_LOCALE_STRING);
foreach ($modulebyname as $mod) {
- foreach ($langs as $lang) {
- if (empty($lang)) {
- continue;
- }
-
- $filepath = "$helpdir/$mod->name/$file";
-
- // If that does not exist, try a fallback into the module code folder.
- if (!file_exists($filepath)) {
- $filepath = "$CFG->dirroot/mod/$mod->name/lang/$lang/help/$mod->name/$file";
- }
-
- if (file_exists_and_readable($filepath)) {
- echo '
';
- @include($filepath); // The actual helpfile
- break; // Out of loop over languages.
- }
+ list($filepath, $foundlang) = string_manager::instance()->find_help_file($file, $mod->name, $forcelang, $skiplocal);
+ if ($filepath) {
+ echo '
';
+ include($filepath);
}
}
}
@@ -253,12 +173,12 @@ function include_help_for_qtype($qtype, $localizedname) {
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 '
';
- @include($filepath); // The actual helpfile
- break; // Out of loop over languages.
- }
+ list($filepath, $foundlang) = string_manager::instance()->find_help_file('type/' . $type->name . '.html', 'resource', $forcelang, $skiplocal);
+ if ($filepath) {
+ echo '
';
+ include($filepath);
}
}
}
@@ -293,9 +204,9 @@ function include_help_for_each_assignment_type() {
$typelist = assignment_types();
foreach ($typelist as $type => $name) {
- echo ''.$name.'
';
+ echo ''.$name.'
';
echo get_string('help'.$type, 'assignment');
- echo '
';
+ echo '
';
}
}
?>
diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php
index 154f97f6db3..817f6513ee3 100644
--- a/lang/en_utf8/moodle.php
+++ b/lang/en_utf8/moodle.php
@@ -589,6 +589,7 @@ The new password was automatically generated - you might like to
link\">change your password to something easier to remember.';
$string['enable'] = 'Enable';
$string['encryptedcode'] = 'Encrypted code';
+$string['english'] = 'English';
$string['enroldate'] = 'Date range';
$string['enroldetails'] = 'Enrolment details';
$string['enrolenddate'] = 'End date';
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index 2108df744fc..1dd58ef9fb7 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -5206,64 +5206,309 @@ function get_parent_language($lang=null) {
* within translation strings
*/
function print_string($identifier, $module='', $a=NULL) {
- echo get_string($identifier, $module, $a);
+ echo string_manager::instance()->get_string($identifier, $module, $a);
}
/**
- * 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'
+ * Singleton class for managing the search for language strings.
+ *
+ * Not that performance of this class is important. If you decide to change
+ * this class, please use the lib/simpletest/getstringperformancetester.php
+ * script to make sure your changes do not cause a performance problem.
*/
-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 );
+class string_manager {
+ private $parentlangs = array('en_utf8' => NULL);
+ private $searchpathsformodule = array();
+ private $strings = array();
+ private $nonpluginfiles = array('moodle' => 1, 'langconfig' => 1);
+ private $langconfigstrs = array('alphabet' => 1, 'backupnameformat' => 1, 'decsep' => 1,
+ 'firstdayofweek' => 1, 'listsep' => 1, 'locale' => 1, 'localewin' => 1,
+ 'localewincharset' => 1, 'oldcharset' => 1, 'parentlanguage' => 1,
+ 'strftimedate' => 1, 'strftimedateshort' => 1, 'strftimedatefullshort' => 1,
+ 'strftimedatetime' => 1, 'strftimedaydate' => 1, 'strftimedaydatetime' => 1,
+ 'strftimedayshort' => 1, 'strftimedaytime' => 1, 'strftimemonthyear' => 1,
+ 'strftimerecent' => 1, 'strftimerecentfull' => 1, 'strftimetime' => 1,
+ 'thischarset' => 1, 'thisdirection' => 1, 'thislanguage' => 1,
+ 'strftimedatetimeshort' => 1, 'thousandssep' => 1);
+ private $searchplacesbyplugintype;
+ private $dirroot;
+ private $corelocations;
+ private $installstrings = NULL;
+ private $parentlangfile = 'langconfig.php';
+ private $logtofile = false;
+ private static $singletoninstance = NULL;
+
+ public static function instance() {
+ if (is_null(self::$singletoninstance)) {
+ global $CFG;
+ self::$singletoninstance = new self($CFG->dirroot, $CFG->dataroot, $CFG->admin, isset($CFG->running_installer));
+ // Uncomment the followign line to log every call to get_string
+ // to a file in $CFG->dataroot/temp/getstringlog/...
+ // self::$singletoninstance->start_logging();
}
- return (object)$new_a_vars;
+ return self::$singletoninstance;
}
- else {
- return $a;
+
+ // Some of our arrays need $CFG.
+ protected function __construct($dirroot, $dataroot, $admin, $runninginstaller) {
+ $this->dirroot = $dirroot;
+ $this->corelocations = array(
+ $dirroot . '/lang/' => '',
+ $dataroot . '/lang/' => '',
+ );
+ $this->searchplacesbyplugintype = array(
+ '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($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')
+ );
+ if ($runninginstaller) {
+ $stringnames = file($dirroot . '/install/stringnames.txt');
+ $this->installstrings = array_map('trim', $stringnames);
+ $this->parentlangfile = 'installer.php';
+ }
}
-}
-/**
- * @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;
+ 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);
- 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')
- );
+ switch ($modulepath[0]) {
+ case 'mod':
+ return $modulepath[1];
+ case 'blocks':
+ case 'block':
+ return 'block_'.$modulepath[1];
+ case 'enrol':
+ return 'enrol_'.$modulepath[1];
+ case 'format':
+ return 'format_'.$modulepath[1];
+ case 'grade':
+ return 'grade'.$modulepath[1].'_'.$modulepath[2];
+ default:
+ return $module;
+ }
+ }
+
+ 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;
+ }
+
+ 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);
+ }
+
+ 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.
+ 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 = array_merge($locations, $extralocations);
+ } else if (is_string($extralocations)) {
+ $locations[] = $extralocations;
+ } else {
+ debugging('Bad lang path provided');
+ }
+ return $locations;
+ }
+
+ protected function get_parent_language($lang) {
+ if (array_key_exists($lang, $this->parentlangs)) {
+ return $this->parentlangs[$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;
+ }
+
+ protected function load_lang_file($langfile) {
+ if (isset($this->strings[$langfile])) {
+ return $this->strings[$langfile];
+ }
+ $string = array();
+ if (file_exists($langfile)) {
+ include($langfile);
+ }
+ $this->strings[$langfile] = $string;
+ return $string;
+ }
+
+ protected function get_string_from_file($identifier, $langfile, $a) {
+ $string = &$this->load_lang_file($langfile);
+ if (!isset($string[$identifier])) {
+ return false;
+ }
+ $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;
+ }
+
+ 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;
+ }
+ }
+
+ $locations = $this->locations_to_search($module);
+
+ if ($skiplocal) {
+ $localsuffices = array('');
+ } else {
+ $localsuffices = array('_local', '');
+ }
+
+ 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('', '');
+ }
+
+ private function start_logging() {
+ $this->logtofile = true;
+ }
+
+ 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");
+ }
+
+ public function get_string($identifier, $module='', $a=NULL, $extralocations=NULL) {
+ if ($this->logtofile) {
+ $this->log_get_string_call($identifier, $module, $a);
+ }
+
+ /// Preprocess the arguments.
+ if ($module == '') {
+ $module = 'moodle';
+ }
+
+ if ($module == 'moodle' && array_key_exists($identifier, $this->langconfigstrs)) {
+ $module = 'langconfig';
+ }
+
+ if (strpos($module, '/') !== false) {
+ $module = $this->fix_deprecated_module_name($module);
+ }
+
+ $locations = $this->locations_to_search($module);
+
+ 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.
+ }
}
/**
@@ -5311,7 +5556,6 @@ or
* 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
@@ -5327,264 +5571,7 @@ or
* @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) {
- $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] .'");';
+ 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 00000000000..a82aff4f06b
--- /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 00000000000..0ce399a5c1a
--- /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 00000000000..39a50cf8fc8
--- /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 00000000000..e0795062818
--- /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 00000000000..b3d35a3f623
--- /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 00000000000..b1d732a41e8
--- /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 00000000000..6767ae8ee19
--- /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 00000000000..a0156df76f8
--- /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 00000000000..2d728dd9456
--- /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 00000000000..0a0fbd1d6d2
--- /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 00000000000..e73150d3a00
--- /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 00000000000..ba1eb44a159
--- /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 00000000000..c5f812d8466
--- /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 00000000000..e6694038ae5
--- /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 00000000000..860a37d2232
--- /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.
+ * If you open moodle/lang/en/moodle.php and look near line 1031
+ * you will find a string to prompt a user for their word for student
+ *
+ * $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 4300698b9af..f3bcdb779d3 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 00000000000..b091e7fc879
--- /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]]');
+ }
+}
+
+?>