Skip to content

Commit

Permalink
MDL-80945 quiz: Add SEB options to override settings
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Kotlyar committed Aug 5, 2024
1 parent 8a6e856 commit ce09e52
Show file tree
Hide file tree
Showing 16 changed files with 410 additions and 17 deletions.
44 changes: 37 additions & 7 deletions mod/quiz/accessrule/seb/classes/seb_quiz_settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use lang_string;
use moodle_exception;
use moodle_url;
use mod_quiz\quiz_settings;

defined('MOODLE_INTERNAL') || die();

Expand Down Expand Up @@ -196,11 +197,39 @@ protected static function define_properties(): array {
* @return false|\quizaccess_seb\seb_quiz_settings
*/
public static function get_by_quiz_id(int $quizid) {
if ($data = self::get_quiz_settings_cache()->get($quizid)) {
return new static(0, $data);
global $USER;
// Skip cache if quiz has overrides for user.
if (!($hasoverrides = quiz_has_user_overrides($quizid))) {
if ($data = self::get_quiz_settings_cache()->get($quizid)) {
return new static(0, $data);
}
}

return self::get_record(['quizid' => $quizid]);
$quiz = self::get_record(['quizid' => $quizid]);

// Overwrite settings from override manager if available.
if ($hasoverrides) {
// Create blank seb_quiz_settings instance if none exists.
if (!$quiz) {
$record = new \stdClass();
$record->quizid = $quizid;
$record->cmid = get_coursemodule_from_instance('quiz', $quizid)->id;
$quiz = $quiz ?: new self(0, $record);
}

$settings = quiz_settings::create_for_cmid($quiz->get('cmid'), $USER->id)->get_quiz();
// If overriding enabled, overwrite seb settings.
if (isset($settings->enableseboverride) && !!$settings->enableseboverride) {
$prefix = 'seb_';
foreach (array_keys(self::properties_definition()) as $key) {
if (isset($settings->{$prefix.$key})) {
$quiz->set($key, $settings->{$prefix.$key});
}
}
}
}

return $quiz;
}

/**
Expand All @@ -210,10 +239,11 @@ public static function get_by_quiz_id(int $quizid) {
* @return string|null
*/
public static function get_config_by_quiz_id(int $quizid): ?string {
$config = self::get_config_cache()->get($quizid);

if ($config !== false) {
return $config;
// Skip cache if quiz has overrides for user.
if (quiz_has_user_overrides($quizid)) {
if ($config = self::get_config_cache()->get($quizid) !== false) {
return $config;
}
}

$config = null;
Expand Down
38 changes: 34 additions & 4 deletions mod/quiz/accessrule/seb/classes/settings_provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,17 @@ protected static function add_seb_header_element(\mod_quiz_mod_form $quizform, \
* @param \MoodleQuickForm $mform the wrapped MoodleQuickForm.
*/
protected static function add_seb_usage_options(\mod_quiz_mod_form $quizform, \MoodleQuickForm $mform) {
$options = self::get_requiresafeexambrowser_options($quizform->get_context());
$element = $mform->createElement(
'select',
'seb_requiresafeexambrowser',
get_string('seb_requiresafeexambrowser', 'quizaccess_seb'),
self::get_requiresafeexambrowser_options($quizform->get_context())
$options
);

self::insert_element($quizform, $mform, $element);
self::set_type($quizform, $mform, 'seb_requiresafeexambrowser', PARAM_INT);
self::set_default($quizform, $mform, 'seb_requiresafeexambrowser', self::USE_SEB_NO);
self::set_default($quizform, $mform, 'seb_requiresafeexambrowser', array_key_first($options));
self::add_help_button($quizform, $mform, 'seb_requiresafeexambrowser');

if (self::is_conflicting_permissions($quizform->get_context())) {
Expand Down Expand Up @@ -549,6 +550,11 @@ public static function is_conflicting_permissions(\context $context) {
return true;
}

if (!self::can_unrequire($context) &&
$settings->get('requiresafeexambrowser') == self::USE_SEB_NO) {
return true;
}

return false;
}

Expand All @@ -559,7 +565,11 @@ public static function is_conflicting_permissions(\context $context) {
* @return array
*/
public static function get_requiresafeexambrowser_options(\context $context): array {
$options[self::USE_SEB_NO] = get_string('no');
$options = [];

if (self::can_unrequire($context) || self::is_conflicting_permissions($context)) {
$options[self::USE_SEB_NO] = get_string('no');
}

if (self::can_configure_manually($context) || self::is_conflicting_permissions($context)) {
$options[self::USE_SEB_CONFIG_MANUALLY] = get_string('seb_use_manually', 'quizaccess_seb');
Expand All @@ -584,7 +594,7 @@ public static function get_requiresafeexambrowser_options(\context $context): ar
* Returns a list of templates.
* @return array
*/
protected static function get_template_options(): array {
public static function get_template_options(): array {
$templates = [];
$records = template::get_records(['enabled' => 1], 'name');
if ($records) {
Expand Down Expand Up @@ -785,6 +795,26 @@ public static function can_change_seb_allowedbrowserexamkeys(\context $context):
return has_capability('quizaccess/seb:manage_seb_allowedbrowserexamkeys', $context);
}

/**
* Check if the current user can unrequire SEB from quiz.
*
* @param \context $context Context to check access in.
* @return bool
*/
public static function can_unrequire(\context $context): bool {
return has_capability('quizaccess/seb:manage_seb_unrequiresafeexambrowser', $context);
}

/**
* Check if the current user can unrequire SEB from quiz in the override menu.
*
* @param \context $context Context to check access in.
* @return bool
*/
public static function can_override_unrequire(\context $context): bool {
return has_capability('quizaccess/seb:override_seb_unrequiresafeexambrowser', $context);
}

/**
* Check if the current user can config SEB manually.
*
Expand Down
16 changes: 16 additions & 0 deletions mod/quiz/accessrule/seb/db/access.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@
'editingteacher' => CAP_ALLOW
]
],
'quizaccess/seb:manage_seb_unrequiresafeexambrowser' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'manager' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
],
],
'quizaccess/seb:override_seb_unrequiresafeexambrowser' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'manager' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
],
],
'quizaccess/seb:manage_seb_templateid' => [
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
Expand Down
2 changes: 2 additions & 0 deletions mod/quiz/accessrule/seb/lang/en/quizaccess_seb.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@
$string['seb:manage_seb_regexallowed'] = 'Change SEB quiz setting: Regex expressions allowed';
$string['seb:manage_seb_regexblocked'] = 'Change SEB quiz setting: Regex expressions blocked';
$string['seb:manage_seb_requiresafeexambrowser'] = 'Change SEB quiz setting: Require Safe Exam Browser';
$string['seb:manage_seb_unrequiresafeexambrowser'] = 'Change SEB quiz setting: Do not require Safe Exam Browser';
$string['seb:override_seb_unrequiresafeexambrowser'] = 'Override SEB quiz setting: Do not require Safe Exam Browser';
$string['seb:manage_seb_showkeyboardlayout'] = 'Change SEB quiz setting: Show keyboard layout';
$string['seb:manage_seb_showreloadbutton'] = 'Change SEB quiz setting: Show reload button';
$string['seb:manage_seb_showsebtaskbar'] = 'Change SEB quiz setting: Show task bar';
Expand Down
9 changes: 9 additions & 0 deletions mod/quiz/accessrule/seb/tests/settings_provider_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,15 @@ public function test_get_requiresafeexambrowser_options($settingcapability): voi

$options = settings_provider::get_requiresafeexambrowser_options($this->context);

$this->assertCount(1, $options);
$this->assertFalse(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
$this->assertFalse(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
$this->assertFalse(array_key_exists(settings_provider::USE_SEB_UPLOAD_CONFIG, $options));
$this->assertTrue(array_key_exists(settings_provider::USE_SEB_CLIENT_CONFIG, $options));
$this->assertFalse(array_key_exists(settings_provider::USE_SEB_NO, $options));

assign_capability('quizaccess/seb:manage_seb_unrequiresafeexambrowser', CAP_ALLOW, $this->roleid, $this->context->id);
$options = settings_provider::get_requiresafeexambrowser_options($this->context);
$this->assertCount(2, $options);
$this->assertFalse(array_key_exists(settings_provider::USE_SEB_CONFIG_MANUALLY, $options));
$this->assertFalse(array_key_exists(settings_provider::USE_SEB_TEMPLATE, $options));
Expand Down
2 changes: 1 addition & 1 deletion mod/quiz/accessrule/seb/version.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2024042200;
$plugin->version = 2024073101;
$plugin->requires = 2024041600;
$plugin->component = 'quizaccess_seb';
$plugin->maturity = MATURITY_STABLE;
2 changes: 1 addition & 1 deletion mod/quiz/backup/moodle2/backup_quiz_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ protected function define_structure() {

$override = new backup_nested_element('override', ['id'], [
'userid', 'groupid', 'timeopen', 'timeclose',
'timelimit', 'attempts', 'password']);
'timelimit', 'attempts', 'password', 'sebdata']);

$grades = new backup_nested_element('grades');

Expand Down
1 change: 1 addition & 0 deletions mod/quiz/classes/external/save_overrides.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public static function execute_parameters(): external_function_parameters {
'timelimit' => new external_value(PARAM_INT, 'Quiz override time limit', VALUE_DEFAULT, null),
'attempts' => new external_value(PARAM_INT, 'Quiz override attempt count', VALUE_DEFAULT, null),
'password' => new external_value(PARAM_TEXT, 'Quiz override password', VALUE_DEFAULT, null),
'sebdata' => new external_value(PARAM_TEXT, 'Quiz override SEB settings', VALUE_DEFAULT, null),
]);

return new external_function_parameters([
Expand Down
Loading

0 comments on commit ce09e52

Please sign in to comment.