MDL-77564 Quiz display options: Hide or show the grade information

Allow settings to show Max marks and Marks, Max marks only, or hide the grade information completely.
This commit is contained in:
mkassaei 2023-05-09 11:08:01 +01:00 committed by Tim Hunt
parent 4ed782dd03
commit cc880cabf5
17 changed files with 135 additions and 16 deletions

View File

@ -34,7 +34,7 @@ class backup_quiz_activity_structure_step extends backup_questions_activity_stru
'name', 'intro', 'introformat', 'timeopen', 'timeclose', 'timelimit',
'overduehandling', 'graceperiod', 'preferredbehaviour', 'canredoquestions', 'attempts_number',
'attemptonlast', 'grademethod', 'decimalpoints', 'questiondecimalpoints',
'reviewattempt', 'reviewcorrectness', 'reviewmarks',
'reviewattempt', 'reviewcorrectness', 'reviewmaxmarks', 'reviewmarks',
'reviewspecificfeedback', 'reviewgeneralfeedback',
'reviewrightanswer', 'reviewoverallfeedback',
'questionsperpage', 'navmethod', 'shuffleanswers',

View File

@ -184,6 +184,14 @@ class restore_quiz_activity_structure_step extends restore_questions_activity_st
($oldreview & QUIZ_OLD_CLOSED & QUIZ_OLD_SCORES ?
display_options::AFTER_CLOSE : 0);
if (!isset($data->reviewmaxmarks)) {
$data->reviewmaxmarks =
display_options::DURING |
display_options::IMMEDIATELY_AFTER |
display_options::LATER_WHILE_OPEN |
display_options::AFTER_CLOSE;
}
$data->reviewmarks =
display_options::DURING |
($oldreview & QUIZ_OLD_IMMEDIATELY & QUIZ_OLD_SCORES ?

View File

@ -63,6 +63,7 @@ class review_setting extends \admin_setting {
return [
'attempt' => get_string('theattempt', 'quiz'),
'correctness' => get_string('whethercorrect', 'question'),
'maxmarks' => get_string('maxmarks', 'quiz'),
'marks' => get_string('marks', 'question'),
'specificfeedback' => get_string('specificfeedback', 'question'),
'generalfeedback' => get_string('generalfeedback', 'question'),

View File

@ -131,7 +131,7 @@ class mod_quiz_external extends external_api {
$quizdetails['hasquestions'] = (int) $quizobj->has_questions();
$quizdetails['autosaveperiod'] = get_config('quiz', 'autosaveperiod');
$additionalfields = ['attemptonlast', 'reviewattempt', 'reviewcorrectness', 'reviewmarks',
$additionalfields = ['attemptonlast', 'reviewattempt', 'reviewcorrectness', 'reviewmaxmarks', 'reviewmarks',
'reviewspecificfeedback', 'reviewgeneralfeedback', 'reviewrightanswer',
'reviewoverallfeedback', 'questionsperpage', 'navmethod',
'browsersecurity', 'delay1', 'delay2', 'showuserpicture', 'showblocks',
@ -208,8 +208,9 @@ class mod_quiz_external extends external_api {
\mod_quiz\question\display_options class. It is formed by ORing
together the constants defined there.', VALUE_OPTIONAL),
'reviewcorrectness' => new external_value(PARAM_INT, 'Whether users are allowed to review their quiz
attempts at various times.
A bit field, like reviewattempt.', VALUE_OPTIONAL),
attempts at various times.A bit field, like reviewattempt.', VALUE_OPTIONAL),
'reviewmaxmarks' => new external_value(PARAM_INT, 'Whether users are allowed to review their quiz
attempts at various times. A bit field, like reviewattempt.', VALUE_OPTIONAL),
'reviewmarks' => new external_value(PARAM_INT, 'Whether users are allowed to review their quiz attempts
at various times. A bit field, like reviewattempt.',
VALUE_OPTIONAL),

View File

@ -72,8 +72,8 @@ class display_options extends \question_display_options {
$options->attempt = self::extract($quiz->reviewattempt, $when, true, false);
$options->correctness = self::extract($quiz->reviewcorrectness, $when);
$options->marks = self::extract($quiz->reviewmarks, $when,
self::MARK_AND_MAX, self::MAX_ONLY);
$options->marks = self::extract($quiz->reviewmaxmarks, $when,
self::extract($quiz->reviewmarks, $when, self::MARK_AND_MAX, self::MAX_ONLY), self::HIDDEN);
$options->feedback = self::extract($quiz->reviewspecificfeedback, $when);
$options->generalfeedback = self::extract($quiz->reviewgeneralfeedback, $when);
$options->rightanswer = self::extract($quiz->reviewrightanswer, $when);

View File

@ -19,17 +19,18 @@
<FIELD NAME="preferredbehaviour" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="The behaviour to ask questions to use."/>
<FIELD NAME="canredoquestions" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Allows students to redo any completed question within a quiz attempt."/>
<FIELD NAME="attempts" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The maximum number of attempts a student is allowed."/>
<FIELD NAME="attemptonlast" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether subsequent attempts start from teh answer to the previous attempt (1) or start blank (0)."/>
<FIELD NAME="attemptonlast" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether subsequent attempts start from the answer to the previous attempt (1) or start blank (0)."/>
<FIELD NAME="grademethod" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="One of the values QUIZ_GRADEHIGHEST, QUIZ_GRADEAVERAGE, QUIZ_ATTEMPTFIRST or QUIZ_ATTEMPTLAST."/>
<FIELD NAME="decimalpoints" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="2" SEQUENCE="false" COMMENT="Number of decimal points to use when displaying grades."/>
<FIELD NAME="questiondecimalpoints" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="-1" SEQUENCE="false" COMMENT="Number of decimal points to use when displaying question grades. (-1 means use decimalpoints.)"/>
<FIELD NAME="reviewattempt" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to review their quiz attempts at various times. This is a bit field, decoded by the \mod_quiz\question\display_options class. It is formed by ORing together the constants defined there."/>
<FIELD NAME="reviewcorrectness" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to review their quiz attempts at various times. A bit field, like reviewattempt."/>
<FIELD NAME="reviewmarks" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to review their quiz attempts at various times. A bit field, like reviewattempt."/>
<FIELD NAME="reviewspecificfeedback" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to review their quiz attempts at various times. A bit field, like reviewattempt."/>
<FIELD NAME="reviewgeneralfeedback" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to review their quiz attempts at various times. A bit field, like reviewattempt."/>
<FIELD NAME="reviewrightanswer" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to review their quiz attempts at various times. A bit field, like reviewattempt."/>
<FIELD NAME="reviewoverallfeedback" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to review their quiz attempts at various times. A bit field, like reviewattempt."/>
<FIELD NAME="reviewcorrectness" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to review the correctness of the questions in their quiz attempts at various times. A bit field, like reviewattempt."/>
<FIELD NAME="reviewmaxmarks" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Works with reviewmarks to control whether users can see grades at various times. 0 here means no grade information is shown at all. If 1, student can see the number of marks available for this question, and reviewmarks applies. A bit field, like reviewattempt."/>
<FIELD NAME="reviewmarks" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Works with reviewmaxmarks to control whether users can see grades at various times. If reviewmaxmarks is 1, then this controls whether students can see the the mark they got for the question, in addition to the max. A bit field, like reviewattempt."/>
<FIELD NAME="reviewspecificfeedback" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to see the specific feedback in their quiz attempts. A bit field, like reviewattempt."/>
<FIELD NAME="reviewgeneralfeedback" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to see the general feedback in their quiz attempts. A bit field, like reviewattempt."/>
<FIELD NAME="reviewrightanswer" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to see the right answer in their quiz attempts. A bit field, like reviewattempt."/>
<FIELD NAME="reviewoverallfeedback" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether users are allowed to see the overall feedback in their quiz attempts. A bit field, like reviewattempt."/>
<FIELD NAME="questionsperpage" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="How often to insert a page break when editing the quiz, or when shuffling the question order."/>
<FIELD NAME="navmethod" TYPE="char" LENGTH="16" NOTNULL="true" DEFAULT="free" SEQUENCE="false" COMMENT="Any constraints on how the user is allowed to navigate around the quiz. Currently recognised values are 'free' and 'seq'."/>
<FIELD NAME="shuffleanswers" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Whether the parts of the question should be shuffled, in those question types that support it."/>

View File

@ -179,5 +179,20 @@ function xmldb_quiz_upgrade($oldversion) {
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2023042401) {
// Define field reviewmaxmarks to be added to quiz.
$table = new xmldb_table('quiz');
$field = new xmldb_field('reviewmaxmarks', XMLDB_TYPE_INTEGER, '6', null, XMLDB_NOTNULL, null, '0', 'reviewcorrectness');
// Conditionally launch add field reviewmaxmarks.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Quiz savepoint reached.
upgrade_mod_savepoint(true, 2023042401, 'quiz');
}
return true;
}

View File

@ -532,6 +532,15 @@ $string['messageprovider:attempt_grading_complete'] = 'Notification that your at
$string['messageprovider:submission'] = 'Notification of your students\' quiz submissions';
$string['max'] = 'Max';
$string['maxmark'] = 'Maximum mark';
$string['maxmarks'] = 'Max Marks';
$string['maxmarks_help'] = 'Max marks determines whether the grade information are hidden or how it is displayed:
* To hide the grade information completely, do not tick this checkbox (Marks checkbox is disabled automatically).
* To show Max marks only: tick this checkbox and not the Marks checkbox.
* To show both Max marks and Marks, tick this checkbox as well as the Marks checkbox.';
$string['min'] = 'Min';
$string['minutes'] = 'Minutes';
$string['missingcorrectanswer'] = 'Correct answer must be specified';

View File

@ -1117,6 +1117,7 @@ function quiz_process_options($quiz) {
// Combing the individual settings into the review columns.
$quiz->reviewattempt = quiz_review_option_form_to_db($quiz, 'attempt');
$quiz->reviewcorrectness = quiz_review_option_form_to_db($quiz, 'correctness');
$quiz->reviewmaxmarks = quiz_review_option_form_to_db($quiz, 'maxmarks');
$quiz->reviewmarks = quiz_review_option_form_to_db($quiz, 'marks');
$quiz->reviewspecificfeedback = quiz_review_option_form_to_db($quiz, 'specificfeedback');
$quiz->reviewgeneralfeedback = quiz_review_option_form_to_db($quiz, 'generalfeedback');

View File

@ -54,6 +54,7 @@ class mod_quiz_mod_form extends moodleform_mod {
self::$reviewfields = [
'attempt' => ['theattempt', 'quiz'],
'correctness' => ['whethercorrect', 'question'],
'maxmarks' => ['maxmarks', 'quiz'],
'marks' => ['marks', 'quiz'],
'specificfeedback' => ['specificfeedback', 'question'],
'generalfeedback' => ['generalfeedback', 'question'],
@ -403,6 +404,7 @@ class mod_quiz_mod_form extends moodleform_mod {
}
}
$mform->disabledIf('marks' . $whenname, 'maxmarks' . $whenname);
if ($whenname != 'during') {
$mform->disabledIf('correctness' . $whenname, 'attempt' . $whenname);
$mform->disabledIf('specificfeedback' . $whenname, 'attempt' . $whenname);

View File

@ -0,0 +1,64 @@
@mod @mod_quiz
Feature: Allow settings to show Max marks and Marks, Max marks only, or hide the grade information completely.
As a teacher
In order to decide how grade review options are displayed on questions in a quiz review page
I need to be able to set the grade review options for a quiz to to show Max and Marks, Max only, or hide the grade information.
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | One | student1@example.com |
| teacher | Teacher | One | teacher@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher | C1 | editingteacher |
| student1 | C1 | student |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | TF1 | First question |
And the following "activities" exist:
| activity | name | intro | course | idnumber | maxmarksduring | marksduring | maxmarksimmediately | marksimmediately | preferredbehaviour |
| quiz | Quiz 1 | Quiz 1 test | C1 | quiz1 | 1 | 1 | 1 | 1 | immediatefeedback |
| quiz | Quiz 2 | Quiz 2 test | C1 | quiz2 | 0 | 0 | 1 | 1 | immediatefeedback |
And quiz "Quiz 1" contains the following questions:
| question | page | maxmark |
| TF1 | 1 | 2.00 |
And quiz "Quiz 2" contains the following questions:
| question | page | maxmark |
| TF1 | 1 | 2.00 |
@javascript
Scenario: Show max marks and marks during and immediately after the attempt.
Given I am on the "Quiz 1" "quiz activity" page logged in as "student1"
And I click on "Attempt quiz" "button"
And I should see "Question 1" in the ".info" "css_element"
And I should see "Not complete" in the ".info" "css_element"
And I should see "Marked out of 2.00" in the ".info" "css_element"
And I set the field "True" to "1"
And I press "Finish attempt ..."
And I press "Submit all and finish"
And I click on "Submit all and finish" "button" in the "Submit all your answers and finish?" "dialogue"
Then I should see "Finished" in the "State" "table_row"
And I should see "Question 1" in the ".info" "css_element"
And I should see "Correct" in the ".info" "css_element"
And I should see "Mark 2.00 out of 2.00" in the ".info" "css_element"
And I am on the "Quiz 2" "quiz activity" page
And I click on "Attempt quiz" "button"
And I should see "Question 1" in the ".info" "css_element"
And I should see "Not complete" in the ".info" "css_element"
And I should not see "Marked out of 2.00" in the ".info" "css_element"
And I set the field "True" to "1"
And I press "Finish attempt ..."
And I press "Submit all and finish"
And I click on "Submit all and finish" "button" in the "Submit all your answers and finish?" "dialogue"
And I should see "Finished" in the "State" "table_row"
And I should see "Question 1" in the ".info" "css_element"
And I should see "Correct" in the ".info" "css_element"
And I should see "Mark 2.00 out of 2.00" in the ".info" "css_element"

View File

@ -102,6 +102,7 @@ Feature: Settings form fields disabled if not required
And I set the field "Name" to "Test quiz"
Then the "id_attemptclosed" "checkbox" should be disabled
And the "id_correctnessclosed" "checkbox" should be disabled
And the "id_maxmarksclosed" "checkbox" should be disabled
And the "id_marksclosed" "checkbox" should be disabled
And the "id_specificfeedbackclosed" "checkbox" should be disabled
And the "id_generalfeedbackclosed" "checkbox" should be disabled
@ -110,11 +111,16 @@ Feature: Settings form fields disabled if not required
And I set the field "id_timeclose_enabled" to "1"
And the "id_attemptclosed" "checkbox" should be enabled
And the "id_correctnessclosed" "checkbox" should be enabled
And the "id_maxmarksclosed" "checkbox" should be enabled
And the "id_marksclosed" "checkbox" should be enabled
And I set the field "id_maxmarksclosed" to "0"
And the "id_marksclosed" "checkbox" should be disabled
And the "id_specificfeedbackclosed" "checkbox" should be enabled
And the "id_generalfeedbackclosed" "checkbox" should be enabled
And the "id_rightanswerclosed" "checkbox" should be enabled
And the "id_overallfeedbackclosed" "checkbox" should be enabled
And I set the field "id_maxmarksduring" to "0"
And the "id_marksduring" "checkbox" should be disabled
And I should not see "Repaginate now"
@javascript

View File

@ -485,6 +485,7 @@ class custom_completion_test extends advanced_testcase {
$moduleinfo->modulename = 'quiz';
$moduleinfo->quizpassword = '';
$moduleinfo->cmidnumber = '';
$moduleinfo->maxmarksopen = 1;
$moduleinfo->marksopen = 1;
$moduleinfo->visible = 1;
$moduleinfo->visibleoncoursepage = 1;

View File

@ -246,7 +246,7 @@ class external_test extends externallib_advanced_testcase {
'timeopen', 'timeclose', 'grademethod', 'section', 'visible', 'groupmode', 'groupingid',
'attempts', 'timelimit', 'grademethod', 'decimalpoints', 'questiondecimalpoints', 'sumgrades',
'grade', 'preferredbehaviour', 'hasfeedback'];
$userswithaccessfields = ['attemptonlast', 'reviewattempt', 'reviewcorrectness', 'reviewmarks',
$userswithaccessfields = ['attemptonlast', 'reviewattempt', 'reviewcorrectness', 'reviewmaxmarks', 'reviewmarks',
'reviewspecificfeedback', 'reviewgeneralfeedback', 'reviewrightanswer',
'reviewoverallfeedback', 'questionsperpage', 'navmethod',
'browsersecurity', 'delay1', 'delay2', 'showuserpicture', 'showblocks',

View File

@ -45,6 +45,7 @@ class mod_quiz_generator extends testing_module_generator {
'questiondecimalpoints' => -1,
'attemptduring' => 1,
'correctnessduring' => 1,
'maxmarksduring' => 1,
'marksduring' => 1,
'specificfeedbackduring' => 1,
'generalfeedbackduring' => 1,
@ -52,6 +53,7 @@ class mod_quiz_generator extends testing_module_generator {
'overallfeedbackduring' => 0,
'attemptimmediately' => 1,
'correctnessimmediately' => 1,
'maxmarksimmediately' => 1,
'marksimmediately' => 1,
'specificfeedbackimmediately' => 1,
'generalfeedbackimmediately' => 1,
@ -59,6 +61,7 @@ class mod_quiz_generator extends testing_module_generator {
'overallfeedbackimmediately' => 1,
'attemptopen' => 1,
'correctnessopen' => 1,
'maxmarksopen' => 1,
'marksopen' => 1,
'specificfeedbackopen' => 1,
'generalfeedbackopen' => 1,
@ -66,6 +69,7 @@ class mod_quiz_generator extends testing_module_generator {
'overallfeedbackopen' => 1,
'attemptclosed' => 1,
'correctnessclosed' => 1,
'maxmarksclosed' => 1,
'marksclosed' => 1,
'specificfeedbackclosed' => 1,
'generalfeedbackclosed' => 1,

View File

@ -37,7 +37,8 @@ class display_options_test extends \basic_testcase {
$quiz->questiondecimalpoints = -1;
$quiz->reviewattempt = 0x11110;
$quiz->reviewcorrectness = 0x10000;
$quiz->reviewmarks = 0x01110;
$quiz->reviewmaxmarks = 0x10000; // Max marks is set.
$quiz->reviewmarks = 0x00000; // Marks is not set.
$quiz->reviewspecificfeedback = 0x10000;
$quiz->reviewgeneralfeedback = 0x01000;
$quiz->reviewrightanswer = 0x00100;
@ -56,6 +57,8 @@ class display_options_test extends \basic_testcase {
$this->assertEquals(2, $options->markdp);
$quiz->questiondecimalpoints = 5;
$quiz->reviewmaxmarks = 0x11000; // Max marks is set.
$quiz->reviewmarks = 0x11000; // Marks is also set.
$options = display_options::make_from_quiz($quiz,
display_options::IMMEDIATELY_AFTER);
@ -67,9 +70,12 @@ class display_options_test extends \basic_testcase {
$this->assertEquals(display_options::HIDDEN, $options->manualcomment);
$this->assertEquals(5, $options->markdp);
$quiz->reviewmaxmarks = 0x00000; // Max marks is NOT set.
$quiz->reviewmarks = 0x00000; // Marks is also NOT set.
$options = display_options::make_from_quiz($quiz,
display_options::LATER_WHILE_OPEN);
$this->assertEquals(display_options::HIDDEN, $options->marks);
$this->assertEquals(display_options::VISIBLE, $options->rightanswer);
$this->assertEquals(display_options::HIDDEN, $options->generalfeedback);

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2023042400;
$plugin->version = 2023042401;
$plugin->requires = 2023041800;
$plugin->component = 'mod_quiz';