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 23, 2024
1 parent 6cd5507 commit 5f3e62b
Show file tree
Hide file tree
Showing 15 changed files with 456 additions and 200 deletions.
139 changes: 55 additions & 84 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 @@ -190,125 +191,95 @@ protected static function define_properties(): array {
/**
* Return an instance by quiz id.
*
* This method gets data from cache before doing any DB calls.
*
* @param int $quizid Quiz id.
* @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;

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

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

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

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

/**
* Return cached SEB config represented as a string by quiz ID.
* Get override record if there is for the current user.
*
* @param int $quizid Quiz id.
* @return string|null
* @return \stdClass|false
*/
public static function get_config_by_quiz_id(int $quizid): ?string {
$config = self::get_config_cache()->get($quizid);
protected function get_override() {
global $DB, $USER;
$userid = $USER->id;
$quizid = $this->get('quizid');

if ($config !== false) {
return $config;
$override = $DB->get_record('quiz_overrides', ['quiz' => $quizid, 'userid' => $userid]);

if (!$override) {
$quiz = $DB->get_record('quiz', ['id' => $quizid]);
$groupings = groups_get_user_groups($quiz->course, $userid);

if (!empty($groupings[0])) {
list($extra, $params) = $DB->get_in_or_equal(array_values($groupings[0]));
$select = "groupid $extra AND quiz = ?";
$params[] = $quiz->id;
$override = $DB->get_records_select('quiz_overrides', $select, $params);
}
}

return $override;
}

/**
* Return SEB config represented as a string by quiz ID.
*
* @param int $quizid Quiz id.
* @return string|null
*/
public static function get_config_by_quiz_id(int $quizid): ?string {
$config = null;
if ($settings = self::get_by_quiz_id($quizid)) {
$config = $settings->get_config();
self::get_config_cache()->set($quizid, $config);
}

return $config;
}

/**
* Return cached SEB config key by quiz ID.
* Return SEB config key by quiz ID.
*
* @param int $quizid Quiz id.
* @return string|null
*/
public static function get_config_key_by_quiz_id(int $quizid): ?string {
$configkey = self::get_config_key_cache()->get($quizid);

if ($configkey !== false) {
return $configkey;
}

$configkey = null;
if ($settings = self::get_by_quiz_id($quizid)) {
$configkey = $settings->get_config_key();
self::get_config_key_cache()->set($quizid, $configkey);
}

return $configkey;
}

/**
* Return SEB config key cache instance.
*
* @return \cache_application
*/
private static function get_config_key_cache(): \cache_application {
return \cache::make('quizaccess_seb', 'configkey');
}

/**
* Return SEB config cache instance.
*
* @return \cache_application
*/
private static function get_config_cache(): \cache_application {
return \cache::make('quizaccess_seb', 'config');
}

/**
* Return quiz settings cache object,
*
* @return \cache_application
*/
private static function get_quiz_settings_cache(): \cache_application {
return \cache::make('quizaccess_seb', 'quizsettings');
}

/**
* Adds the new record to the cache.
*/
protected function after_create() {
$this->after_save();
}

/**
* Updates the cache record.
*
* @param bool $result
*/
protected function after_update($result) {
$this->after_save();
}

/**
* Helper method to execute common stuff after create and update.
*/
private function after_save() {
self::get_quiz_settings_cache()->set($this->get('quizid'), $this->to_record());
self::get_config_cache()->set($this->get('quizid'), $this->config);
self::get_config_key_cache()->set($this->get('quizid'), $this->configkey);
}

/**
* Removes unnecessary stuff from db.
*/
protected function before_delete() {
$key = $this->get('quizid');
self::get_quiz_settings_cache()->delete($key);
self::get_config_cache()->delete($key);
self::get_config_key_cache()->delete($key);
}

/**
* Validate the browser exam keys string.
*
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_donotrequire($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_donotrequire($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 not require SEB for a quiz.
*
* @param \context $context Context to check access in.
* @return bool
*/
public static function can_donotrequire(\context $context): bool {
return has_capability('quizaccess/seb:manage_seb_donotrequiresafeexambrowser', $context);
}

/**
* Check if the current user can not require SEB for a quiz in the override menu.
*
* @param \context $context Context to check access in.
* @return bool
*/
public static function can_override_donotrequire(\context $context): bool {
return has_capability('quizaccess/seb:override_seb_donotrequiresafeexambrowser', $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_donotrequiresafeexambrowser' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'manager' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
],
],
'quizaccess/seb:override_seb_donotrequiresafeexambrowser' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => [
'manager' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
],
],
'quizaccess/seb:manage_seb_templateid' => [
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
Expand Down
47 changes: 0 additions & 47 deletions mod/quiz/accessrule/seb/db/caches.php

This file was deleted.

5 changes: 2 additions & 3 deletions mod/quiz/accessrule/seb/lang/en/quizaccess_seb.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
$string['addtemplate'] = 'Add new template';
$string['allowedbrowserkeysdistinct'] = 'The keys must all be different.';
$string['allowedbrowserkeyssyntax'] = 'A key should be a 64-character hex string.';
$string['cachedef_config'] = 'SEB config cache';
$string['cachedef_configkey'] = 'SEB config key cache';
$string['cachedef_quizsettings'] = 'SEB quiz settings cache';
$string['cantdelete'] = 'The template can\'t be deleted as it has been used for one or more quizzes.';
$string['cantedit'] = 'The template can\'t be edited as it has been used for one or more quizzes.';
$string['checkingaccess'] = 'Checking access to Safe Exam Browser...';
Expand Down Expand Up @@ -106,6 +103,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_donotrequiresafeexambrowser'] = 'Change SEB quiz setting: Do not require Safe Exam Browser';
$string['seb:override_seb_donotrequiresafeexambrowser'] = '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
Loading

0 comments on commit 5f3e62b

Please sign in to comment.