From 83e840b8e747d932b70f467079050cfff2e8ff73 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 7 Sep 2023 10:46:34 +0100 Subject: [PATCH 1/2] MDL-79280 mod_quiz: consistently store ->cm as a cm_info --- mod/quiz/classes/form/edit_override_form.php | 4 ++-- mod/quiz/classes/quiz_attempt.php | 4 ++-- mod/quiz/classes/quiz_settings.php | 11 +++++------ mod/quiz/upgrade.txt | 5 +++++ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/mod/quiz/classes/form/edit_override_form.php b/mod/quiz/classes/form/edit_override_form.php index 57978625567..eb7ef272de6 100644 --- a/mod/quiz/classes/form/edit_override_form.php +++ b/mod/quiz/classes/form/edit_override_form.php @@ -60,14 +60,14 @@ class edit_override_form extends moodleform { * Constructor. * * @param moodle_url $submiturl the form action URL. - * @param cm_info|stdClass $cm course module object. + * @param cm_info $cm course module object. * @param stdClass $quiz the quiz settings object. * @param context_module $context the quiz context. * @param bool $groupmode editing group override (true) or user override (false). * @param stdClass|null $override the override being edited, if it already exists. */ public function __construct(moodle_url $submiturl, - cm_info|stdClass $cm, stdClass $quiz, context_module $context, + cm_info $cm, stdClass $quiz, context_module $context, bool $groupmode, ?stdClass $override) { $this->cm = $cm; diff --git a/mod/quiz/classes/quiz_attempt.php b/mod/quiz/classes/quiz_attempt.php index aacf15a5256..b031b192edc 100644 --- a/mod/quiz/classes/quiz_attempt.php +++ b/mod/quiz/classes/quiz_attempt.php @@ -100,7 +100,7 @@ class quiz_attempt { * * @param stdClass $attempt the row of the quiz_attempts table. * @param stdClass $quiz the quiz object for this attempt and user. - * @param stdClass|cm_info $cm the course_module object for this quiz. + * @param cm_info $cm the course_module object for this quiz. * @param stdClass $course the row from the course table for the course we belong to. * @param bool $loadquestions (optional) if true, the default, load all the details * of the state of each question. Else just set up the basic details of the attempt. @@ -349,7 +349,7 @@ class quiz_attempt { /** * Get the course_module for this quiz. * - * @return stdClass|cm_info the course_module object. + * @return cm_info the course_module object. */ public function get_cm() { return $this->quizobj->get_cm(); diff --git a/mod/quiz/classes/quiz_settings.php b/mod/quiz/classes/quiz_settings.php index d07f0fa2c91..4aaa1130388 100644 --- a/mod/quiz/classes/quiz_settings.php +++ b/mod/quiz/classes/quiz_settings.php @@ -45,7 +45,7 @@ use stdClass; class quiz_settings { /** @var stdClass the course settings from the database. */ protected $course; - /** @var stdClass the course_module settings from the database. */ + /** @var cm_info the course_module settings from the database. */ protected $cm; /** @var stdClass the quiz settings from the database. */ protected $quiz; @@ -89,12 +89,12 @@ class quiz_settings { * Helper used by the other factory methods. * * @param stdClass $quiz - * @param cm_info|stdClass $cm + * @param cm_info $cm * @param stdClass $course * @param int|null $userid the the userid (optional). If passed, relevant overrides are applied. * @return quiz_settings the new quiz settings object. */ - protected static function create_helper(stdClass $quiz, cm_info|stdClass $cm, stdClass $course, ?int $userid): self { + protected static function create_helper(stdClass $quiz, cm_info $cm, stdClass $course, ?int $userid): self { // Update quiz with override information. if ($userid) { $quiz = quiz_update_effective_access($quiz, $userid); @@ -112,8 +112,7 @@ class quiz_settings { */ public static function create(int $quizid, int $userid = null): self { $quiz = access_manager::load_quiz_and_settings($quizid); - $course = get_course($quiz->course); - $cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id, false, MUST_EXIST); + [$course, $cm] = get_course_and_cm_from_instance($quiz, 'quiz'); return self::create_helper($quiz, $cm, $course, $userid); } @@ -266,7 +265,7 @@ class quiz_settings { /** * Get the course-module object for this quiz. * - * @return stdClass the course_module object. + * @return cm_info the course_module object. */ public function get_cm() { return $this->cm; diff --git a/mod/quiz/upgrade.txt b/mod/quiz/upgrade.txt index b1928061875..fb40f8d30dd 100644 --- a/mod/quiz/upgrade.txt +++ b/mod/quiz/upgrade.txt @@ -4,6 +4,11 @@ This files describes API changes in the quiz code. * The method get_questions() has a new parameter 'requirequestionfullyloaded' which can be used to instruct whether the questions should be fully loaded or not. +* the quiz_settings and quiz_attempt classes now always store the ->cm property as a cm_info class. + In the distant past it was always a stdClass, then at one point there was an undocumented change making + it sometimes a stdClass and sometimes a cm_info. Now it is consistently a cm_info. Type hints have been + updated to reflect this. + === 4.2 === From efe3e377b62d6c177873d97abb8ff036330e3acc Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Wed, 6 Sep 2023 17:24:06 +0100 Subject: [PATCH 2/2] MDL-79280 mod_quiz: Behat scenario for adding multiple user overrides. --- .../tests/behat/quiz_user_override.feature | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/mod/quiz/tests/behat/quiz_user_override.feature b/mod/quiz/tests/behat/quiz_user_override.feature index e9ff50c419e..02d8462341c 100644 --- a/mod/quiz/tests/behat/quiz_user_override.feature +++ b/mod/quiz/tests/behat/quiz_user_override.feature @@ -59,6 +59,30 @@ Feature: Quiz user override And I press "Continue" And I should not see "Student One" + @javascript + Scenario: Add multiple user overrides, one after another + Given the following "activities" exist: + | activity | name | course | idnumber | + | quiz | Test quiz | C1 | quiz1 | + And I am on the "Test quiz" "mod_quiz > View" page logged in as "teacher" + And I change window size to "large" + And I navigate to "Overrides" in current page administration + And I press "Add user override" + And I set the following fields to these values: + | Override user | Student One | + | timeclose[enabled] | 1 | + | Close the quiz | ## 1 January 2020 08:00 ## | + And I press "Save and enter another override" + And I set the following fields to these values: + | Override user | Student Two | + | timeclose[enabled] | 1 | + | Close the quiz | ## 2 January 2020 08:00 ## | + When I press "Save" + Then the following should exist in the "generaltable" table: + | User | Overrides | -4- | + | Student One | Quiz closes | 1 January 2020, 8:00 | + | Student Two | Quiz closes | 2 January 2020, 8:00 | + @javascript Scenario: Can add a user override when the quiz is not available to the student Given the following "activities" exist: