mirror of
https://github.com/moodle/moodle.git
synced 2025-02-22 10:57:20 +01:00
217 lines
9.3 KiB
HTML
217 lines
9.3 KiB
HTML
<!DOCTYPE HTML PUBLIC>
|
|
<html>
|
|
<head>
|
|
<title>Attempt.php</title>
|
|
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
|
<!--LINK rel="Stylesheet" type="text/css" href="doc.css"-->
|
|
</head>
|
|
<body>
|
|
|
|
<h1>Attempt.php</h1>
|
|
|
|
<h2>Contents</h2>
|
|
<ul>
|
|
<a href='#description'><li>Description and purpose</li></a>
|
|
<a href='#simple'><li>A simplified perspective</li></a>
|
|
<ul>
|
|
<a href='#simple_start'><li>Starting a new attempt</li></a>
|
|
<a href='#simple_finish'><li>Finishing an attempt</li></a>
|
|
</ul>
|
|
<a href='#complicated'><li>A more complicated perspective</li></a>
|
|
</ul>
|
|
|
|
<a name="description"></a><h2>Description and purpose</h2>
|
|
<p>
|
|
|
|
The attempt.php script is one of the most complicated scripts of the
|
|
quiz module. It is responsible for displaying questions to a user,
|
|
to evaluate and grade the users' responses and additionally it needs
|
|
to take various quiz settings into account and change the behaviour
|
|
of the script accordingly. This script, which is vital for the
|
|
functioning of the quiz module, is explained in this document in some
|
|
detail in order to provide some context and examples for the use of
|
|
the question/state model and to illustrate some of the functions
|
|
provided in locallib.php.
|
|
|
|
</p><p>
|
|
|
|
In addition to the immediate benefit of explaining what happens in attempt.php,
|
|
this piece of documentation should provide an entry point to the quiz module
|
|
code. A number of functions are used in attempt.php that are likely to be used
|
|
in other scripts as well.
|
|
|
|
</p><p>
|
|
|
|
Although the attempt.php script is useful for understanding how user
|
|
interactions are handled, in order to gain an understanding of the
|
|
teacher interface for editing quizzes and questions you should look at edit.php.
|
|
|
|
</p>
|
|
|
|
<a name="simple"></a><h2>A simplified perspective</h2>
|
|
<p>
|
|
|
|
From a simple functional point of view, the responsibilities of attempt.php is
|
|
the handling of attempts at a quiz. This includes displaying questions and
|
|
storing data provided or generated by the users. The interaction could be
|
|
limited to opening the page and thus creating a new attempt and submitting the
|
|
responses back to the server, which causes the responses to be graded. While the
|
|
script is actually more sophisticated and allows to interrupt and continue
|
|
attempts, this two step scenario provides a good starting point and covers the
|
|
core functionality.
|
|
|
|
</p>
|
|
|
|
<a name='simple_start'></a><h3>Starting a new attempt</h3>
|
|
<p>
|
|
|
|
When a new attempt is started the attempt object is created by the function
|
|
<code>quiz_create_attempt()</code> (line 183). It returns an empty <code>
|
|
$attempt</code> object, which is stored in the database immediately to record
|
|
the fact that the student has seen the questions.
|
|
|
|
</p><p>
|
|
|
|
The next step is to load up all questions and to create initial states for all
|
|
of them. Loading up the questions is a two step process: first the question
|
|
records are extracted from the database, then the function <code>
|
|
quiz_get_questions_options()</code> is called. This attaches the name_prefix
|
|
field and calls the questiontype specific <code>get_question_options()</code>
|
|
method for each question record in order to add any required data.
|
|
|
|
</p><pre>
|
|
// Load the questions
|
|
if (!$questions = get_records_sql($sql)) {
|
|
...
|
|
}
|
|
// Load the question type specific information
|
|
if (!quiz_get_question_options($questions)) {
|
|
...
|
|
}
|
|
// Restore the question sessions to their most recent states
|
|
// creating new sessions where required
|
|
if (!$states = quiz_get_states($questions, $attempt)) {
|
|
...
|
|
}
|
|
|
|
</pre><p>
|
|
|
|
After all questions are correctly initialised a state object is created for
|
|
each by the function <code>quiz_get_states()</code>. This
|
|
function is responsible for providing a state for each question and creates a
|
|
new state if there isn't one to be restored. Any newly states are added
|
|
to the database right away.
|
|
|
|
</p><p>
|
|
|
|
At this point all the required data has been generated or loaded, so the last step is
|
|
to print the page. The printing happens towards the end of the attempt.php
|
|
script and, apart from a simple call to <code>print_heading()</code> (line 409),
|
|
is done in a loop through all the question records by calling <code>
|
|
quiz_print_quiz_question()</code> (line 461), which is just a shorthand for
|
|
calling the questiontype specific <code>print_question()</code> method. So, quite
|
|
conveniently, each question is responsible for printing itself. To round up the
|
|
printing, submit buttons and a footer are printed to the bottom of the page.
|
|
|
|
</p>
|
|
|
|
<a name='simple_finish'></a><h3>Processing responses</h3>
|
|
<p>
|
|
|
|
The next logical step after creating and displaying an attempt is that the user
|
|
enters answers for all questions and submits them for marking. Now it is not
|
|
necessary to create a new attempt, because there is already an open existing one
|
|
in the database and the same holds for each question's state. So this time the
|
|
attempt record is loaded from the database. The questions are loaded in the same
|
|
way, by querying for the question records an then attaching any required
|
|
questiontype specific fields by calling the function <code>
|
|
quiz_get_question_options()</code>. Now the call to the function <code>
|
|
quiz_get_states()</code> does actually restore the states from the
|
|
database rather than generate new ones, so the same code works for the two
|
|
scenarios, creating and closing an attempt.
|
|
|
|
</p><p>
|
|
|
|
Now that all data concerning the attempt under discussion has been loaded, the
|
|
responses submitted by the student come to the scene. For each
|
|
question they need to be evaluated and graded. The first step here
|
|
is to determine how to deal with each question and the associated
|
|
responses. In the simplified case this is clear; all responses need
|
|
to be graded, the grades stored and then the attempt needs to be
|
|
closed. However, there are more complicated cases, so the function
|
|
<code> quiz_extract_responses()</code> is called to create the
|
|
<code>$actions</code> array, which acts as a set of instructions for
|
|
the function <code>quiz_process_responses()</code>, a quite
|
|
complicated function, which encapsulates the entire response
|
|
processing for one question and calls out to the questiontype
|
|
specific <code>grade_responses()</code> method for grading.
|
|
|
|
</p><p>
|
|
|
|
After all submitted responses have been processed, the questions are rendered
|
|
in the new states. An exception is if the student has requested to close the
|
|
attempt (or if it is closed automatically due to a time limit). In this case
|
|
the attempt is closed by setting the
|
|
<code>timefinish</code> field to the current time. After this the user is
|
|
redirected to review.php, which, depending on the quiz review settings, shows
|
|
the questions including the student's responses, feedback, grades and correct
|
|
answers.
|
|
|
|
</p>
|
|
|
|
|
|
<a name="complicated"></a><h2>A more complicated perspective</h2>
|
|
<p>
|
|
|
|
Before an attempt may be started there are a series of mandatory and optional
|
|
checks, to determine if the user is allowed to attempt the quiz. In addition to
|
|
these checks, the page display and functionality are slightly different for
|
|
users with and without teacher privileges. Also, when the quiz is set to start
|
|
in "secure" mode (the $quiz->popup option), the printing of the page is slightly
|
|
different. Including all of these scenarios evidently complicates the structure
|
|
of the attempt.php script, deviating from the simple scenario described above.
|
|
|
|
</p><p>
|
|
|
|
First of all, access to the quiz is denied to guests. Additionally it is
|
|
possible to restrict acces to an IP range ($quiz->subnet) and to set up a
|
|
password for the quiz ($quiz->password). In both cases users that can't pass the
|
|
required tests are denied access.
|
|
|
|
</p><p>
|
|
|
|
When a teacher "attempts" a quiz there is a tab navigation facility at the top
|
|
of the page, which allows the teacher to jump between reviewing, previewing and
|
|
editing the quiz (and possibly even more options). The teacher interface also
|
|
contains a button to start a new attempt, which is not present on the student
|
|
interface. Teachers' attempts are automatically marked as previews, which means
|
|
that old attempts are automatically deleted when a new attempt is started. It
|
|
also prevents previews to show up in the students' answers review and preview
|
|
attempts don't block the possibility of editing the quiz, while students'
|
|
attempts do.
|
|
|
|
</p><p>
|
|
|
|
Further complication is introduced by the feature to allow multiple pages with
|
|
questions and navigation between these pages. This requieres mechanisms to
|
|
determine which questions are on which page, which page is currently displayed
|
|
and which page needs to be viewed next. This is not too hard to achieve,
|
|
however, one subtlety should be noted: when the attempt is closed it is
|
|
necessary to load all questions and their most recent states before they are
|
|
marked, whereas in the case of navgation only the questions and related states
|
|
of the page that was displayed before are loaded, processed and saved; and the
|
|
questions and states for the next page are loaded.
|
|
|
|
</p><p>
|
|
|
|
Towards the end of the script there are two blocks of code that are responsible
|
|
for timed quizzes ($quiz->timelimit). The first block prints the start element
|
|
of the form using javascript to make sure that javascript is enabled (which
|
|
obviously doesn't help a lot, because the quiz is printed as usual, only the
|
|
submit won't work). The second block includes the file jstimer.php, which prints
|
|
a timer that counts down and causes an auto-submit when time is up.
|
|
|
|
</p>
|
|
</body>
|
|
</html>
|