Skip to content

Commit

Permalink
WR437567: Add SEB options to override settings.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Kotlyar committed Aug 1, 2024
1 parent 1a33da6 commit ca807a8
Show file tree
Hide file tree
Showing 14 changed files with 399 additions and 19 deletions.
1 change: 1 addition & 0 deletions mod/quiz/accessrule/seb/classes/seb_access_manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

use context_module;
use mod_quiz\quiz_settings;
use mod_quiz\local\override_manager;

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

Expand Down
34 changes: 27 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,29 @@ 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;
if (!quiz_has_user_overrides($quizid)) {
if ($data = self::get_quiz_settings_cache()->get($quizid)) {
return new static(0, $data);
}
}

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

if (!empty($quiz)) {
// Overwrite settings from override manager if enabled.
$settings = quiz_settings::create_for_cmid($quiz->get('cmid'), $USER->id)->get_quiz();
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 self::get_record(['quizid' => $quizid]);
return $quiz;
}

/**
Expand All @@ -210,10 +229,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
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;
166 changes: 166 additions & 0 deletions mod/quiz/classes/form/edit_override_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use moodle_url;
use moodleform;
use stdClass;
use quizaccess_seb\{seb_quiz_settings,settings_provider};

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

Expand Down Expand Up @@ -59,6 +60,9 @@ class edit_override_form extends moodleform {
/** @var int overrideid, if provided. */
protected int $overrideid;

/** @var array array of seb settings to override. */
protected array $sebdata;

