From 7409013e79984103675d7a3afd669cef35ee9d00 Mon Sep 17 00:00:00 2001 From: tjhunt Date: Fri, 2 Oct 2009 11:30:11 +0000 Subject: [PATCH] moodlelib: MDL-19764 change get_list_of_countries so admins can more easily control the list. * New admin setting $CFG->allcountrycodes - on Location page. * Same rules used to translate country names as any other string. * With unit tests. --- admin/settings/location.php | 8 +- lang/en_utf8/admin.php | 2 + lib/adminlib.php | 26 ++++++ lib/moodlelib.php | 92 +++++++++++------- lib/simpletest/teststringmanager.php | 134 +++++++++++++++++++++++++++ 5 files changed, 221 insertions(+), 41 deletions(-) diff --git a/admin/settings/location.php b/admin/settings/location.php index 1b91a210f2..60890f4ade 100644 --- a/admin/settings/location.php +++ b/admin/settings/location.php @@ -9,17 +9,15 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page $temp->add(new admin_setting_configselect('timezone', get_string('timezone','admin'), get_string('configtimezone', 'admin'), 99, $options)); $options[99] = get_string('timezonenotforced', 'admin'); $temp->add(new admin_setting_configselect('forcetimezone', get_string('forcetimezone', 'admin'), get_string('helpforcetimezone', 'admin'), 99, $options)); - $options = get_list_of_countries(); - $options[0] = get_string('choose') .'...'; - $temp->add(new admin_setting_configselect('country', get_string('country', 'admin'), get_string('configcountry', 'admin'), 0, $options)); + $temp->add(new admin_settings_country_select('country', get_string('country', 'admin'), get_string('configcountry', 'admin'), 0)); $temp->add(new admin_setting_heading('iplookup', get_string('iplookup', 'admin'), get_string('iplookupinfo', 'admin'))); $temp->add(new admin_setting_configfile('geoipfile', get_string('geoipfile', 'admin'), get_string('configgeoipfile', 'admin', $CFG->dataroot.'/geoip/'), $CFG->dataroot.'/geoip/GeoLiteCity.dat')); $temp->add(new admin_setting_configtext('googlemapkey', get_string('googlemapkey', 'admin'), get_string('configgooglemapkey', 'admin', $CFG->wwwroot), '')); - $ADMIN->add('location', $temp); - + $temp->add(new admin_setting_configtext('allcountrycodes', get_string('allcountrycodes', 'admin'), get_string('configallcountrycodes', 'admin'), '', '/^(?:\w+(?:,\w+)*)?$/')); + $ADMIN->add('location', $temp); $ADMIN->add('location', new admin_externalpage('timezoneimport', get_string('updatetimezones', 'admin'), "$CFG->wwwroot/$CFG->admin/timezoneimport.php")); } // end of speedup diff --git a/lang/en_utf8/admin.php b/lang/en_utf8/admin.php index d5057b854c..09c1fefa95 100644 --- a/lang/en_utf8/admin.php +++ b/lang/en_utf8/admin.php @@ -5,6 +5,7 @@ $string['adminseesall'] = 'Admins See All'; $string['adminseesallevents'] = 'Administrators see all events'; $string['adminseesownevents'] = 'Administrators are just like other users'; $string['advancedfeatures'] = 'Advanced features'; +$string['allcountrycodes'] = 'All country codes'; $string['allowcategorythemes'] = 'Allow category themes'; $string['allowcoursethemes'] = 'Allow course themes'; $string['allowdeletes'] = 'Allow deletes'; @@ -75,6 +76,7 @@ $string['commonsettings'] = 'Common settings'; $string['componentinstalled'] = 'Component Installed'; $string['computedfromlogs'] = 'Computed from logs since $a.'; $string['confeditorhidebuttons'] = 'Select the buttons that should be hidden in the HTML editor.'; +$string['configallcountrycodes'] = 'This is the list of countries that may be selected in various places, for example in a user\'s profile. If blank (the default) the list in countries.php in the standard English language pack is used. That is the list from ISO 3166-1. Otherwise, you can specify a comma-separated list of codes, for example \'GB,FR,ES\'. If you add new, non-standard codes here, you will need to add them to countries.php in your language pack.'; $string['configallowassign'] = 'You can allow people who have the roles on the left side to assign some of the column roles to other people'; $string['configallowcategorythemes'] = 'If you enable this, then themes can be set at the category level. This will affect all child categories and courses unless they have specifically set their own theme. WARNING: Enabling category themes may affect performance.'; $string['configallowcoursethemes'] = 'If you enable this, then courses will be allowed to set their own themes. Course themes override all other theme choices (site, user, or session themes)'; diff --git a/lib/adminlib.php b/lib/adminlib.php index f7c0b297fb..239d71c31d 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -3483,6 +3483,32 @@ class admin_setting_langlist extends admin_setting_configtext { } } +/** + * Selection of one of the recognised countries using the list + * returned by {@link get_list_of_countries()}. + * + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class admin_settings_country_select extends admin_setting_configselect { + public function __construct($name, $visiblename, $description, $defaultsetting) { + parent::__construct($name, $visiblename, $description, $defaultsetting, NULL); + } + + /** + * Lazy-load the available choices for the select box + */ + public function load_choices() { + global $CFG; + if (is_array($this->choices)) { + return true; + } + $this->choices = array_merge( + array('0' => get_string('choosedots')), + get_list_of_countries()); + return true; + } +} + /** * Course category selection * diff --git a/lib/moodlelib.php b/lib/moodlelib.php index e281cad95c..210b71cf2b 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -5720,6 +5720,7 @@ class string_manager { private $parentlangfile = 'langconfig.php'; private $logtofile = false; private $showstringsource = false; + private $allcountrycodes = NULL; private static $singletoninstance = NULL; /** @@ -6088,7 +6089,11 @@ class string_manager { } } - return '[[' . $identifier . ']]'; // Last resort. + return $this->missing_string($identifier); // Last resort. + } + + protected function missing_string($identifier) { + return '[[' . $identifier . ']]'; } /** @@ -6102,6 +6107,54 @@ class string_manager { // The bracketing makes that clear. return '{' . $string . ' ' . $module . '/' . $identifier . '}'; } + + protected function get_list_of_country_codes() { + if (!is_null($this->allcountrycodes)) { + return $this->allcountrycodes; + } + + global $CFG; + if (!empty($CFG->allcountrycodes)) { + $this->allcountrycodes = explode(',', $CFG->allcountrycodes); + } else { + $this->allcountrycodes = array_keys( + $this->load_lang_file($this->dirroot . '/lang/en_utf8/countries.php')); + } + return $this->allcountrycodes; + } + + /** + * Returns a list of country names in the current language + * @return array two-letter country code => translated name. + */ + public function get_list_of_countries() { + $locations = $this->locations_to_search('countries'); + + // Now load all the translated country names. We load the files in + // the order most specific to lease specific. + $rawcountries = array(); + 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 . '/countries.php'; + $rawcountries = array_merge($this->load_lang_file($file), $rawcountries); + } + } + } + + // Now trim the array to just contain the codes $codes. + $codes = $this->get_list_of_country_codes(); + $countries = array(); + foreach ($codes as $code) { + if (array_key_exists($code, $rawcountries)) { + $countries[$code] = $rawcountries[$code]; + } else { + $countries[$code] = $this->missing_string($code); + } + } + + return $countries; + } } /** @@ -6336,43 +6389,10 @@ function get_list_of_charsets() { /** * Returns a list of country names in the current language - * - * @global object - * @global object - * @return array + * @return array two-letter country code => translated name. */ function get_list_of_countries() { - global $CFG, $USER; - - $lang = current_language(); - - if (!file_exists($CFG->dirroot .'/lang/'. $lang .'/countries.php') && - !file_exists($CFG->dataroot.'/lang/'. $lang .'/countries.php')) { - if ($parentlang = get_parent_language()) { - if (file_exists($CFG->dirroot .'/lang/'. $parentlang .'/countries.php') || - file_exists($CFG->dataroot.'/lang/'. $parentlang .'/countries.php')) { - $lang = $parentlang; - } else { - $lang = 'en_utf8'; // countries.php must exist in this pack - } - } else { - $lang = 'en_utf8'; // countries.php must exist in this pack - } - } - - if (file_exists($CFG->dataroot .'/lang/'. $lang .'/countries.php')) { - include($CFG->dataroot .'/lang/'. $lang .'/countries.php'); - } else if (file_exists($CFG->dirroot .'/lang/'. $lang .'/countries.php')) { - include($CFG->dirroot .'/lang/'. $lang .'/countries.php'); - } - - if (!empty($string)) { - uasort($string, 'strcoll'); - } else { - print_error('countriesphpempty', '', '', $lang); - } - - return $string; + return string_manager::instance()->get_list_of_countries(); } /** diff --git a/lib/simpletest/teststringmanager.php b/lib/simpletest/teststringmanager.php index f5658d4913..9f8301e40a 100644 --- a/lib/simpletest/teststringmanager.php +++ b/lib/simpletest/teststringmanager.php @@ -337,6 +337,140 @@ class string_manager_test extends UnitTestCase { $this->assertEqual($this->stringmanager->get_string('stringnotdefinedanywhere'), '[[stringnotdefinedanywhere]]'); } + public function test_get_list_of_countries_en_utf8() { + global $CFG, $SESSION; + // Setup fixture. + $countriesen = array( + 'AU' => 'Australia', + 'GB' => 'United Kingdom', + ); + $this->write_lang_file('moodle/lang/en_utf8/countries.php', $countriesen); + + $oldlist = $CFG->allcountrycodes; + $CFG->allcountrycodes = ''; + $SESSION->lang = 'en_utf8'; + + // Exercise SUT. + $this->assertEqual($this->stringmanager->get_list_of_countries(), + $countriesen); + + // Tear down. + $CFG->allcountrycodes = $oldlist; + } + + public function test_get_list_of_countries_specific_list() { + global $CFG, $SESSION; + // Setup fixture. + $countriesen = array( + 'AU' => 'Australia', + 'GB' => 'United Kingdom', + ); + $this->write_lang_file('moodle/lang/en_utf8/countries.php', $countriesen); + + $oldlist = $CFG->allcountrycodes; + $CFG->allcountrycodes = 'AU'; + $SESSION->lang = 'en_utf8'; + + // Exercise SUT. + $this->assertEqual($this->stringmanager->get_list_of_countries(), + array('AU' => $this->stringmanager->get_string('AU', 'countries'))); + + // Tear down. + $CFG->allcountrycodes = $oldlist; + } + + public function test_get_list_of_countries_fr_utf8() { + global $CFG, $SESSION; + // Setup fixture. + $countriesen = array( + 'AU' => 'Australia', + 'GB' => 'United Kingdom', + ); + $this->write_lang_file('moodle/lang/en_utf8/countries.php', $countriesen); + + $countriesfr = array( + 'AU' => 'Australie', + 'FR' => 'France', + 'GB' => 'Royaume-Uni', + ); + $this->write_lang_file('moodledata/lang/fr_utf8/countries.php', $countriesfr); + + $oldlist = $CFG->allcountrycodes; + $CFG->allcountrycodes = ''; + $SESSION->lang = 'fr_utf8'; + + // Exercise SUT. + unset($countriesfr['FR']); + $this->assertEqual($this->stringmanager->get_list_of_countries(), + $countriesfr); + + // Tear down. + $CFG->allcountrycodes = $oldlist; + } + + public function test_get_list_of_countries_specific_list_fr() { + global $CFG, $SESSION; + // Setup fixture. + $countriesen = array( + 'AU' => 'Australia', + 'GB' => 'United Kingdom', + ); + $this->write_lang_file('moodle/lang/en_utf8/countries.php', $countriesen); + + $countriesfr = array( + 'AU' => 'Australie', + 'FR' => 'France', + 'GB' => 'Royaume-Uni', + ); + $this->write_lang_file('moodledata/lang/fr_utf8/countries.php', $countriesfr); + + $oldlist = $CFG->allcountrycodes; + $CFG->allcountrycodes = 'FR'; + $SESSION->lang = 'fr_utf8'; + + // Exercise SUT. + unset($countriesfr['FR']); + $this->assertEqual($this->stringmanager->get_list_of_countries(), + array('FR' => 'France')); + // Tear down. + $CFG->allcountrycodes = $oldlist; + } + + public function test_get_list_of_countries_lang_with_parent_local_override() { + global $CFG, $SESSION; + + // Setup fixture. + $this->write_lang_file('moodledata/lang/fr_ca_utf8/langconfig.php', array( + 'parentlanguage' => 'fr_utf8', + )); + + $countriesen = array( + 'AU' => 'Australia', + 'GB' => 'United Kingdom', + ); + $this->write_lang_file('moodle/lang/en_utf8/countries.php', $countriesen); + + $countriesfr = array( + 'AU' => 'Australie', + 'GB' => 'Royaume-Uni', + ); + $this->write_lang_file('moodledata/lang/fr_utf8/countries.php', $countriesfr); + + $this->write_lang_file('moodle/lang/fr_ca_utf8_local/countries.php', array( + 'AU' => 'Aussie', + )); + + $oldlist = $CFG->allcountrycodes; + $CFG->allcountrycodes = ''; + $SESSION->lang = 'fr_ca_utf8'; + + // Exercise SUT. + $this->assertEqual($this->stringmanager->get_list_of_countries(), + array('AU' => 'Aussie', 'GB' => 'Royaume-Uni')); + + // Tear down. + $CFG->allcountrycodes = $oldlist; + } } ?> -- 2.39.5