Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402] [Versions 402 and 403]

This file defines the class {@link question_definition} and its subclasses. The type hierarchy is quite complex. Here is a summary: - question_definition - question_information_item - question_with_responses implements question_manually_gradable - question_graded_automatically implements question_automatically_gradable - question_graded_automatically_with_countback implements question_automatically_gradable_with_countback - question_graded_by_strategy

Copyright: 2009 The Open University
License: http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
File Size: 1147 lines (45 kb)
Included or required: 1 time
Referenced: 9 times
Includes or requires: 0 files

Defines 16 classes

question_definition:: (24 methods):
  __construct()
  get_type_name()
  make_behaviour()
  start_attempt()
  apply_attempt_state()
  validate_can_regrade_with_other_version()
  update_attempt_state_data_for_new_version()
  get_question_summary()
  get_num_variants()
  get_variants_selection_seed()
  get_min_fraction()
  get_max_fraction()
  clear_wrong_from_response()
  get_num_parts_right()
  get_renderer()
  prepare_simulated_post_data()
  get_student_response_values_for_simulation()
  format_text()
  html_to_text()
  format_questiontext()
  format_generalfeedback()
  make_html_inline()
  check_file_access()
  get_question_definition_for_external_rendering()

question_information_item:: (5 methods):
  __construct()
  make_behaviour()
  get_expected_data()
  get_correct_response()
  get_question_summary()

question_manually_gradable:: (6 methods):
  is_gradable_response()
  is_complete_response()
  is_same_response()
  summarise_response()
  un_summarise_response()
  classify_response()

question_classified_response:: (2 methods):
  __construct()
  no_response()

question_automatically_gradable:: (4 methods):
  get_validation_error()
  grade_response()
  get_hint()
  get_right_answer_summary()

question_automatically_gradable_with_countback:: (1 method):
  compute_final_grade()

question_with_responses:: (3 methods):
  classify_response()
  is_gradable_response()
  un_summarise_response()

question_graded_automatically:: (5 methods):
  get_right_answer_summary()
  check_combined_feedback_file_access()
  check_hint_file_access()
  get_hint()
  format_hint()

question_graded_automatically_with_countback:: (1 method):
  make_behaviour()

question_graded_by_strategy:: (6 methods):
  __construct()
  get_correct_response()
  get_matching_answer()
  get_correct_answer()
  grade_response()
  classify_response()

question_answer:: (1 method):
  __construct()

question_hint:: (3 methods):
  __construct()
  load_from_record()
  adjust_display_options()

question_hint_with_parts:: (3 methods):
  __construct()
  load_from_record()
  adjust_display_options()

question_grading_strategy:: (2 methods):
  grade()
  get_correct_answer()

question_response_answer_comparer:: (2 methods):
  get_answers()
  compare_response_with_answer()

question_first_matching_answer_grading_strategy:: (3 methods):
  __construct()
  grade()
  get_correct_answer()


Class: question_definition  - X-Ref

The definition of a question of a particular type.

This class is a close match to the question table in the database.
Definitions of question of a particular type normally subclass one of the
more specific classes {@link question_with_responses},
{@link question_graded_automatically} or {@link question_information_item}.

__construct()   X-Ref
Constructor. Normally to get a question, you call
{@link question_bank::load_question()}, but questions can be created
directly, for example in unit test code.


get_type_name()   X-Ref

return: string the name of the question type (for example multichoice) that this

make_behaviour(question_attempt $qa, $preferredbehaviour)   X-Ref
Creat the appropriate behaviour for an attempt at this quetsion,
given the desired (archetypal) behaviour.

This default implementation will suit most normal graded questions.

If your question is of a patricular type, then it may need to do something
different. For example, if your question can only be graded manually, then
it should probably return a manualgraded behaviour, irrespective of
what is asked for.

If your question wants to do somthing especially complicated is some situations,
then you may wish to return a particular behaviour related to the
one asked for. For example, you migth want to return a
qbehaviour_interactive_adapted_for_myqtype.

param: question_attempt $qa the attempt we are creating a behaviour for.
param: string $preferredbehaviour the requested type of behaviour.
return: question_behaviour the new behaviour object.

start_attempt(question_attempt_step $step, $variant)   X-Ref
Start a new attempt at this question, storing any information that will
be needed later in the step.

