diff --git a/mod/quiz/accessmanager.php b/mod/quiz/accessmanager.php index f1db4ba549b..df1c42fe9f1 100644 --- a/mod/quiz/accessmanager.php +++ b/mod/quiz/accessmanager.php @@ -15,549 +15,11 @@ // along with Moodle. If not, see . /** - * Classes to enforce the various access rules that can apply to a quiz. + * File only retained to prevent fatal errors in code that tries to require/include this. * - * @package mod_quiz - * @copyright 2009 Tim Hunt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @todo MDL-76612 delete this file as part of Moodle 4.6 development. + * @deprecated This file is no longer required in Moodle 4.2+. */ - - defined('MOODLE_INTERNAL') || die(); -use mod_quiz\question\display_options; - -/** - * This class keeps track of the various access rules that apply to a particular - * quiz, with convinient methods for seeing whether access is allowed. - * - * @copyright 2009 Tim Hunt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 2.2 - */ -class quiz_access_manager { - /** @var quiz the quiz settings object. */ - protected $quizobj; - /** @var int the time to be considered as 'now'. */ - protected $timenow; - /** @var array of quiz_access_rule_base. */ - protected $rules = array(); - - /** - * Create an instance for a particular quiz. - * @param object $quizobj An instance of the class quiz from attemptlib.php. - * The quiz we will be controlling access to. - * @param int $timenow The time to use as 'now'. - * @param bool $canignoretimelimits Whether this user is exempt from time - * limits (has_capability('mod/quiz:ignoretimelimits', ...)). - */ - public function __construct($quizobj, $timenow, $canignoretimelimits) { - $this->quizobj = $quizobj; - $this->timenow = $timenow; - $this->rules = $this->make_rules($quizobj, $timenow, $canignoretimelimits); - } - - /** - * Make all the rules relevant to a particular quiz. - * @param quiz $quizobj information about the quiz in question. - * @param int $timenow the time that should be considered as 'now'. - * @param bool $canignoretimelimits whether the current user is exempt from - * time limits by the mod/quiz:ignoretimelimits capability. - * @return array of {@link quiz_access_rule_base}s. - */ - protected function make_rules($quizobj, $timenow, $canignoretimelimits) { - - $rules = array(); - foreach (self::get_rule_classes() as $ruleclass) { - $rule = $ruleclass::make($quizobj, $timenow, $canignoretimelimits); - if ($rule) { - $rules[$ruleclass] = $rule; - } - } - - $superceededrules = array(); - foreach ($rules as $rule) { - $superceededrules += $rule->get_superceded_rules(); - } - - foreach ($superceededrules as $superceededrule) { - unset($rules['quizaccess_' . $superceededrule]); - } - - return $rules; - } - - /** - * @return array of all the installed rule class names. - */ - protected static function get_rule_classes() { - return core_component::get_plugin_list_with_class('quizaccess', '', 'rule.php'); - } - - /** - * Add any form fields that the access rules require to the settings form. - * - * Note that the standard plugins do not use this mechanism, becuase all their - * settings are stored in the quiz table. - * - * @param mod_quiz_mod_form $quizform the quiz settings form that is being built. - * @param MoodleQuickForm $mform the wrapped MoodleQuickForm. - */ - public static function add_settings_form_fields( - mod_quiz_mod_form $quizform, MoodleQuickForm $mform) { - - foreach (self::get_rule_classes() as $rule) { - $rule::add_settings_form_fields($quizform, $mform); - } - } - - /** - * The the options for the Browser security settings menu. - * - * @return array key => lang string. - */ - public static function get_browser_security_choices() { - $options = array('-' => get_string('none', 'quiz')); - foreach (self::get_rule_classes() as $rule) { - $options += $rule::get_browser_security_choices(); - } - return $options; - } - - /** - * Validate the data from any form fields added using {@link add_settings_form_fields()}. - * @param array $errors the errors found so far. - * @param array $data the submitted form data. - * @param array $files information about any uploaded files. - * @param mod_quiz_mod_form $quizform the quiz form object. - * @return array $errors the updated $errors array. - */ - public static function validate_settings_form_fields(array $errors, - array $data, $files, mod_quiz_mod_form $quizform) { - - foreach (self::get_rule_classes() as $rule) { - $errors = $rule::validate_settings_form_fields($errors, $data, $files, $quizform); - } - - return $errors; - } - - /** - * Save any submitted settings when the quiz settings form is submitted. - * - * Note that the standard plugins do not use this mechanism because their - * settings are stored in the quiz table. - * - * @param object $quiz the data from the quiz form, including $quiz->id - * which is the id of the quiz being saved. - */ - public static function save_settings($quiz) { - - foreach (self::get_rule_classes() as $rule) { - $rule::save_settings($quiz); - } - } - - /** - * Delete any rule-specific settings when the quiz is deleted. - * - * Note that the standard plugins do not use this mechanism because their - * settings are stored in the quiz table. - * - * @param object $quiz the data from the database, including $quiz->id - * which is the id of the quiz being deleted. - * @since Moodle 2.7.1, 2.6.4, 2.5.7 - */ - public static function delete_settings($quiz) { - - foreach (self::get_rule_classes() as $rule) { - $rule::delete_settings($quiz); - } - } - - /** - * Build the SQL for loading all the access settings in one go. - * @param int $quizid the quiz id. - * @param string $basefields initial part of the select list. - * @return array with two elements, the sql and the placeholder values. - * If $basefields is '' then you must allow for the possibility that - * there is no data to load, in which case this method returns $sql = ''. - */ - protected static function get_load_sql($quizid, $rules, $basefields) { - $allfields = $basefields; - $alljoins = '{quiz} quiz'; - $allparams = array('quizid' => $quizid); - - foreach ($rules as $rule) { - list($fields, $joins, $params) = $rule::get_settings_sql($quizid); - if ($fields) { - if ($allfields) { - $allfields .= ', '; - } - $allfields .= $fields; - } - if ($joins) { - $alljoins .= ' ' . $joins; - } - if ($params) { - $allparams += $params; - } - } - - if ($allfields === '') { - return array('', array()); - } - - return array("SELECT $allfields FROM $alljoins WHERE quiz.id = :quizid", $allparams); - } - - /** - * Load any settings required by the access rules. We try to do this with - * a single DB query. - * - * Note that the standard plugins do not use this mechanism, becuase all their - * settings are stored in the quiz table. - * - * @param int $quizid the quiz id. - * @return array setting value name => value. The value names should all - * start with the name of the corresponding plugin to avoid collisions. - */ - public static function load_settings($quizid) { - global $DB; - - $rules = self::get_rule_classes(); - list($sql, $params) = self::get_load_sql($quizid, $rules, ''); - - if ($sql) { - $data = (array) $DB->get_record_sql($sql, $params); - } else { - $data = array(); - } - - foreach ($rules as $rule) { - $data += $rule::get_extra_settings($quizid); - } - - return $data; - } - - /** - * Load the quiz settings and any settings required by the access rules. - * We try to do this with a single DB query. - * - * Note that the standard plugins do not use this mechanism, becuase all their - * settings are stored in the quiz table. - * - * @param int $quizid the quiz id. - * @return object mdl_quiz row with extra fields. - */ - public static function load_quiz_and_settings($quizid) { - global $DB; - - $rules = self::get_rule_classes(); - list($sql, $params) = self::get_load_sql($quizid, $rules, 'quiz.*'); - $quiz = $DB->get_record_sql($sql, $params, MUST_EXIST); - - foreach ($rules as $rule) { - foreach ($rule::get_extra_settings($quizid) as $name => $value) { - $quiz->$name = $value; - } - } - - return $quiz; - } - - /** - * @return array the class names of all the active rules. Mainly useful for - * debugging. - */ - public function get_active_rule_names() { - $classnames = array(); - foreach ($this->rules as $rule) { - $classnames[] = get_class($rule); - } - return $classnames; - } - - /** - * Accumulates an array of messages. - * @param array $messages the current list of messages. - * @param string|array $new the new messages or messages. - * @return array the updated array of messages. - */ - protected function accumulate_messages($messages, $new) { - if (is_array($new)) { - $messages = array_merge($messages, $new); - } else if (is_string($new) && $new) { - $messages[] = $new; - } - return $messages; - } - - /** - * Provide a description of the rules that apply to this quiz, such - * as is shown at the top of the quiz view page. Note that not all - * rules consider themselves important enough to output a description. - * - * @return array an array of description messages which may be empty. It - * would be sensible to output each one surrounded by <p> tags. - */ - public function describe_rules() { - $result = array(); - foreach ($this->rules as $rule) { - $result = $this->accumulate_messages($result, $rule->description()); - } - return $result; - } - - /** - * Whether or not a user should be allowed to start a new attempt at this quiz now. - * If there are any restrictions in force now, return an array of reasons why access - * should be blocked. If access is OK, return false. - * - * @param int $numattempts the number of previous attempts this user has made. - * @param object|false $lastattempt information about the user's last completed attempt. - * if there is not a previous attempt, the false is passed. - * @return mixed An array of reason why access is not allowed, or an empty array - * (== false) if access should be allowed. - */ - public function prevent_new_attempt($numprevattempts, $lastattempt) { - $reasons = array(); - foreach ($this->rules as $rule) { - $reasons = $this->accumulate_messages($reasons, - $rule->prevent_new_attempt($numprevattempts, $lastattempt)); - } - return $reasons; - } - - /** - * Whether the user should be blocked from starting a new attempt or continuing - * an attempt now. If there are any restrictions in force now, return an array - * of reasons why access should be blocked. If access is OK, return false. - * - * @return mixed An array of reason why access is not allowed, or an empty array - * (== false) if access should be allowed. - */ - public function prevent_access() { - $reasons = array(); - foreach ($this->rules as $rule) { - $reasons = $this->accumulate_messages($reasons, $rule->prevent_access()); - } - return $reasons; - } - - /** - * @param int|null $attemptid the id of the current attempt, if there is one, - * otherwise null. - * @return bool whether a check is required before the user starts/continues - * their attempt. - */ - public function is_preflight_check_required($attemptid) { - foreach ($this->rules as $rule) { - if ($rule->is_preflight_check_required($attemptid)) { - return true; - } - } - return false; - } - - /** - * Build the form required to do the pre-flight checks. - * @param moodle_url $url the form action URL. - * @param int|null $attemptid the id of the current attempt, if there is one, - * otherwise null. - * @return mod_quiz_preflight_check_form the form. - */ - public function get_preflight_check_form(moodle_url $url, $attemptid) { - // This form normally wants POST submissins. However, it also needs to - // accept GET submissions. Since formslib is strict, we have to detect - // which case we are in, and set the form property appropriately. - $method = 'post'; - if (!empty($_GET['_qf__mod_quiz_preflight_check_form'])) { - $method = 'get'; - } - return new mod_quiz_preflight_check_form($url->out_omit_querystring(), - array('rules' => $this->rules, 'quizobj' => $this->quizobj, - 'attemptid' => $attemptid, 'hidden' => $url->params()), $method); - } - - /** - * The pre-flight check has passed. This is a chance to record that fact in - * some way. - * @param int|null $attemptid the id of the current attempt, if there is one, - * otherwise null. - */ - public function notify_preflight_check_passed($attemptid) { - foreach ($this->rules as $rule) { - $rule->notify_preflight_check_passed($attemptid); - } - } - - /** - * Inform the rules that the current attempt is finished. This is use, for example - * by the password rule, to clear the flag in the session. - */ - public function current_attempt_finished() { - foreach ($this->rules as $rule) { - $rule->current_attempt_finished(); - } - } - - /** - * Do any of the rules mean that this student will no be allowed any further attempts at this - * quiz. Used, for example, to change the label by the grade displayed on the view page from - * 'your current grade is' to 'your final grade is'. - * - * @param int $numattempts the number of previous attempts this user has made. - * @param object $lastattempt information about the user's last completed attempt. - * @return bool true if there is no way the user will ever be allowed to attempt - * this quiz again. - */ - public function is_finished($numprevattempts, $lastattempt) { - foreach ($this->rules as $rule) { - if ($rule->is_finished($numprevattempts, $lastattempt)) { - return true; - } - } - return false; - } - - /** - * Sets up the attempt (review or summary) page with any properties required - * by the access rules. - * - * @param moodle_page $page the page object to initialise. - */ - public function setup_attempt_page($page) { - foreach ($this->rules as $rule) { - $rule->setup_attempt_page($page); - } - } - - /** - * Compute when the attempt must be submitted. - * - * @param object $attempt the data from the relevant quiz_attempts row. - * @return int|false the attempt close time. - * False if there is no limit. - */ - public function get_end_time($attempt) { - $timeclose = false; - foreach ($this->rules as $rule) { - $ruletimeclose = $rule->end_time($attempt); - if ($ruletimeclose !== false && ($timeclose === false || $ruletimeclose < $timeclose)) { - $timeclose = $ruletimeclose; - } - } - return $timeclose; - } - - /** - * Compute what should be displayed to the user for time remaining in this attempt. - * - * @param object $attempt the data from the relevant quiz_attempts row. - * @param int $timenow the time to consider as 'now'. - * @return int|false the number of seconds remaining for this attempt. - * False if no limit should be displayed. - */ - public function get_time_left_display($attempt, $timenow) { - $timeleft = false; - foreach ($this->rules as $rule) { - $ruletimeleft = $rule->time_left_display($attempt, $timenow); - if ($ruletimeleft !== false && ($timeleft === false || $ruletimeleft < $timeleft)) { - $timeleft = $ruletimeleft; - } - } - return $timeleft; - } - - /** - * @return bolean if this quiz should only be shown to students in a popup window. - */ - public function attempt_must_be_in_popup() { - foreach ($this->rules as $rule) { - if ($rule->attempt_must_be_in_popup()) { - return true; - } - } - return false; - } - - /** - * @return array any options that are required for showing the attempt page - * in a popup window. - */ - public function get_popup_options() { - $options = array(); - foreach ($this->rules as $rule) { - $options += $rule->get_popup_options(); - } - return $options; - } - - /** - * Send the user back to the quiz view page. Normally this is just a redirect, but - * If we were in a secure window, we close this window, and reload the view window we came from. - * - * This method does not return; - * - * @param mod_quiz_renderer $output the quiz renderer. - * @param string $message optional message to output while redirecting. - */ - public function back_to_view_page($output, $message = '') { - if ($this->attempt_must_be_in_popup()) { - echo $output->close_attempt_popup($this->quizobj->view_url(), $message); - die(); - } else { - redirect($this->quizobj->view_url(), $message); - } - } - - /** - * Make some text into a link to review the quiz, if that is appropriate. - * - * @param string $linktext some text. - * @param object $attempt the attempt object - * @return string some HTML, the $linktext either unmodified or wrapped in a - * link to the review page. - */ - public function make_review_link($attempt, $reviewoptions, $output) { - - // If the attempt is still open, don't link. - if (in_array($attempt->state, array(quiz_attempt::IN_PROGRESS, quiz_attempt::OVERDUE))) { - return $output->no_review_message(''); - } - - $when = quiz_attempt_state($this->quizobj->get_quiz(), $attempt); - $reviewoptions = display_options::make_from_quiz( - $this->quizobj->get_quiz(), $when); - - if (!$reviewoptions->attempt) { - return $output->no_review_message($this->quizobj->cannot_review_message($when, true)); - - } else { - return $output->review_link($this->quizobj->review_url($attempt->id), - $this->attempt_must_be_in_popup(), $this->get_popup_options()); - } - } - - /** - * Run the preflight checks using the given data in all the rules supporting them. - * - * @param array $data passed data for validation - * @param array $files un-used, Moodle seems to not support it anymore - * @param int|null $attemptid the id of the current attempt, if there is one, - * otherwise null. - * @return array of errors, empty array means no erros - * @since Moodle 3.1 - */ - public function validate_preflight_check($data, $files, $attemptid) { - $errors = array(); - foreach ($this->rules as $rule) { - if ($rule->is_preflight_check_required($attemptid)) { - $errors = $rule->validate_preflight_check($data, $files, $errors, $attemptid); - } - } - return $errors; - } -} +debugging('This file is no longer required in Moodle 4.2+. Please do not include/require it.', DEBUG_DEVELOPER); diff --git a/mod/quiz/accessrule/accessrulebase.php b/mod/quiz/accessrule/accessrulebase.php index d8495122076..3bccd0181f8 100644 --- a/mod/quiz/accessrule/accessrulebase.php +++ b/mod/quiz/accessrule/accessrulebase.php @@ -302,7 +302,7 @@ abstract class quiz_access_rule_base { /** * Return the bits of SQL needed to load all the settings from all the access * plugins in one DB query. The easiest way to understand what you need to do - * here is probalby to read the code of {@link quiz_access_manager::load_settings()}. + * here is probably to read the code of {@see access_manager::load_settings()}. * * If you have some settings that cannot be loaded in this way, then you can * use the {@link get_extra_settings()} method instead, but that has diff --git a/mod/quiz/accessrule/seb/classes/external/validate_quiz_keys.php b/mod/quiz/accessrule/seb/classes/external/validate_quiz_keys.php index 2375e18ec63..1ec74bb7405 100644 --- a/mod/quiz/accessrule/seb/classes/external/validate_quiz_keys.php +++ b/mod/quiz/accessrule/seb/classes/external/validate_quiz_keys.php @@ -29,7 +29,6 @@ use quiz; use quizaccess_seb\event\access_prevented; use quizaccess_seb\access_manager; -require_once($CFG->dirroot . '/mod/quiz/accessmanager.php'); require_once($CFG->dirroot . '/mod/quiz/attemptlib.php'); require_once($CFG->libdir . '/externallib.php'); diff --git a/mod/quiz/accessrule/seb/rule.php b/mod/quiz/accessrule/seb/rule.php index 1772a818237..a9f53bf01c9 100644 --- a/mod/quiz/accessrule/seb/rule.php +++ b/mod/quiz/accessrule/seb/rule.php @@ -228,7 +228,7 @@ class quizaccess_seb extends quiz_access_rule_base { /** * Return the bits of SQL needed to load all the settings from all the access * plugins in one DB query. The easiest way to understand what you need to do - * here is probalby to read the code of {@link quiz_access_manager::load_settings()}. + * here is probably to read the code of {@see \mod\quiz\access_manager::load_settings()}. * * If you have some settings that cannot be loaded in this way, then you can * use the {@link get_extra_settings()} method instead, but that has diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index 54475f19814..999bb9f6d81 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die(); +use mod_quiz\access_manager; use mod_quiz\question\bank\qbank_helper; use mod_quiz\question\display_options; @@ -89,7 +90,7 @@ class quiz { protected $questions = null; /** @var stdClass[] of quiz_section rows. */ protected $sections = null; - /** @var quiz_access_manager the access manager for this quiz. */ + /** @var access_manager the access manager for this quiz. */ protected $accessmanager = null; /** @var bool whether the current user has capability mod/quiz:preview. */ protected $ispreviewuser = null; @@ -123,7 +124,7 @@ class quiz { public static function create($quizid, $userid = null) { global $DB; - $quiz = quiz_access_manager::load_quiz_and_settings($quizid); + $quiz = access_manager::load_quiz_and_settings($quizid); $course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id, false, MUST_EXIST); @@ -360,16 +361,16 @@ class quiz { } /** - * Return quiz_access_manager and instance of the quiz_access_manager class + * Return access_manager and instance of the access_manager class * for this quiz at this time. * * @param int $timenow the current time as a unix timestamp. - * @return quiz_access_manager and instance of the quiz_access_manager class + * @return access_manager and instance of the access_manager class * for this quiz at this time. */ public function get_access_manager($timenow) { if (is_null($this->accessmanager)) { - $this->accessmanager = new quiz_access_manager($this, $timenow, + $this->accessmanager = new access_manager($this, $timenow, has_capability('mod/quiz:ignoretimelimits', $this->context, null, false)); } return $this->accessmanager; @@ -665,7 +666,7 @@ class quiz_attempt { global $DB; $attempt = $DB->get_record('quiz_attempts', $conditions, '*', MUST_EXIST); - $quiz = quiz_access_manager::load_quiz_and_settings($attempt->quiz); + $quiz = access_manager::load_quiz_and_settings($attempt->quiz); $course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id, false, MUST_EXIST); @@ -894,7 +895,7 @@ class quiz_attempt { /** * @param int $timenow the current time as a unix timestamp. - * @return quiz_access_manager and instance of the quiz_access_manager class + * @return access_manager and instance of the access_manager class * for this quiz at this time. */ public function get_access_manager($timenow) { diff --git a/mod/quiz/classes/access_manager.php b/mod/quiz/classes/access_manager.php new file mode 100644 index 00000000000..4fec0ca6d2b --- /dev/null +++ b/mod/quiz/classes/access_manager.php @@ -0,0 +1,564 @@ +. + +namespace mod_quiz; + +use core_component; +use mod_quiz\question\display_options; +use mod_quiz_mod_form; +use mod_quiz_preflight_check_form; +use mod_quiz_renderer; +use moodle_page; +use moodle_url; +use MoodleQuickForm; +use quiz; +use quiz_attempt; + +/** + * This class keeps track of the various access rules that apply to a particular + * quiz, with convinient methods for seeing whether access is allowed. + * + * @package mod_quiz + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.2 + */ +class access_manager { + /** @var quiz the quiz settings object. */ + protected $quizobj; + /** @var int the time to be considered as 'now'. */ + protected $timenow; + /** @var array of quiz_access_rule_base. */ + protected $rules = array(); + + /** + * Create an instance for a particular quiz. + * @param object $quizobj An instance of the class quiz from attemptlib.php. + * The quiz we will be controlling access to. + * @param int $timenow The time to use as 'now'. + * @param bool $canignoretimelimits Whether this user is exempt from time + * limits (has_capability('mod/quiz:ignoretimelimits', ...)). + */ + public function __construct($quizobj, $timenow, $canignoretimelimits) { + $this->quizobj = $quizobj; + $this->timenow = $timenow; + $this->rules = $this->make_rules($quizobj, $timenow, $canignoretimelimits); + } + + /** + * Make all the rules relevant to a particular quiz. + * @param quiz $quizobj information about the quiz in question. + * @param int $timenow the time that should be considered as 'now'. + * @param bool $canignoretimelimits whether the current user is exempt from + * time limits by the mod/quiz:ignoretimelimits capability. + * @return array of {@link quiz_access_rule_base}s. + */ + protected function make_rules($quizobj, $timenow, $canignoretimelimits) { + + $rules = array(); + foreach (self::get_rule_classes() as $ruleclass) { + $rule = $ruleclass::make($quizobj, $timenow, $canignoretimelimits); + if ($rule) { + $rules[$ruleclass] = $rule; + } + } + + $superceededrules = array(); + foreach ($rules as $rule) { + $superceededrules += $rule->get_superceded_rules(); + } + + foreach ($superceededrules as $superceededrule) { + unset($rules['quizaccess_' . $superceededrule]); + } + + return $rules; + } + + /** + * @return array of all the installed rule class names. + */ + protected static function get_rule_classes() { + return core_component::get_plugin_list_with_class('quizaccess', '', 'rule.php'); + } + + /** + * Add any form fields that the access rules require to the settings form. + * + * Note that the standard plugins do not use this mechanism, becuase all their + * settings are stored in the quiz table. + * + * @param mod_quiz_mod_form $quizform the quiz settings form that is being built. + * @param MoodleQuickForm $mform the wrapped MoodleQuickForm. + */ + public static function add_settings_form_fields( + mod_quiz_mod_form $quizform, MoodleQuickForm $mform) { + + foreach (self::get_rule_classes() as $rule) { + $rule::add_settings_form_fields($quizform, $mform); + } + } + + /** + * The the options for the Browser security settings menu. + * + * @return array key => lang string. + */ + public static function get_browser_security_choices() { + $options = array('-' => get_string('none', 'quiz')); + foreach (self::get_rule_classes() as $rule) { + $options += $rule::get_browser_security_choices(); + } + return $options; + } + + /** + * Validate the data from any form fields added using {@link add_settings_form_fields()}. + * @param array $errors the errors found so far. + * @param array $data the submitted form data. + * @param array $files information about any uploaded files. + * @param mod_quiz_mod_form $quizform the quiz form object. + * @return array $errors the updated $errors array. + */ + public static function validate_settings_form_fields(array $errors, + array $data, $files, mod_quiz_mod_form $quizform) { + + foreach (self::get_rule_classes() as $rule) { + $errors = $rule::validate_settings_form_fields($errors, $data, $files, $quizform); + } + + return $errors; + } + + /** + * Save any submitted settings when the quiz settings form is submitted. + * + * Note that the standard plugins do not use this mechanism because their + * settings are stored in the quiz table. + * + * @param object $quiz the data from the quiz form, including $quiz->id + * which is the id of the quiz being saved. + */ + public static function save_settings($quiz) { + + foreach (self::get_rule_classes() as $rule) { + $rule::save_settings($quiz); + } + } + + /** + * Delete any rule-specific settings when the quiz is deleted. + * + * Note that the standard plugins do not use this mechanism because their + * settings are stored in the quiz table. + * + * @param object $quiz the data from the database, including $quiz->id + * which is the id of the quiz being deleted. + * @since Moodle 2.7.1, 2.6.4, 2.5.7 + */ + public static function delete_settings($quiz) { + + foreach (self::get_rule_classes() as $rule) { + $rule::delete_settings($quiz); + } + } + + /** + * Build the SQL for loading all the access settings in one go. + * @param int $quizid the quiz id. + * @param string $basefields initial part of the select list. + * @return array with two elements, the sql and the placeholder values. + * If $basefields is '' then you must allow for the possibility that + * there is no data to load, in which case this method returns $sql = ''. + */ + protected static function get_load_sql($quizid, $rules, $basefields) { + $allfields = $basefields; + $alljoins = '{quiz} quiz'; + $allparams = array('quizid' => $quizid); + + foreach ($rules as $rule) { + list($fields, $joins, $params) = $rule::get_settings_sql($quizid); + if ($fields) { + if ($allfields) { + $allfields .= ', '; + } + $allfields .= $fields; + } + if ($joins) { + $alljoins .= ' ' . $joins; + } + if ($params) { + $allparams += $params; + } + } + + if ($allfields === '') { + return array('', array()); + } + + return array("SELECT $allfields FROM $alljoins WHERE quiz.id = :quizid", $allparams); + } + + /** + * Load any settings required by the access rules. We try to do this with + * a single DB query. + * + * Note that the standard plugins do not use this mechanism, becuase all their + * settings are stored in the quiz table. + * + * @param int $quizid the quiz id. + * @return array setting value name => value. The value names should all + * start with the name of the corresponding plugin to avoid collisions. + */ + public static function load_settings($quizid) { + global $DB; + + $rules = self::get_rule_classes(); + list($sql, $params) = self::get_load_sql($quizid, $rules, ''); + + if ($sql) { + $data = (array) $DB->get_record_sql($sql, $params); + } else { + $data = array(); + } + + foreach ($rules as $rule) { + $data += $rule::get_extra_settings($quizid); + } + + return $data; + } + + /** + * Load the quiz settings and any settings required by the access rules. + * We try to do this with a single DB query. + * + * Note that the standard plugins do not use this mechanism, becuase all their + * settings are stored in the quiz table. + * + * @param int $quizid the quiz id. + * @return object mdl_quiz row with extra fields. + */ + public static function load_quiz_and_settings($quizid) { + global $DB; + + $rules = self::get_rule_classes(); + list($sql, $params) = self::get_load_sql($quizid, $rules, 'quiz.*'); + $quiz = $DB->get_record_sql($sql, $params, MUST_EXIST); + + foreach ($rules as $rule) { + foreach ($rule::get_extra_settings($quizid) as $name => $value) { + $quiz->$name = $value; + } + } + + return $quiz; + } + + /** + * @return array the class names of all the active rules. Mainly useful for + * debugging. + */ + public function get_active_rule_names() { + $classnames = array(); + foreach ($this->rules as $rule) { + $classnames[] = get_class($rule); + } + return $classnames; + } + + /** + * Accumulates an array of messages. + * @param array $messages the current list of messages. + * @param string|array $new the new messages or messages. + * @return array the updated array of messages. + */ + protected function accumulate_messages($messages, $new) { + if (is_array($new)) { + $messages = array_merge($messages, $new); + } else if (is_string($new) && $new) { + $messages[] = $new; + } + return $messages; + } + + /** + * Provide a description of the rules that apply to this quiz, such + * as is shown at the top of the quiz view page. Note that not all + * rules consider themselves important enough to output a description. + * + * @return array an array of description messages which may be empty. It + * would be sensible to output each one surrounded by <p> tags. + */ + public function describe_rules() { + $result = array(); + foreach ($this->rules as $rule) { + $result = $this->accumulate_messages($result, $rule->description()); + } + return $result; + } + + /** + * Whether or not a user should be allowed to start a new attempt at this quiz now. + * If there are any restrictions in force now, return an array of reasons why access + * should be blocked. If access is OK, return false. + * + * @param int $numattempts the number of previous attempts this user has made. + * @param object|false $lastattempt information about the user's last completed attempt. + * if there is not a previous attempt, the false is passed. + * @return mixed An array of reason why access is not allowed, or an empty array + * (== false) if access should be allowed. + */ + public function prevent_new_attempt($numprevattempts, $lastattempt) { + $reasons = array(); + foreach ($this->rules as $rule) { + $reasons = $this->accumulate_messages($reasons, + $rule->prevent_new_attempt($numprevattempts, $lastattempt)); + } + return $reasons; + } + + /** + * Whether the user should be blocked from starting a new attempt or continuing + * an attempt now. If there are any restrictions in force now, return an array + * of reasons why access should be blocked. If access is OK, return false. + * + * @return mixed An array of reason why access is not allowed, or an empty array + * (== false) if access should be allowed. + */ + public function prevent_access() { + $reasons = array(); + foreach ($this->rules as $rule) { + $reasons = $this->accumulate_messages($reasons, $rule->prevent_access()); + } + return $reasons; + } + + /** + * @param int|null $attemptid the id of the current attempt, if there is one, + * otherwise null. + * @return bool whether a check is required before the user starts/continues + * their attempt. + */ + public function is_preflight_check_required($attemptid) { + foreach ($this->rules as $rule) { + if ($rule->is_preflight_check_required($attemptid)) { + return true; + } + } + return false; + } + + /** + * Build the form required to do the pre-flight checks. + * @param moodle_url $url the form action URL. + * @param int|null $attemptid the id of the current attempt, if there is one, + * otherwise null. + * @return mod_quiz_preflight_check_form the form. + */ + public function get_preflight_check_form(moodle_url $url, $attemptid) { + // This form normally wants POST submissins. However, it also needs to + // accept GET submissions. Since formslib is strict, we have to detect + // which case we are in, and set the form property appropriately. + $method = 'post'; + if (!empty($_GET['_qf__mod_quiz_preflight_check_form'])) { + $method = 'get'; + } + return new mod_quiz_preflight_check_form($url->out_omit_querystring(), + array('rules' => $this->rules, 'quizobj' => $this->quizobj, + 'attemptid' => $attemptid, 'hidden' => $url->params()), $method); + } + + /** + * The pre-flight check has passed. This is a chance to record that fact in + * some way. + * @param int|null $attemptid the id of the current attempt, if there is one, + * otherwise null. + */ + public function notify_preflight_check_passed($attemptid) { + foreach ($this->rules as $rule) { + $rule->notify_preflight_check_passed($attemptid); + } + } + + /** + * Inform the rules that the current attempt is finished. This is use, for example + * by the password rule, to clear the flag in the session. + */ + public function current_attempt_finished() { + foreach ($this->rules as $rule) { + $rule->current_attempt_finished(); + } + } + + /** + * Do any of the rules mean that this student will no be allowed any further attempts at this + * quiz. Used, for example, to change the label by the grade displayed on the view page from + * 'your current grade is' to 'your final grade is'. + * + * @param int $numattempts the number of previous attempts this user has made. + * @param object $lastattempt information about the user's last completed attempt. + * @return bool true if there is no way the user will ever be allowed to attempt + * this quiz again. + */ + public function is_finished($numprevattempts, $lastattempt) { + foreach ($this->rules as $rule) { + if ($rule->is_finished($numprevattempts, $lastattempt)) { + return true; + } + } + return false; + } + + /** + * Sets up the attempt (review or summary) page with any properties required + * by the access rules. + * + * @param moodle_page $page the page object to initialise. + */ + public function setup_attempt_page($page) { + foreach ($this->rules as $rule) { + $rule->setup_attempt_page($page); + } + } + + /** + * Compute when the attempt must be submitted. + * + * @param object $attempt the data from the relevant quiz_attempts row. + * @return int|false the attempt close time. + * False if there is no limit. + */ + public function get_end_time($attempt) { + $timeclose = false; + foreach ($this->rules as $rule) { + $ruletimeclose = $rule->end_time($attempt); + if ($ruletimeclose !== false && ($timeclose === false || $ruletimeclose < $timeclose)) { + $timeclose = $ruletimeclose; + } + } + return $timeclose; + } + + /** + * Compute what should be displayed to the user for time remaining in this attempt. + * + * @param object $attempt the data from the relevant quiz_attempts row. + * @param int $timenow the time to consider as 'now'. + * @return int|false the number of seconds remaining for this attempt. + * False if no limit should be displayed. + */ + public function get_time_left_display($attempt, $timenow) { + $timeleft = false; + foreach ($this->rules as $rule) { + $ruletimeleft = $rule->time_left_display($attempt, $timenow); + if ($ruletimeleft !== false && ($timeleft === false || $ruletimeleft < $timeleft)) { + $timeleft = $ruletimeleft; + } + } + return $timeleft; + } + + /** + * @return bolean if this quiz should only be shown to students in a popup window. + */ + public function attempt_must_be_in_popup() { + foreach ($this->rules as $rule) { + if ($rule->attempt_must_be_in_popup()) { + return true; + } + } + return false; + } + + /** + * @return array any options that are required for showing the attempt page + * in a popup window. + */ + public function get_popup_options() { + $options = array(); + foreach ($this->rules as $rule) { + $options += $rule->get_popup_options(); + } + return $options; + } + + /** + * Send the user back to the quiz view page. Normally this is just a redirect, but + * If we were in a secure window, we close this window, and reload the view window we came from. + * + * This method does not return; + * + * @param mod_quiz_renderer $output the quiz renderer. + * @param string $message optional message to output while redirecting. + */ + public function back_to_view_page($output, $message = '') { + if ($this->attempt_must_be_in_popup()) { + echo $output->close_attempt_popup($this->quizobj->view_url(), $message); + die(); + } else { + redirect($this->quizobj->view_url(), $message); + } + } + + /** + * Make some text into a link to review the quiz, if that is appropriate. + * + * @param string $linktext some text. + * @param object $attempt the attempt object + * @return string some HTML, the $linktext either unmodified or wrapped in a + * link to the review page. + */ + public function make_review_link($attempt, $reviewoptions, $output) { + + // If the attempt is still open, don't link. + if (in_array($attempt->state, array(quiz_attempt::IN_PROGRESS, quiz_attempt::OVERDUE))) { + return $output->no_review_message(''); + } + + $when = quiz_attempt_state($this->quizobj->get_quiz(), $attempt); + $reviewoptions = display_options::make_from_quiz( + $this->quizobj->get_quiz(), $when); + + if (!$reviewoptions->attempt) { + return $output->no_review_message($this->quizobj->cannot_review_message($when, true)); + + } else { + return $output->review_link($this->quizobj->review_url($attempt->id), + $this->attempt_must_be_in_popup(), $this->get_popup_options()); + } + } + + /** + * Run the preflight checks using the given data in all the rules supporting them. + * + * @param array $data passed data for validation + * @param array $files un-used, Moodle seems to not support it anymore + * @param int|null $attemptid the id of the current attempt, if there is one, + * otherwise null. + * @return array of errors, empty array means no erros + * @since Moodle 3.1 + */ + public function validate_preflight_check($data, $files, $attemptid) { + $errors = array(); + foreach ($this->rules as $rule) { + if ($rule->is_preflight_check_required($attemptid)) { + $errors = $rule->validate_preflight_check($data, $files, $errors, $attemptid); + } + } + return $errors; + } +} diff --git a/mod/quiz/classes/admin/browser_security_setting.php b/mod/quiz/classes/admin/browser_security_setting.php index e7be3f35c72..bea427eba71 100644 --- a/mod/quiz/classes/admin/browser_security_setting.php +++ b/mod/quiz/classes/admin/browser_security_setting.php @@ -16,6 +16,8 @@ namespace mod_quiz\admin; +use mod_quiz\access_manager; + /** * Admin settings class for the quiz browser security option. * @@ -35,7 +37,7 @@ class browser_security_setting extends \admin_setting_configselect_with_advanced } require_once($CFG->dirroot . '/mod/quiz/locallib.php'); - $this->choices = \quiz_access_manager::get_browser_security_choices(); + $this->choices = access_manager::get_browser_security_choices(); return true; } diff --git a/mod/quiz/classes/completion/custom_completion.php b/mod/quiz/classes/completion/custom_completion.php index 3502a92b378..3921c02e37e 100644 --- a/mod/quiz/classes/completion/custom_completion.php +++ b/mod/quiz/classes/completion/custom_completion.php @@ -20,10 +20,8 @@ namespace mod_quiz\completion; use context_module; use core_completion\activity_custom_completion; -use grade_grade; -use grade_item; use quiz; -use quiz_access_manager; +use mod_quiz\access_manager; /** * Activity custom completion subclass for the quiz activity. @@ -72,7 +70,7 @@ class custom_completion extends activity_custom_completion { $lastfinishedattempt = end($attempts); $context = context_module::instance($this->cm->id); $quizobj = quiz::create($this->cm->instance, $this->userid); - $accessmanager = new quiz_access_manager( + $accessmanager = new access_manager( $quizobj, time(), has_capability('mod/quiz:ignoretimelimits', $context, $this->userid, false) diff --git a/mod/quiz/classes/external.php b/mod/quiz/classes/external.php index b1b5ecd17ae..024a3dfb1b4 100644 --- a/mod/quiz/classes/external.php +++ b/mod/quiz/classes/external.php @@ -25,6 +25,7 @@ */ use core_course\external\helper_for_get_mods_by_courses; +use mod_quiz\access_manager; defined('MOODLE_INTERNAL') || die; @@ -112,7 +113,7 @@ class mod_quiz_external extends external_api { $timenow = time(); $quizobj = quiz::create($quiz->id, $USER->id); - $accessmanager = new quiz_access_manager($quizobj, $timenow, has_capability('mod/quiz:ignoretimelimits', + $accessmanager = new access_manager($quizobj, $timenow, has_capability('mod/quiz:ignoretimelimits', $context, null, false)); // Fields the user could see if have access to the quiz. @@ -1810,7 +1811,7 @@ class mod_quiz_external extends external_api { $quizobj = quiz::create($cm->instance, $USER->id); $ignoretimelimits = has_capability('mod/quiz:ignoretimelimits', $context, null, false); $timenow = time(); - $accessmanager = new quiz_access_manager($quizobj, $timenow, $ignoretimelimits); + $accessmanager = new access_manager($quizobj, $timenow, $ignoretimelimits); $result['accessrules'] = $accessmanager->describe_rules(); $result['activerulenames'] = $accessmanager->get_active_rule_names(); @@ -1896,7 +1897,7 @@ class mod_quiz_external extends external_api { $quizobj = quiz::create($cm->instance, $USER->id); $ignoretimelimits = has_capability('mod/quiz:ignoretimelimits', $context, null, false); $timenow = time(); - $accessmanager = new quiz_access_manager($quizobj, $timenow, $ignoretimelimits); + $accessmanager = new access_manager($quizobj, $timenow, $ignoretimelimits); $attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'finished', true); $lastfinishedattempt = end($attempts); diff --git a/mod/quiz/classes/question/bank/qbank_helper.php b/mod/quiz/classes/question/bank/qbank_helper.php index f28000c274c..b719974b756 100644 --- a/mod/quiz/classes/question/bank/qbank_helper.php +++ b/mod/quiz/classes/question/bank/qbank_helper.php @@ -23,7 +23,6 @@ use qubaid_condition; defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/question/engine/bank.php'); -require_once($CFG->dirroot . '/mod/quiz/accessmanager.php'); require_once($CFG->dirroot . '/mod/quiz/attemptlib.php'); /** diff --git a/mod/quiz/db/renamedclasses.php b/mod/quiz/db/renamedclasses.php index 4904067348e..9d953c12f9b 100644 --- a/mod/quiz/db/renamedclasses.php +++ b/mod/quiz/db/renamedclasses.php @@ -51,4 +51,5 @@ $renamedclasses = [ 'mod_quiz_attempts_report_form' => 'mod_quiz\local\reports\attempts_report_options_form', 'mod_quiz_attempts_report_options' => 'mod_quiz\local\reports\attempts_report_options', 'quiz_attempts_report_table' => 'mod_quiz\local\reports\attempts_report_table', + 'quiz_access_manager' => 'mod_quiz\access_manager', ]; diff --git a/mod/quiz/deprecatedlib.php b/mod/quiz/deprecatedlib.php index 07c39ea8cfc..f430d76d502 100644 --- a/mod/quiz/deprecatedlib.php +++ b/mod/quiz/deprecatedlib.php @@ -22,6 +22,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use mod_quiz\access_manager; + /** * Internal function used in quiz_get_completion_state. Check passing grade (or no attempts left) requirement for completion. * @@ -69,7 +71,7 @@ function quiz_completion_check_passing_grade_or_all_attempts($course, $cm, $user $lastfinishedattempt = end($attempts); $context = context_module::instance($cm->id); $quizobj = quiz::create($quiz->id, $userid); - $accessmanager = new quiz_access_manager($quizobj, time(), + $accessmanager = new access_manager($quizobj, time(), has_capability('mod/quiz:ignoretimelimits', $context, $userid, false)); return $accessmanager->is_finished(count($attempts), $lastfinishedattempt); diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index 8aaa204b151..7f0bf9daa1b 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die(); +use mod_quiz\access_manager; use mod_quiz\question\bank\custom_view; use mod_quiz\question\display_options; use mod_quiz\question\qubaids_for_quiz; @@ -190,7 +191,7 @@ function quiz_delete_instance($id) { $DB->delete_records('quiz_feedback', array('quizid' => $quiz->id)); - quiz_access_manager::delete_settings($quiz); + access_manager::delete_settings($quiz); $events = $DB->get_records('event', array('modulename' => 'quiz', 'instance' => $quiz->id)); foreach ($events as $event) { @@ -1236,7 +1237,7 @@ function quiz_after_add_or_update($quiz) { } // Store any settings belonging to the access rules. - quiz_access_manager::save_settings($quiz); + access_manager::save_settings($quiz); // Update the events relating to this quiz. quiz_update_events($quiz); diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index 00d8b14161a..f7abd0a28e7 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -31,7 +31,6 @@ defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/mod/quiz/lib.php'); -require_once($CFG->dirroot . '/mod/quiz/accessmanager.php'); require_once($CFG->dirroot . '/mod/quiz/accessmanager_form.php'); require_once($CFG->dirroot . '/mod/quiz/renderer.php'); require_once($CFG->dirroot . '/mod/quiz/attemptlib.php'); @@ -39,6 +38,7 @@ require_once($CFG->libdir . '/completionlib.php'); require_once($CFG->libdir . '/filelib.php'); require_once($CFG->libdir . '/questionlib.php'); +use mod_quiz\access_manager; use mod_quiz\question\bank\qbank_helper; use mod_quiz\question\display_options; @@ -2438,7 +2438,7 @@ function quiz_view($quiz, $course, $cm, $context) { * Validate permissions for creating a new attempt and start a new preview attempt if required. * * @param quiz $quizobj quiz object - * @param quiz_access_manager $accessmanager quiz access manager + * @param access_manager $accessmanager quiz access manager * @param bool $forcenew whether was required to start a new preview attempt * @param int $page page to jump to in the attempt * @param bool $redirect whether to redirect or throw exceptions (for web or ws usage) @@ -2446,7 +2446,7 @@ function quiz_view($quiz, $course, $cm, $context) { * @throws moodle_quiz_exception * @since Moodle 3.1 */ -function quiz_validate_new_attempt(quiz $quizobj, quiz_access_manager $accessmanager, $forcenew, $page, $redirect) { +function quiz_validate_new_attempt(quiz $quizobj, access_manager $accessmanager, $forcenew, $page, $redirect) { global $DB, $USER; $timenow = time(); diff --git a/mod/quiz/mod_form.php b/mod/quiz/mod_form.php index 772b6ddfd7c..a9fec29231b 100644 --- a/mod/quiz/mod_form.php +++ b/mod/quiz/mod_form.php @@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/course/moodleform_mod.php'); require_once($CFG->dirroot . '/mod/quiz/locallib.php'); +use mod_quiz\access_manager; use mod_quiz\question\display_options; /** @@ -289,11 +290,11 @@ class mod_quiz_mod_form extends moodleform_mod { // Browser security choices. $mform->addElement('select', 'browsersecurity', get_string('browsersecurity', 'quiz'), - quiz_access_manager::get_browser_security_choices()); + access_manager::get_browser_security_choices()); $mform->addHelpButton('browsersecurity', 'browsersecurity', 'quiz'); // Any other rule plugins. - quiz_access_manager::add_settings_form_fields($this, $mform); + access_manager::add_settings_form_fields($this, $mform); // ------------------------------------------------------------------------------- $mform->addElement('header', 'overallfeedbackhdr', get_string('overallfeedback', 'quiz')); @@ -479,7 +480,7 @@ class mod_quiz_mod_form extends moodleform_mod { // Load any settings belonging to the access rules. if (!empty($toform['instance'])) { - $accesssettings = quiz_access_manager::load_settings($toform['instance']); + $accesssettings = access_manager::load_settings($toform['instance']); foreach ($accesssettings as $name => $value) { $toform[$name] = $value; } @@ -589,7 +590,7 @@ class mod_quiz_mod_form extends moodleform_mod { unset($errors['gradepass']); } // Any other rule plugins. - $errors = quiz_access_manager::validate_settings_form_fields($errors, $data, $files, $this); + $errors = access_manager::validate_settings_form_fields($errors, $data, $files, $this); return $errors; } diff --git a/mod/quiz/renderer.php b/mod/quiz/renderer.php index 0055f5b7343..3c33af87a05 100644 --- a/mod/quiz/renderer.php +++ b/mod/quiz/renderer.php @@ -25,6 +25,7 @@ defined('MOODLE_INTERNAL') || die(); +use mod_quiz\access_manager; use mod_quiz\question\display_options; @@ -444,7 +445,7 @@ class mod_quiz_renderer extends plugin_renderer_base { * * @param quiz_attempt $attemptobj Instance of quiz_attempt * @param int $page Current page number - * @param quiz_access_manager $accessmanager Instance of quiz_access_manager + * @param access_manager $accessmanager Instance of access_manager * @param array $messages An array of messages * @param array $slots Contains an array of integers that relate to questions * @param int $id The ID of an attempt @@ -912,7 +913,7 @@ class mod_quiz_renderer extends plugin_renderer_base { // Calling code was not updated since the API change. debugging('The third argument to start_attempt_button should now be the ' . 'mod_quiz_preflight_check_form from ' . - 'quiz_access_manager::get_preflight_check_form, not a warning message string.'); + 'access_manager::get_preflight_check_form, not a warning message string.'); } $button = new single_button($url, $buttontext, 'post', true); @@ -1430,7 +1431,7 @@ class mod_quiz_view_object { public $attempts; /** @var array $attemptobjs quiz_attempt objects corresponding to $attempts. */ public $attemptobjs; - /** @var quiz_access_manager $accessmanager contains various access rules. */ + /** @var access_manager $accessmanager contains various access rules. */ public $accessmanager; /** @var bool $canreviewmine whether the current user has the capability to * review their own attempts. */ diff --git a/mod/quiz/report/reportlib.php b/mod/quiz/report/reportlib.php index da0e996af74..611428cdc8f 100644 --- a/mod/quiz/report/reportlib.php +++ b/mod/quiz/report/reportlib.php @@ -28,7 +28,6 @@ defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/mod/quiz/lib.php'); require_once($CFG->dirroot . '/mod/quiz/attemptlib.php'); require_once($CFG->libdir . '/filelib.php'); -require_once($CFG->dirroot . '/mod/quiz/accessmanager.php'); use mod_quiz\question\display_options; diff --git a/mod/quiz/upgrade.txt b/mod/quiz/upgrade.txt index 9c27c08735b..f9b020dabf0 100644 --- a/mod/quiz/upgrade.txt +++ b/mod/quiz/upgrade.txt @@ -35,14 +35,16 @@ This files describes API changes in the quiz code. - mod_quiz_attempts_report_form => mod_quiz\local\reports\attempts_report_options_form - mod_quiz_attempts_report_options => mod_quiz\local\reports\attempts_report_options - quiz_attempts_report_table => mod_quiz\local\reports\attempts_report_table + - quiz_access_manager => mod_quiz\access_manager - As part of the clean-up, the following files are no longer required, and if you try to +* As part of the clean-up, the following files are no longer required, and if you try to include them, you will get a debugging notices telling you not to: - mod/quiz/report/attemptsreport.php - mod/quiz/report/attemptsreport_form.php - mod/quiz/report/attemptsreport_options.php - mod/quiz/report/attemptsreport_table.php - mod/quiz/report/default.php + - mod/quiz/accessmanager.php === 4.1 === diff --git a/mod/quiz/view.php b/mod/quiz/view.php index f4e4647f2fe..a176e8d839b 100644 --- a/mod/quiz/view.php +++ b/mod/quiz/view.php @@ -23,6 +23,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use mod_quiz\access_manager; require_once(__DIR__ . '/../../config.php'); require_once($CFG->libdir.'/gradelib.php'); @@ -65,7 +66,7 @@ $canpreview = has_capability('mod/quiz:preview', $context); // Create an object to manage all the other (non-roles) access rules. $timenow = time(); $quizobj = quiz::create($cm->instance, $USER->id); -$accessmanager = new quiz_access_manager($quizobj, $timenow, +$accessmanager = new access_manager($quizobj, $timenow, has_capability('mod/quiz:ignoretimelimits', $context, null, false)); $quiz = $quizobj->get_quiz();