MDL-55197 filter_multilang: handle 'en' as parent lang better

This commit is contained in:
Tim Hunt 2019-05-17 15:35:54 +01:00
parent 587c0772e6
commit 41bf80a69d
2 changed files with 43 additions and 22 deletions

View File

@ -40,6 +40,8 @@ defined('MOODLE_INTERNAL') || die();
/**
* Implementation of the Moodle filter API for the Multi-lang filter.
*
* @copyright Gaetan Frenoy <gaetan@frenoy.net>
* @copyright 2004 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -81,38 +83,52 @@ class filter_multilang extends moodle_text_filter {
* @return string the replacement string (one of the possible translations).
*/
protected function process_match(array $langblock): string {
$mylang = current_language();
static $parentcache;
if (!isset($parentcache)) {
$parentcache = array();
}
if (!array_key_exists($mylang, $parentcache)) {
$parentlang = get_parent_language($mylang);
$parentcache[$mylang] = $parentlang;
} else {
$parentlang = $parentcache[$mylang];
}
$searchtosplit = '/<(?:lang|span)[^>]+lang="([a-zA-Z0-9_-]+)"[^>]*>(.*?)<\/(?:lang|span)>/is';
if (!preg_match_all($searchtosplit, $langblock[0], $rawlanglist)) {
//skip malformed blocks
// Skip malformed blocks.
return $langblock[0];
}
$langlist = array();
foreach ($rawlanglist[1] as $index=>$lang) {
$lang = str_replace('-','_',strtolower($lang)); // normalize languages
foreach ($rawlanglist[1] as $index => $lang) {
$lang = str_replace('-', '_', strtolower($lang)); // Normalize languages.
$langlist[$lang] = $rawlanglist[2][$index];
}
if (array_key_exists($mylang, $langlist)) {
return $langlist[$mylang];
} else if (array_key_exists($parentlang, $langlist)) {
return $langlist[$parentlang];
} else {
$first = array_shift($langlist);
return $first;
// Follow the stream of parent languages.
$lang = current_language();
do {
if (isset($langlist[$lang])) {
return $langlist[$lang];
}
} while ($lang = $this->get_parent_lang($lang));
// If we don't find a match, default to the first provided translation.
return array_shift($langlist);
}
/**
* Puts some caching around get_parent_language().
*
* Also handle parent == 'en' in a way that works better for us.
*
* @param string $lang a Moodle language code, e.g. 'fr'.
* @return string the parent language.
*/
protected function get_parent_lang(string $lang): string {
static $parentcache;
if (!isset($parentcache)) {
$parentcache = ['en' => ''];
}
if (!isset($parentcache[$lang])) {
$parentcache[$lang] = get_parent_language($lang);
// The standard get_parent_language method returns '' for parent == 'en'.
// That is less helpful for us, so change it back.
if ($parentcache[$lang] === '') {
$parentcache[$lang] = 'en';
}
}
return $parentcache[$lang];
}
}

View File

@ -116,6 +116,11 @@ class filter_multilang_filter_testcase extends advanced_testcase {
<span lang="fr_ca" class="multilang">Québécois</span>',
'fr', ['fr_ca' => 'fr'],
],
'Fallback to parent when child not present when parent is en' => [
'English',
'<span lang="de" class="multilang">Deutsch</span><span lang="en" class="multilang">English</span>',
'en_us',
],
];
}