Probably the underlying cause of this mess is that the one file does at least four different things:
- It checks all the conditions about whether the student can do the quiz (quiz open and close times, delays between attempts, number of attempts allowed, password, IP address, ...)
- It starts a new attempt, if necessary.
- It process any data that came from the previous page (if moving between pages of a multi-page quiz, or clicking one of the save/submit buttons).
- It displays (a page of) the quiz, for the student to enter their answers into.
What I am going to doI'm going to split attempt.php into three bits:
attempt.php?attemptid=X&page=YThis will just to part 4 above. It will display a single page of the quiz ready for the student to enter their answers. In can only be used to display an attempt, once that attempt has been started.
The only checking it will do is to ensure that this attempt belongs to the current user, is still open, that we have not passed the close date, and the time limit has not expired.
Instead of checking all the other conditions, we will store in the user's $SESSION a list of attempt ids that have been fully checked. It the student tries to go directly to attempt.php for an attempt that they started in a previous session, it will redirect them to startattempt.php.
processattempt.phpWhen you submit the form on attempt.php, it will POST the data to this page. This page just does step 3. above, that is process the responses. Once it has done the processing, it redirects the student pack to attempt.php (or review.php if they did submit all and finish).
It does the same simple checks on the validity of attemptid that attempt.php does, but is slightly more flexible about submissions very close to the cutoff date.
startattempt.phpThis is used to create a new attempt (or preview), or resume an attempt that was started in a previous login session. It does all the checks about whether the student should be allowed to start an attempt now, from this IP address, etc.
Then, if all is OK, and if we are starting a new attempt, it creates that attempt and initialises all the question sessions either from scratch or from the previous attempt.
move more code to librariesIn fact, the code to do all the checks will be moved into mod/quiz/locallib, because at the moment a lot of this code is duplicated between attempt.php, and view.php where it decides whether to display a start/continue attempt button.
I am pretty sure this is a sensible plan, so I have documented it, and the rest of the quiz, on this page on the wiki: http://docs.moodle.org/en/Development:Quiz_user_interface_overview
Update: I have logged this as MDL-9299.