Flagging questions during a quiz attempt
We want students to be able to mark certain questions as they are doing them for whatever purpose, for example:
- because they want to go back and check their answer before submitting the quiz.
- because the results will only be released later, and they particularly want to remember to check whether they got this question right.
- because they want to ask their friend or teacher something relating to that question later.
This should be a simple toggleable marker, so a question is either flagged or not. The flag is controlled by the person attempting the quiz. Other people (for example a teacher reviewing the quiz) can see but not change the state.
Teachers should be able to configure whether flags are used on a particular quiz.
Flagging of questions actually be implemented as a feature of the question engine, because it is potentially useful shared functionality. However any user of the question engine will have control over whether the flagging interface appears using the $cmoptions parameter to the print_question function.
In addition, some other parts of the quiz interface will be enhanced to show the flagged state of questions.
We will just store the current state of the flag for each attempt at a question (per question session), so there will not be any history kept.
Interface within questions
The flags will be displayed to the left of the questions, under the question number and marks, if the $cmoptions->flags is set in the call to print_question. There are three modes: QUESTION_FLAGSHIDDEN, QUESTION_FLAGSSHOWN and QUESTION_FLAGSEDITABLE. QUESTION_FLAGSSHOWN means display the current state of the flag, but don't let it be changed. QUESTION_FLAGSEDITABLE means show the flag with UI to change it.
Configuration options within the quiz
There will be a new capability moodle/question:flag, which can be overridden in the quiz context to control whether a particular quiz uses flagging.
Interface within the quiz
If flags are on, the quiz will use QUESTION_FLAGSEDITABLE in attempt.php, and on the review.php and reviewquestion.php page when a user is reviewing their own attempt. It will use QUESTION_FLAGSSHOWN on the two review pages when you are reviewing someone else's attempt.
In addition, if flags are in use
- they will be shown on summary.php.
- they may also be shown in the navigation block. (I will try it, is see if it looks good or if it is just confusing.)
There will be a new column
flagged INT(2) NOT NULL DEFAULT 0
in the question_sessions table.
This will be accessed and updated through a few functions in questionlib.php.
Recording state changes
Also, in the standard response processing (question_process_responses) there will be additional code to get the state of the flag checkbox and store it. TODO
Security of the Ajax interface
One difficulty with the Ajax interface is that the flags are managed by the question bank, but the question bank does not associate the question session with a particular user. (This is to give maximum flexibility to the quiz and other modules using the question engine.) So, when the question bank receives a request saying update the flag for session 12345 from a particular user, how does it know whether to allow it?
We use two techniques to ensure that a call to question/toggleflag.php is valid.
First, question_session has an id column as a primary key, but the pair (attemptid, questionid) also uniquely identifies the row. toggleflag.php requires all three ids to be sent, and checks that they are consistent. That makes it harder to forge requests. However it does not really check that the user sending the request should be allowed to change the flag on this question session.
Second, toggleflag.php requires a checksum parameter to be sent. This must be
md5($attemptid . "_" . $user->secret . "_" . $questionid . "_" . $sessionid);
This can be computed when the flag is being output in the calling page, and in toggleflag.php we can check it against the same quantity for $USER, after require_login(). ($user->secret is a random string stored for each user that is not accessible anywhere.)
(This problem does not arise with the normal response processing because the quiz only asks the question bank to process responses after checking the user's identity.)