/**
* Constructor.
*
Expand All @@ -80,6 +84,7 @@ public function __construct(moodle_url $submiturl,
$this->groupid = empty($override->groupid) ? 0 : $override->groupid;
$this->userid = empty($override->userid) ? 0 : $override->userid;
$this->overrideid = $override->id ?? 0;
$this->sebdata = empty($override->sebdata) ? [] : unserialize($override->sebdata);

parent::__construct($submiturl);
}
Expand Down Expand Up @@ -224,6 +229,9 @@ protected function definition() {
$mform->addHelpButton('attempts', 'attempts', 'quiz');
$mform->setDefault('attempts', $this->quiz->attempts);

// SEB override settings.
$this->display_seb_settings($mform);

// Submit buttons.
$mform->addElement('submit', 'resetbutton',
get_string('reverttodefaults', 'quiz'));
Expand All @@ -239,6 +247,164 @@ protected function definition() {
$mform->closeHeaderBefore('buttonbar');
}

/**
* Add SEB settings to the form.
*
* @param \MoodleQuickForm $mform
* @return void
*/
protected function display_seb_settings($mform) {
$mform->addElement('header', 'seb', get_string('seb', 'quizaccess_seb'));

$mform->addElement('checkbox', 'enableseboverride', 'Enable SEB override');
$mform->setDefault('enableseboverride', $this->sebdata['enableseboverride'] ?? false);

// "Require the use of Safe Exam Browser".
if (settings_provider::can_override_unrequire($this->context)) {
$requireseboptions[settings_provider::USE_SEB_NO] = get_string('no');
}

if (settings_provider::can_configure_manually($this->context) || self::is_conflicting_permissions($this->context)) {
$requireseboptions[settings_provider::USE_SEB_CONFIG_MANUALLY] = get_string('seb_use_manually', 'quizaccess_seb');
}

if (settings_provider::can_use_seb_template($this->context) || self::is_conflicting_permissions($this->context)) {
if (!empty(settings_provider::get_template_options())) {
$requireseboptions[settings_provider::USE_SEB_TEMPLATE] = get_string('seb_use_template', 'quizaccess_seb');
}
}

$requireseboptions[settings_provider::USE_SEB_CLIENT_CONFIG] = get_string('seb_use_client', 'quizaccess_seb');

$mform->addElement(
'select',
'seb_requiresafeexambrowser',
get_string('seb_requiresafeexambrowser', 'quizaccess_seb'),
$requireseboptions
);

$mform->setType('seb_requiresafeexambrowser', PARAM_INT);
$mform->setDefault('seb_requiresafeexambrowser', $this->sebdata['seb_requiresafeexambrowser'] ?? $this->quiz->seb_requiresafeexambrowser ?? 0);
$mform->addHelpButton('seb_requiresafeexambrowser', 'seb_requiresafeexambrowser', 'quizaccess_seb');
$mform->disabledIf('seb_requiresafeexambrowser', 'enableseboverride');

if (settings_provider::is_conflicting_permissions($this->context)) {
$mform->freeze('seb_requiresafeexambrowser');
}

// "Safe Exam Browser config template".
if (settings_provider::can_use_seb_template($this->context) || settings_provider::is_conflicting_permissions($this->context)) {
$element = $mform->addElement(
'select',
'seb_templateid',
get_string('seb_templateid', 'quizaccess_seb'),
settings_provider::get_template_options()
);
} else {
$element = $mform->addElement('hidden', 'seb_templateid');
}

$mform->setType('seb_templateid', PARAM_INT);
$mform->setDefault('seb_templateid', $this->sebdata['seb_templateid'] ?? $this->quiz->seb_templateid ?? 0);
$mform->addHelpButton('seb_templateid', 'seb_templateid', 'quizaccess_seb');
$mform->disabledIf('seb_templateid', 'enableseboverride');

if (settings_provider::is_conflicting_permissions($this->context)) {
$mform->freeze('seb_templateid');
}

// "Show Safe Exam browser download button".
if (settings_provider::can_change_seb_showsebdownloadlink($this->context)) {
$mform->addElement('selectyesno',
'seb_showsebdownloadlink',
get_string('seb_showsebdownloadlink', 'quizaccess_seb')
);

$mform->setType('seb_showsebdownloadlink', PARAM_BOOL);
$mform->setDefault('seb_showsebdownloadlink', $this->sebdata['seb_showsebdownloadlink'] ?? $this->quiz->seb_showsebdownloadlink ?? 1);
$mform->addHelpButton('seb_showsebdownloadlink', 'seb_showsebdownloadlink', 'quizaccess_seb');
$mform->disabledIf('seb_showsebdownloadlink', 'enableseboverride');
}

// Manual config elements.
$defaults = settings_provider::get_seb_config_element_defaults();
$types = settings_provider::get_seb_config_element_types();

foreach (settings_provider::get_seb_config_elements() as $name => $type) {
if (!settings_provider::can_manage_seb_config_setting($name, $this->context)) {
$type = 'hidden';
}

$mform->addElement($type, $name, get_string($name, 'quizaccess_seb'));

$mform->addHelpButton($name, $name, 'quizaccess_seb');
$mform->setType('seb_showsebdownloadlink', PARAM_BOOL);
$mform->setDefault('seb_showsebdownloadlink', $this->sebdata['seb_showsebdownloadlink'] ?? $this->quiz->seb_showsebdownloadlink ?? 1);
$mform->disabledIf($name, 'enableseboverride');

if (isset($defaults[$name])) {
$mform->setDefault($name, $this->sebdata[$name] ?? $this->quiz->{$name} ?? $defaults[$name]);
}

if (isset($types[$name])) {
$mform->setType($name, $types[$name]);
}
}

if (settings_provider::can_change_seb_allowedbrowserexamkeys($this->context)) {
$mform->addElement('textarea',
'seb_allowedbrowserexamkeys',
get_string('seb_allowedbrowserexamkeys', 'quizaccess_seb')
);

$mform->setType('seb_allowedbrowserexamkeys', PARAM_RAW);
$mform->setDefault('seb_allowedbrowserexamkeys', $this->sebdata['seb_allowedbrowserexamkeys'] ?? $this->quiz->seb_allowedbrowserexamkeys ?? '');
$mform->addHelpButton('seb_allowedbrowserexamkeys', 'seb_allowedbrowserexamkeys', 'quizaccess_seb');
$mform->disabledIf('seb_allowedbrowserexamkeys', 'enableseboverride');
}

// Hideifs.
foreach (settings_provider::get_quiz_hideifs() as $elname => $rules) {
if ($mform->elementExists($elname)) {
foreach ($rules as $hideif) {
$mform->hideIf(
$hideif->get_element(),
$hideif->get_dependantname(),
$hideif->get_condition(),
$hideif->get_dependantvalue()
);
}
}
}

// Lock elements.
if (settings_provider::is_conflicting_permissions($this->context)) {
// Freeze common quiz settings.
$mform->addElement('enableseboverride');
$mform->freeze('seb_requiresafeexambrowser');
$mform->freeze('seb_templateid');
$mform->freeze('seb_showsebdownloadlink');
$mform->freeze('seb_allowedbrowserexamkeys');

$quizsettings = seb_quiz_settings::get_by_quiz_id((int) $this->quiz->id);

// Remove template ID if not using template for this quiz.
if (empty($quizsettings) || $quizsettings->get('requiresafeexambrowser') != settings_provider::USE_SEB_TEMPLATE) {
$mform->removeElement('seb_templateid');
}

// Freeze all SEB specific settings.
foreach (settings_provider::get_seb_config_elements() as $element => $type) {
if ($mform->elementExists($element)) {
$mform->freeze($element);
}
}
}

// Close header before next field.
$mform->closeHeaderBefore('resetbutton');
}

/**
* Get a user's name and identity ready to display.
*
Expand Down
Loading

0 comments on commit ca807a8

Please sign in to comment.