From 59ec5b1851c63fe9e5aa5d550e0e710dd577a620 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Thu, 15 Oct 2020 23:31:31 +0100 Subject: [PATCH 1/2] MDL-69788 lang: fallback to all translations if misconfigured. If given translation list contains only invalid entries, fallback to returning the complete list of available language translations. --- lib/classes/string_manager_standard.php | 15 +++++++++++++-- lib/tests/string_manager_standard_test.php | 7 +++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/classes/string_manager_standard.php b/lib/classes/string_manager_standard.php index 1a3f36400c8..140ba650925 100644 --- a/lib/classes/string_manager_standard.php +++ b/lib/classes/string_manager_standard.php @@ -533,7 +533,13 @@ class core_string_manager_standard implements core_string_manager { $languages[$langcode] = !empty($this->transaliases[$langcode]) ? $this->transaliases[$langcode] : $langname; } } - return $languages; + + // If there are no valid enabled translations, then return all languages. + if (!empty($languages)) { + return $languages; + } else { + return $cachedlist; + } } // Get all languages available in system. @@ -584,7 +590,12 @@ class core_string_manager_standard implements core_string_manager { } } - return $languages; + // If there are no valid enabled translations, then return all languages. + if (!empty($languages)) { + return $languages; + } else { + return $cachedlist; + } } /** diff --git a/lib/tests/string_manager_standard_test.php b/lib/tests/string_manager_standard_test.php index aa73a0e6a9d..c167707e874 100644 --- a/lib/tests/string_manager_standard_test.php +++ b/lib/tests/string_manager_standard_test.php @@ -140,6 +140,13 @@ class core_string_manager_standard_testcase extends advanced_testcase { $this->assertEquals(['en' => 'En'], $stringman->get_list_of_translations()); + // Set invalid config, ensure original list is returned. + set_config('langlist', 'xx'); + $this->assertEquals(['en' => 'English ‎(en)‎'], get_string_manager(true)->get_list_of_translations()); + + set_config('langlist', 'xx,en|En'); + $this->assertEquals(['en' => 'En'], get_string_manager(true)->get_list_of_translations()); + set_config('langlist', ''); get_string_manager(true); } From 7337934484cc7ad810ad5025692ee174abe7e489 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Fri, 16 Oct 2020 08:59:53 +0100 Subject: [PATCH 2/2] MDL-69788 admin: validate language menu configuration. --- admin/tests/behat/language_settings.feature | 34 +++++++++++++++++++++ lang/en/error.php | 1 + lib/adminlib.php | 30 ++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 admin/tests/behat/language_settings.feature diff --git a/admin/tests/behat/language_settings.feature b/admin/tests/behat/language_settings.feature new file mode 100644 index 00000000000..6d00ebecdd6 --- /dev/null +++ b/admin/tests/behat/language_settings.feature @@ -0,0 +1,34 @@ +@core @core_admin +Feature: Configure language settings for the site + In order to configure language settings for the site + As an admin + I want to set language settings relevant to my site users + + Scenario: Set languages on language menu + Given I log in as "admin" + And I navigate to "Language > Language settings" in site administration + When I set the field "Languages on language menu" to "en" + And I press "Save changes" + Then I should not see "Invalid language code" + + Scenario: Reset languages on language menu + Given I log in as "admin" + And I navigate to "Language > Language settings" in site administration + When I set the field "Languages on language menu" to "" + And I press "Save changes" + Then I should not see "Invalid language code" + + Scenario Outline: Set languages on language menu with invalid language + Given I log in as "admin" + And I navigate to "Language > Language settings" in site administration + When I set the field "Languages on language menu" to "" + And I press "Save changes" + Then I should see "Invalid language code: " + Examples: + | fieldvalue | invalidlang | + | xx | xx | + | xx\|Bad | xx | + | en,qq | qq | + | en,qq\|Bad | qq | + | en$$ | en$$ | + | en$$\|Bad | en$$ | diff --git a/lang/en/error.php b/lang/en/error.php index f8d5b9b2e06..ef16de31ef4 100644 --- a/lang/en/error.php +++ b/lang/en/error.php @@ -341,6 +341,7 @@ $string['invalidgroupid'] = 'Incorrect group ID specified'; $string['invalidipformat'] = 'Invalid IP address format'; $string['invaliditemid'] = 'Incorrect item ID'; $string['invalidkey'] = 'Incorrect key'; +$string['invalidlanguagecode'] = 'Invalid language code: {$a}'; $string['invalidlegacy'] = 'Incorrect legacy role definition for type: {$a}'; $string['invalidmd5'] = 'The check variable was wrong - try again'; $string['invalidmode'] = 'Invalid mode ({$a})'; diff --git a/lib/adminlib.php b/lib/adminlib.php index bfdd78767a6..4b46fb57659 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -4933,6 +4933,36 @@ class admin_setting_langlist extends admin_setting_configtext { parent::__construct('langlist', get_string('langlist', 'admin'), get_string('configlanglist', 'admin'), '', PARAM_NOTAGS); } + /** + * Validate that each language identifier exists on the site + * + * @param string $data + * @return bool|string True if validation successful, otherwise error string + */ + public function validate($data) { + $parentcheck = parent::validate($data); + if ($parentcheck !== true) { + return $parentcheck; + } + + if ($data === '') { + return true; + } + + // Normalize language identifiers. + $langcodes = array_map('trim', explode(',', $data)); + foreach ($langcodes as $langcode) { + // If the langcode contains optional alias, split it out. + [$langcode, ] = preg_split('/\s*\|\s*/', $langcode, 2); + + if (!get_string_manager()->translation_exists($langcode)) { + return get_string('invalidlanguagecode', 'error', $langcode); + } + } + + return true; + } + /** * Save the new setting *