Skip to content

Commit

Permalink
MDL-69772 admin: Better validation for the allcountrycodes setting
Browse files Browse the repository at this point in the history
The patch introduces a new admin_setting fiela type that can be used for
specifying comma separated list of countries. The field has inbuilt
validation so that only valid country codes can be inserted.
  • Loading branch information
mudrd8mz committed Oct 1, 2020
1 parent d75844e commit 271b94f
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 2 deletions.
4 changes: 2 additions & 2 deletions admin/settings/location.php
Expand Up @@ -49,8 +49,8 @@
$temp->add(new admin_setting_configtext('googlemapkey3', new lang_string('googlemapkey3', 'core_admin'),
new lang_string('googlemapkey3_help', 'core_admin'), '', PARAM_RAW, 60));

$temp->add(new admin_setting_configtext('allcountrycodes', new lang_string('allcountrycodes', 'core_admin'),
new lang_string('configallcountrycodes', 'core_admin'), '', '/^(?:\w+(?:,\w+)*)?$/'));
$temp->add(new admin_setting_countrycodes('allcountrycodes', new lang_string('allcountrycodes', 'core_admin'),
new lang_string('configallcountrycodes', 'core_admin')));
}

$ADMIN->add('location', $temp);
Expand Down
29 changes: 29 additions & 0 deletions admin/tests/behat/invalid_allcountrycodes.feature
@@ -0,0 +1,29 @@
@core @core_admin
Feature: Administrator is warned and when trying to set invalid allcountrycodes value.
In order to avoid misconfiguration of the country selector fields
As an admin
I want to be warned when I try to set an invalid country code in the allcountrycodes field

Scenario: Attempting to set allcountrycodes field with valid country codes
Given I log in as "admin"
And I navigate to "Location > Location settings" in site administration
When I set the following administration settings values:
| All country codes | CZ,BE,GB,ES |
Then I should not see "Invalid country code"

Scenario: Attempting to set allcountrycodes field with invalid country code
Given I log in as "admin"
And I navigate to "Location > Location settings" in site administration
When I set the following administration settings values:
| All country codes | CZ,BE,FOOBAR,GB,ES |
Then I should see "Invalid country code: FOOBAR"

Scenario: Attempting to unset allcountrycodes field
Given I log in as "admin"
And I navigate to "Location > Location settings" in site administration
And I set the following administration settings values:
| All country codes | CZ,BE,GB,ES |
And I navigate to "Location > Location settings" in site administration
When I set the following administration settings values:
| All country codes | |
Then I should not see "Invalid country code"
1 change: 1 addition & 0 deletions lang/en/error.php
Expand Up @@ -324,6 +324,7 @@
$string['invalidcourseformat'] = 'Invalid course format';
$string['invalidcoursemodule'] = 'Invalid course module ID';
$string['invalidcoursenameshort'] = 'Invalid short course name';
$string['invalidcountrycode'] = 'Invalid country code: {$a}';
$string['invaliddata'] = 'Data submitted is invalid';
$string['invaliddatarootpermissions'] = 'Invalid permissions detected when trying to create a directory. Turn debugging on for further details.';
$string['invaliddevicetype'] = 'Invalid device type';
Expand Down
60 changes: 60 additions & 0 deletions lib/adminlib.php
Expand Up @@ -4901,6 +4901,66 @@ public function write_setting($data) {
}


/**
* Allows to specify comma separated list of known country codes.
*
* This is a simple subclass of the plain input text field with added validation so that all the codes are actually
* known codes.
*
* @package core
* @category admin
* @copyright 2020 David Mudrák <david@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class admin_setting_countrycodes extends admin_setting_configtext {

/**
* Construct the instance of the setting.
*
* @param string $name Name of the admin setting such as 'allcountrycodes' or 'myplugin/countries'.
* @param lang_string|string $visiblename Language string with the field label text.
* @param lang_string|string $description Language string with the field description text.
* @param string $defaultsetting Default value of the setting.
* @param int $size Input text field size.
*/
public function __construct($name, $visiblename, $description, $defaultsetting = '', $size = null) {
parent::__construct($name, $visiblename, $description, $defaultsetting, '/^(?:\w+(?:,\w+)*)?$/', $size);
}

/**
* Validate the setting value before storing it.
*
* The value is first validated through custom regex so that it is a word consisting of letters, numbers or underscore; or
* a comma separated list of such words.
*
* @param string $data Value inserted into the setting field.
* @return bool|string True if the value is OK, error string otherwise.
*/
public function validate($data) {

$parentcheck = parent::validate($data);

if ($parentcheck !== true) {
return $parentcheck;
}

if ($data === '') {
return true;
}

$allcountries = get_string_manager()->get_list_of_countries(true);

foreach (explode(',', $data) as $code) {
if (!isset($allcountries[$code])) {
return get_string('invalidcountrycode', 'core_error', $code);
}
}

return true;
}
}


/**
* Selection of one of the recognised countries using the list
* returned by {@link get_list_of_countries()}.
Expand Down

0 comments on commit 271b94f

Please sign in to comment.