This change is logically the same as changing
$this->has_capability('mod/quiz:viewreports')
to
$this->has_capability('mod/quiz:viewreports') || $this->has_capability('mod/quiz:preview')
in the original code. However, I rewrote the logic so that we test the
most common and performance-critical case first - that of a student
lookign at their own attempt.
The sequence of questions that made up a quiz used to be stored as a
comma-separated list in quiz.questions. Now the same information is
stored in the rows in the quiz_slots table. This is not just 'better' in
a database design sense, but it allows for the future changes we will
need as we enhance the quiz in the MDL-40987 epic.
Having changed the database structure, all the rest of the code needs to
be changed to account for it, and that is done here.
Note that there are not many unit tests for the changed bit. That is
because as part of MDL-40987 we will be changing the code further, and
we will add unit tests then.
Some columns needed to be renamed:
* quiz -> quizid
* question -> questionid
* grade -> maxmark
Then all the places that refer to those needed to be fixed.
We now compute the average CBM score, accuracy, CBM bonus and enhanced
accuracy, both for the entire quiz, and for just the questions answered.
Note that these calculations must work correctly in the presence of
descriptions, ungraded questions, and manually graded questions. For
example, imagine a essay added at the end of the quiz "Summarise what
you learned attempting this exercise." This might have max mark zero or
non-zero. The CBM statistics just ignores questions like that.
At the top of the quiz reivew page, there is a table that summarises
infomration about the quiz attempt as a whole. For some question
behaviours, we would like to be able to add additional information to
that summary.
This commit introduces a generic method for the behaviour to provide
summary information about an entire question usage.
1. There is a new admin setting to control whether this feature is
enabled. The admin can set the auto-save frequency to 1, 2 or 5 minutes,
or disable it.
2. When autosave is enabled, there is code in the quiz that monitors the
main quiz form, and does an ajax save call at the given frequency when
changes are being made by the student.
3. The ajax saves go to a new script that calls the question engine to
do the work.
4. To avoid simultaneous autosave + submit and finish, the auto-save
system shuts down shortly before time expires in a timed quiz.
It used to be necessary to store the question number and question page
by adding them as random extra fields on the question object (but
I can no longer remember what that reason was). Now it is possible
to store this sensibly in the quiz_attempt object, which is much
cleaner, so do that.
This fix a small API change in mod_quiz_renderer::finish_review_link.
At least the required change is an improvement, since it gives the
renderer more flexibility.
Here, we catch all the places where a student might be accessing their
own attempts, and make sure any automatic state transitions that
should happen, do happen, before the student sees the attempt.
The places where we need to check this are view.php, startattempt.php
and processattempt.php.
We do not really need to check attempt.php or summary.php, because if
the student is on one of those pages, the JavaScript timer will
auto-submit when time expires, taking them to processattempt.php,
which will do the acutal work.
We intentionally do not trigger state transition when a teacher is
looking at a student's quiz attemp. We will trigger state transitions
on cron, but that is still to do.
Also, the body of the process_... methods still needs to be written.
This achieves a massive clean-up. It simplifies comples code in a number
of places. It allows some methods and functions to be moved to a more
appropriate home (for example cannot_review_message to the quiz class).
It moves more logic out of the renderer.
This avoids the problem that you cannot send messages in transactions.
It also means that the quiz submission will not be prevented, and the
message will still be sent eventually, if any part of the messaging
system is giving intermittent errors when the student wants to submit
their quiz.
The standard themes do not use this for anything, but it makes it easier for themers to do cool stuff.
Also improve the API for getting the question state class.