This is where the question can do any initialisation required on a
per-attempt basis. For example, this is where the multiple choice
question type randomly shuffles the choices (if that option is set).

Any information about how the question has been set up for this attempt
should be stored in the $step, by calling $step->set_qt_var(...).

param: question_attempt_step The first step of the {@link question_attempt}
param: int $varant which variant of this question to start. Will be between

apply_attempt_state(question_attempt_step $step)   X-Ref
When an in-progress {@link question_attempt} is re-loaded from the
database, this method is called so that the question can re-initialise
its internal state as needed by this attempt.

For example, the multiple choice question type needs to set the order
of the choices to the order that was set up when start_attempt was called
originally. All the information required to do this should be in the
$step object, which is the first step of the question_attempt being loaded.

param: question_attempt_step The first step of the {@link question_attempt}

validate_can_regrade_with_other_version(question_definition $otherversion)   X-Ref
Verify if an attempt at this question can be re-graded using the other question version.

To put it another way, will {@see update_attempt_state_date_from_old_version()} be able to work?

It is expected that this relationship is symmetrical, so if you can regrade from V1 to V3, then
you can change back from V3 to V1.

param: question_definition $otherversion a different version of the question to use in the regrade.
return: string|null null if the regrade can proceed, else a reason why not.

update_attempt_state_data_for_new_version(question_attempt_step $oldstep, question_definition $oldquestion)   X-Ref
Update the data representing the initial state of an attempt another version of this question, to allow for the changes.

What is required is probably most easily understood using an example. Think about multiple choice questions.
The first step has a variable '_order' which is a comma-separated list of question_answer ids.
A different version of the question will have different question_answers with different ids. However, the list of
choices should be similar, and so we need to shuffle the new list of ids in the same way that the old one was.

Note: be sure to return all the data that was originally in $oldstep, while updating the fields that
require it. Otherwise you might break features like 'Each attempt builds on last' in the quiz.

This method should only be called if {@see validate_can_regrade_with_other_version()} did not
flag up a potential problem. So, this method will throw a {@see coding_exception} if it is not
possible to work out a return value.

param: question_attempt_step $oldstep the first step of a {@see question_attempt} at $oldquestion.
param: question_definition $oldquestion the previous version of the question, which $oldstate comes from.
return: array the submit data which can be passed to {@see apply_attempt_state} to start

get_question_summary()   X-Ref
Generate a brief, plain-text, summary of this question. This is used by
various reports. This should show the particular variant of the question
as presented to students. For example, the calculated quetsion type would
fill in the particular numbers that were presented to the student.
This method will return null if such a summary is not possible, or
inappropriate.

return: string|null a plain text summary of this question.

get_num_variants()   X-Ref

return: int the number of vaiants that this question has.

get_variants_selection_seed()   X-Ref

return: string that can be used to seed the pseudo-random selection of a

get_min_fraction()   X-Ref
Some questions can return a negative mark if the student gets it wrong.

This method returns the lowest mark the question can return, on the
fraction scale. that is, where the maximum possible mark is 1.0.

return: float minimum fraction this question will ever return.

get_max_fraction()   X-Ref
Some questions can return a mark greater than the maximum.

This method returns the lowest highest the question can return, on the
fraction scale. that is, where the nominal maximum mark is 1.0.

return: float maximum fraction this question will ever return.

clear_wrong_from_response(array $response)   X-Ref
Given a response, rest the parts that are wrong.

param: array $response a response
return: array a cleaned up response with the wrong bits reset.

get_num_parts_right(array $response)   X-Ref
Return the number of subparts of this response that are right.

param: array $response a response
return: array with two elements, the number of correct subparts, and

get_renderer(moodle_page $page)   X-Ref

param: moodle_page the page we are outputting to.
return: qtype_renderer the renderer to use for outputting this question.

prepare_simulated_post_data($simulatedresponse)   X-Ref
Takes an array of values representing a student response represented in a way that is understandable by a human and
transforms that to the response as the POST values returned from the HTML form that takes the student response during a
student attempt. Primarily this is used when reading csv values from a file of student responses in order to be able to
simulate the student interaction with a quiz.

