diff --git a/lang/en/admin.php b/lang/en/admin.php index 57a8edb5c4ad2..0f573a48b9ba1 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -227,6 +227,8 @@ $string['configdoclang'] = 'This language will be used in links for the documentation pages.'; $string['configdocroot'] = 'Defines the path to Moodle Docs for providing context-specific documentation via \'Help and documentation\' links in the footer of each page. If the field is left blank, links will not be displayed.'; $string['configdoctonewwindow'] = 'If enabled, then links to Moodle Docs will be shown in a new window.'; +$string['configduration_low'] = 'This value is too low. The minimum value is {$a}.'; +$string['configduration_high'] = 'This value is too high. The maximum value is {$a}.'; $string['configeditordictionary'] = 'This value will be used if aspell doesn\'t have dictionary for users own language.'; $string['configeditorfontlist'] = 'Select the fonts that should appear in the editor\'s drop-down list.'; $string['configemailchangeconfirmation'] = 'Require an email confirmation step when users change their email address in their profile.'; diff --git a/lib/adminlib.php b/lib/adminlib.php index a64723d9bb0d8..5a93e06759a11 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -3874,6 +3874,12 @@ class admin_setting_configduration extends admin_setting { /** @var callable|null Validation function */ protected $validatefunction = null; + /** @var int The minimum allowed value */ + protected int $minduration = 0; + + /** @var null|int The maximum allowed value */ + protected null|int $maxduration = null; + /** * Constructor * @param string $name unique ascii name, either 'mysetting' for settings that in config, @@ -3896,6 +3902,31 @@ public function __construct($name, $visiblename, $description, $defaultsetting, parent::__construct($name, $visiblename, $description, $defaultsetting); } + /** + * Set the minimum allowed value. + * This must be at least 0. + * + * @param int $duration + */ + public function set_min_duration(int $duration): void { + if ($duration < 0) { + throw new coding_exception('The minimum duration must be at least 0.'); + } + + $this->minduration = $duration; + } + + /** + * Set the maximum allowed value. + * + * A value of null will disable the maximum duration value. + * + * @param int|null $duration + */ + public function set_max_duration(?int $duration): void { + $this->maxduration = $duration; + } + /** * Sets a validate function. * @@ -3918,15 +3949,23 @@ public function set_validate_function(?callable $validatefunction = null) { * @since Moodle 3.10 */ protected function validate_setting(int $data): string { + if ($data < $this->minduration) { + return get_string( + 'configduration_low', + 'admin', + self::get_duration_text($this->minduration, get_string('numseconds', 'core', 0)) + ); + } + + if ($this->maxduration && $data > $this->maxduration) { + return get_string('configduration_high', 'admin', self::get_duration_text($this->maxduration)); + } + // If validation function is specified, call it now. if ($this->validatefunction) { return call_user_func($this->validatefunction, $data); - } else { - if ($data < 0) { - return get_string('errorsetting', 'admin'); - } - return ''; } + return ''; } /** @@ -3948,10 +3987,14 @@ protected static function get_units() { * Converts seconds to some more user friendly string. * @static * @param int $seconds + * @param null|string The value to use when the duration is empty. If not specified, a "None" value is used. * @return string */ - protected static function get_duration_text($seconds) { + protected static function get_duration_text(int $seconds, ?string $emptyvalue = null): string { if (empty($seconds)) { + if ($emptyvalue !== null) { + return $emptyvalue; + } return get_string('none'); } $data = self::parse_seconds($seconds); @@ -4043,7 +4086,15 @@ public function output_html($data, $query='') { } $inputid = $this->get_id() . 'v'; - $units = self::get_units(); + $units = array_filter(self::get_units(), function($unit): bool { + if (!$this->maxduration) { + // No duration limit. All units are valid. + return true; + } + + return $unit <= $this->maxduration; + }, ARRAY_FILTER_USE_KEY); + $defaultunit = $this->defaultunit; $context = (object) [