Response Storage

Contents

Purpose and Description

Responses are an attribute of the $state object. Questiontypes are completely free to implement the storage mechanism of their responses (and other state information) the way they want. Still, the default questiontypes all follow a similar model. The default storage model and the questiontype specific variations are explained below.

The runtime model needs some more standardisation to work generically. Therefore it imposes some constraints by convention, which are explained later on the page.

Questiontype Methods

The flexibility for the questiontypes to choose their response storage mechanism freely and to convert from the storage model to the runtime model is provided by a set of three functions, which allow to initialise the runtime $state->responses field, to convert from the runtime to the storage model and vice versa:

The following method descriptions are adapted from the phpdoc comments in locallib.php.

create_session_and_responses

Initializes the $state object, in particular the $state->responses field, but also any other state (or session) information.

This function is called to start a question session. Empty question type specific session data (if any) and empty response data is added to the $state object. Session data is any data which must persist throughout the quiz attempt, possibly with updates as the user interacts with the question. This function does not create new entries in the database for the session; a call to the save_session_and_responses method will occur to do this.

restore_session_and_responses

Restores the session data and most recent responses for the given state.

This function loads any session data associated with the question session in the given state from the database into the $state object. In particular it loads the responses that have been saved for the given $state into the $state->responses field.

Questiontypes with only a single form field for the student's response will not need to restore the responses; the value of the answer field in the quiz_states table is restored to $state->responses[''] automatically before this function is called. Questiontypes with more response fields should override this method and set the $state->responses field to an associative array of responses.

save_session_and_responses

Saves the session data and responses for the given question and state.

This function saves the question type specific session data from the $state object to the database. In particular, for most questiontypes, it saves the responses from the $state->responses field of the $state object. The questiontype non-specific data for the state has already been saved in the quiz_states table and the $state object contains the corresponding id and sequence number, which may be used to index a question type specific table.

Questiontypes with only a single form field for the student's response, which is contained in $state->responses[''] will not have to save this response. It will already have been saved to the answer field of the quiz_states table. Questiontypes with more response fields should override this method and save the responses in their own database tables.

Response Storage

The generic quiz module code saves the contents form the $state->responses[''] field to the answer field in the quiz_states table and also automatically restores the contents of this field to $state->responses['']. This means that any questiontype, which only expects a single value as its response can skip the implementation of the three methods described above. All questiontypes that have multiple value responses need to implement these methods. The default questiontypes handle this problem by serializing/de-serializing the responses to/from the answer field in the quiz_states table. However, it is also possible (and may be better practice) to extend the quiz_states table with a questiontype specific table, i.e. take the id of the quiz_states record as a foreign key in the questiontype specific table. Because the value of $state->responses[''] is set to the value of the answer field, questiontypes that serialize their response need to overwrite (in save_session_and_responses) whatever value the generic code set this field to with their serialized value (usually achieved with a simple set_field). In the method restore_session_and_responses the serialized value can be read from $state->responses['']. Care needs to be taken that this array value is then unset or the whole array overwritten, so that the array does not accidentally contain a value with the empty string index.

Runtime Model

The runtime model for responses dictates the structure of the $state->responses array. Starting with the names of the form elements this section goes through the relevant processing steps and thus attempts to clarify why the indices of the $state->responses array can differ for different questiontypes; even more, it explains how the indicies are chosen and set.

Although it may initially seem strange to start with the naming convention of the form fields, the reason for this will become clear later on. The controls (i.e. the form fields) of a question get printed by the method print_question_formulation_and_controls. The convention only dictates, that the name of the control element(s) must begin with the value of $question->name_prefix. The $question->name_prefix is a string starting with "resp" followed by the question id and an underscore, e.g. resp56_. In the default case, when there is only a single control element (this includes a list of equally named radio buttons), no postfix is appended to the name prefix. For questiontypes that allow or require multiple form elements, an arbitrary string can be appended to the name prefix to form the name of these form elements. The postfix must not include any relational data (i.e. ids of records in the quiz_answers table), because this can lead to problems with regrading of versioned questions.

After the printing of the question the server only sees it again when it is submitted. So the submitted data will contain several values indexed by strings starting with respXX_. Upon submission, the function quiz_process_responses is called, which assigns the submitted responses to the state of the question with id XX, using the postfix (i.e. everything after the underscore) as array indices. In the default case with only one control element the name only consists of the name prefix. This explains why the default index of the $state->responses array is the empty string. The value of each array element is obviously the value that was submitted by the form, basically a raw response.

The function quiz_process_responses in turn calls the questiontype specific method grade_responses to assign a grade to the submitted responses and compare_responses to determine whether the response was identical to the previous submission and to avoid regrading the same responses repeatedly. These questiontype specific functions need to be aware of the expected indicies of the $state->responses array.

Finally, the methods restore_session_and_responses and save_session_and_responses also need to know the questiontype specific layout of the $state->responses array and restore or save the information, e.g. by converting from or to the data representation.

Responses by Questiontype

Calculated

The calculated questiontype inherits its methods create_session_and_responses, restore_session_and_responses and save_session_and_responses from the abstract dataset dependent questiontype. This questiontype serializes the information of the chosen dataset together with the (single) response value into a string of the format datasetXX-RESPONSE, where dataset is the actual string "dataset", XX is the number of the chosen dataset item and RESPONSE is the value that was recieved from the submitted form.

Description

The description questiontype does not have responses.

Match

Note: This will be changed soon, so the description is pending.

Multianswer

The serialized format of multianswer questions is a comma separated list of pairs. Each pair saves the reponse for one of the subquestions and is itself separated with a hyphen ('-'). In front of the hyphen there is the sequence number of the subquestion (starting at 1 incremented by the order the subquestions apear in the text). After the hyphen is the raw response, that was submitted by the student. The serialized format could look like the following example:
1-34,2-Napoleon,3-4,4-correct response,5-1
All commas and hyphens that are part of the raw answer are HTML entity encoded to avoid problems.

Multichoice

Note: This will be changed soon, so the description is pending.

Numerical

The numerical questiontype, which inherits the function print_question_formulation_and_controls from the shortanswer questiontype, has only one response field, so its responses are handled by the default questiontype. The response is stored without any modifications in the answer field of the table quiz_states.

Random

The random questiontype saves one state with a question id in the answer field to indicate which question was randomly selected. From that point onwards only states for the chosen question are saved.

RandomSAMatch

Note: This will be changed soon, so the description is pending.

Shortanswer

The shortanswer questiontype is the ideal example of the default case. It does not overwrite any of the default implementations of the three methods mentioned above, because it uses the default $state->responses array indexed with the empty string. The value entered into the shortanswer input field is entered directly into the answer field.

Truefalse

Note: This will be changed soon, so the description is pending.