In most cases the array will just be returned as is. Some question types will need to transform the keys of the array,
as the meaning of the keys in the html form is deliberately obfuscated so that someone looking at the html does not get an
advantage. The values that represent the response might also be changed in order to more meaningful to a human.

See the examples of question types that have overridden this in core and also see the csv files of simulated student
responses used in unit tests in :
- mod/quiz/tests/fixtures/stepsXX.csv
- mod/quiz/report/responses/tests/fixtures/steps00.csv
- mod/quiz/report/statistics/tests/fixtures/stepsXX.csv

Also see {@link https://github.com/jamiepratt/moodle-quiz_simulate}, a quiz report plug in for uploading and downloading
student responses as csv files.

param: array $simulatedresponse an array of data representing a student response
return: array a response array as would be returned from the html form (but without prefixes)

get_student_response_values_for_simulation($realresponse)   X-Ref
Does the opposite of {@link prepare_simulated_post_data}.

This takes a student response (the POST values returned from the HTML form that takes the student response during a
student attempt) it then represents it in a way that is understandable by a human.

Primarily this is used when creating a file of csv from real student responses in order later to be able to
simulate the same student interaction with a quiz later.

param: string[] $realresponse the response array as was returned from the form during a student attempt (without prefixes).
return: string[] an array of data representing a student response.

format_text($text, $format, $qa, $component, $filearea, $itemid,$clean = false)   X-Ref
Apply {@link format_text()} to some content with appropriate settings for
this question.

param: string $text some content that needs to be output.
param: int $format the FORMAT_... constant.
param: question_attempt $qa the question attempt.
param: string $component used for rewriting file area URLs.
param: string $filearea used for rewriting file area URLs.
param: bool $clean Whether the HTML needs to be cleaned. Generally,
return: string the text formatted for output by format_text.

html_to_text($text, $format)   X-Ref
Convert some part of the question text to plain text. This might be used,
for example, by get_response_summary().

param: string $text The HTML to reduce to plain text.
param: int $format the FORMAT_... constant.
return: string the equivalent plain text.

format_questiontext($qa)   X-Ref
No description

format_generalfeedback($qa)   X-Ref
No description

make_html_inline($html)   X-Ref
Take some HTML that should probably already be a single line, like a
multiple choice choice, or the corresponding feedback, and make it so that
it is suitable to go in a place where the HTML must be inline, like inside a <p> tag.

param: string $html to HTML to fix up.
return: string the fixed HTML.

check_file_access($qa, $options, $component, $filearea, $args, $forcedownload)   X-Ref
Checks whether the users is allow to be served a particular file.

param: question_attempt $qa the question attempt being displayed.
param: question_display_options $options the options that control display of the question.
param: string $component the name of the component we are serving files for.
param: string $filearea the name of the file area.
param: array $args the remaining bits of the file path.
param: bool $forcedownload whether the user must be forced to download the file.
return: bool true if the user can access this file.

get_question_definition_for_external_rendering(question_attempt $qa, question_display_options $options)   X-Ref
Return the question settings that define this question as structured data.

This is used by external systems such as the Moodle mobile app, which want to display the question themselves,
rather than using the renderer provided.

This method should only return the data that the student is allowed to see or know, given the current state of
the question. For example, do not include the 'General feedback' until the student has completed the question,
and even then, only include it if the question_display_options say it should be visible.

But, within those rules, it is recommended that you return all the settings for the question,
to give maximum flexibility to the external system providing its own rendering of the question.

param: question_attempt $qa the current attempt for which we are exporting the settings.
param: question_display_options $options the question display options which say which aspects of the question
return: mixed structure representing the question settings. In web services, this will be JSON-encoded.

Class: question_information_item  - X-Ref

This class represents a 'question' that actually does not allow the student
to respond, like the description 'question' type.

__construct()   X-Ref
No description

make_behaviour(question_attempt $qa, $preferredbehaviour)   X-Ref
No description

get_expected_data()   X-Ref
No description

get_correct_response()   X-Ref
No description

get_question_summary()   X-Ref
No description

Interface: question_manually_gradable  - X-Ref

Interface that a {@link question_definition} must implement to be usable by
the manual graded behaviour.

is_gradable_response(array $response)   X-Ref
Use by many of the behaviours to determine whether the student
has provided enough of an answer for the question to be graded automatically,
or whether it must be considered aborted.

param: array $response responses, as returned by
return: bool whether this response can be graded.

is_complete_response(array $response)   X-Ref
Used by many of the behaviours, to work out whether the student's
response to the question is complete. That is, whether the question attempt
should move to the COMPLETE or INCOMPLETE state.

param: array $response responses, as returned by
return: bool whether this response is a complete answer to this question.

is_same_response(array $prevresponse, array $newresponse)   X-Ref
Use by many of the behaviours to determine whether the student's
response has changed. This is normally used to determine that a new set
of responses can safely be discarded.

param: array $prevresponse the responses previously recorded for this question,
param: array $newresponse the new responses, in the same format.
return: bool whether the two sets of responses are the same - that is

summarise_response(array $response)   X-Ref
Produce a plain text summary of a response.

param: array $response a response, as might be passed to {@link grade_response()}.
return: string a plain text summary of that response, that could be used in reports.

un_summarise_response(string $summary)   X-Ref
If possible, construct a response that could have lead to the given
response summary. This is basically the opposite of {@link summarise_response()}
but it is intended only to be used for testing.

param: string $summary a string, which might have come from summarise_response
return: array a response that could have lead to that.

classify_response(array $response)   X-Ref
Categorise the student's response according to the categories defined by
get_possible_responses.

param: $response a response, as might be passed to {@link grade_response()}.
return: array subpartid => {@link question_classified_response} objects.

Class: question_classified_response  - X-Ref

This class is used in the return value from
{@link question_manually_gradable::classify_response()}.

__construct($responseclassid, $response, $fraction)   X-Ref
Constructor, just an easy way to set the fields.

param: string $responseclassid see the field descriptions above.
param: string $response see the field descriptions above.
param: number $fraction see the field descriptions above.

no_response()   X-Ref
No description

Interface: question_automatically_gradable  - X-Ref

Interface that a {@link question_definition} must implement to be usable by
the various automatic grading behaviours.

get_validation_error(array $response)   X-Ref
In situations where is_gradable_response() returns false, this method
should generate a description of what the problem is.

return: string the message.

grade_response(array $response)   X-Ref
Grade a response to the question, returning a fraction between
get_min_fraction() and get_max_fraction(), and the corresponding {@link question_state}
right, partial or wrong.

param: array $response responses, as returned by
return: array (float, integer) the fraction, and the state.

get_hint($hintnumber, question_attempt $qa)   X-Ref
Get one of the question hints. The question_attempt is passed in case
the question type wants to do something complex. For example, the
multiple choice with multiple responses question type will turn off most
of the hint options if the student has selected too many opitions.

param: int $hintnumber Which hint to display. Indexed starting from 0
param: question_attempt $qa The question_attempt.

get_right_answer_summary()   X-Ref
Generate a brief, plain-text, summary of the correct answer to this question.
This is used by various reports, and can also be useful when testing.
This method will return null if such a summary is not possible, or
inappropriate.

return: string|null a plain text summary of the right answer to this question.

Interface: question_automatically_gradable_with_countback  - X-Ref

Interface that a {@link question_definition} must implement to be usable by
the interactivecountback behaviour.

compute_final_grade($responses, $totaltries)   X-Ref
Work out a final grade for this attempt, taking into account all the
tries the student made.

param: array $responses the response for each try. Each element of this
param: int $totaltries The maximum number of tries allowed.
return: numeric the fraction that should be awarded for this

Class: question_with_responses  - X-Ref

This class represents a real question. That is, one that is not a
{@link question_information_item}.

classify_response(array $response)   X-Ref
No description

is_gradable_response(array $response)   X-Ref
No description

un_summarise_response(string $summary)   X-Ref
No description

Class: question_graded_automatically  - X-Ref

This class represents a question that can be graded automatically.

get_right_answer_summary()   X-Ref
No description

check_combined_feedback_file_access($qa, $options, $filearea, $args = null)   X-Ref
Check a request for access to a file belonging to a combined feedback field.

param: question_attempt $qa the question attempt being displayed.
param: question_display_options $options the options that control display of the question.
param: string $filearea the name of the file area.
param: array $args the remaining bits of the file path.
return: bool whether access to the file should be allowed.

check_hint_file_access($qa, $options, $args)   X-Ref
Check a request for access to a file belonging to a hint.

param: question_attempt $qa the question attempt being displayed.
param: question_display_options $options the options that control display of the question.
param: array $args the remaining bits of the file path.
return: bool whether access to the file should be allowed.

get_hint($hintnumber, question_attempt $qa)   X-Ref
No description

format_hint(question_hint $hint, question_attempt $qa)   X-Ref
No description

Class: question_graded_automatically_with_countback  - X-Ref

This class represents a question that can be graded automatically with
countback grading in interactive mode.

make_behaviour(question_attempt $qa, $preferredbehaviour)   X-Ref
No description

Class: question_graded_by_strategy  - X-Ref

This class represents a question that can be graded automatically by using
a {@link question_grading_strategy}.

__construct(question_grading_strategy $strategy)   X-Ref
No description

get_correct_response()   X-Ref
No description

get_matching_answer(array $response)   X-Ref
Get an answer that contains the feedback and fraction that should be
awarded for this resonse.

param: array $response a response.
return: question_answer the matching answer.

get_correct_answer()   X-Ref

return: question_answer an answer that contains the a response that would

grade_response(array $response)   X-Ref
No description

classify_response(array $response)   X-Ref
No description

Class: question_answer  - X-Ref

Class to represent a question answer, loaded from the question_answers table
in the database.

__construct($id, $answer, $fraction, $feedback, $feedbackformat)   X-Ref
Constructor.

param: int $id the answer.
param: string $answer the answer.
param: number $fraction the fraction this answer is worth.
param: string $feedback the feedback for this answer.
param: int $feedbackformat the format of the feedback.

Class: question_hint  - X-Ref

Class to represent a hint associated with a question.
Used by iteractive mode, etc. A question has an array of these.

__construct($id, $hint, $hintformat)   X-Ref
Constructor.

param: int the hint id from the database.
param: string $hint The hint text
param: int the corresponding text FORMAT_... type.

load_from_record($row)   X-Ref
Create a basic hint from a row loaded from the question_hints table in the database.

param: object $row with $row->hint set.
return: question_hint

adjust_display_options(question_display_options $options)   X-Ref
Adjust this display options according to the hint settings.

param: question_display_options $options

Class: question_hint_with_parts  - X-Ref

An extension of {@link question_hint} for questions like match and multiple
choice with multile answers, where there are options for whether to show the
number of parts right at each stage, and to reset the wrong parts.

__construct($id, $hint, $hintformat, $shownumcorrect, $clearwrong)   X-Ref
Constructor.

param: int the hint id from the database.
param: string $hint The hint text
param: int the corresponding text FORMAT_... type.
param: bool $shownumcorrect whether the number of right parts should be shown
param: bool $clearwrong whether the wrong parts should be reset.

load_from_record($row)   X-Ref
Create a basic hint from a row loaded from the question_hints table in the database.

param: object $row with $row->hint, ->shownumcorrect and ->clearwrong set.
return: question_hint_with_parts

adjust_display_options(question_display_options $options)   X-Ref
No description

Interface: question_grading_strategy  - X-Ref

This question_grading_strategy interface. Used to share grading code between
questions that that subclass {@link question_graded_by_strategy}.

grade(array $response)   X-Ref
Return a question answer that describes the outcome (fraction and feeback)
for a particular respons.

param: array $response the response.
return: question_answer the answer describing the outcome.

get_correct_answer()   X-Ref

return: question_answer an answer that contains the a response that would

Interface: question_response_answer_comparer  - X-Ref

This interface defines the methods that a {@link question_definition} must
implement if it is to be graded by the
{@link question_first_matching_answer_grading_strategy}.

get_answers()   X-Ref
No description

compare_response_with_answer(array $response, question_answer $answer)   X-Ref

param: array $response the response.
param: question_answer $answer an answer.
return: bool whether the response matches the answer.

Class: question_first_matching_answer_grading_strategy  - X-Ref

This grading strategy is used by question types like shortanswer an numerical.
It gets a list of possible answers from the question, and returns the first one
that matches the given response. It returns the first answer with fraction 1.0
when asked for the correct answer.

__construct(question_response_answer_comparer $question)   X-Ref

param: question_response_answer_comparer $question (presumably also a

grade(array $response)   X-Ref
No description

get_correct_answer()   X-Ref
No description