Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

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

The default questiontype class.

Copyright: 1999 onwards Martin Dougiamas {@link http://moodle.com}
License: http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
File Size: 1662 lines (70 kb)
Included or required: 2 times
Referenced: 4 times
Includes or requires: 0 files

Defines 2 classes

question_type:: (70 methods):
  __construct()
  name()
  plugin_name()
  local_name()
  menu_name()
  is_real_question_type()
  is_manual_graded()
  is_question_manual_graded()
  is_usable_by_random()
  can_analyse_responses()
  has_html_answers()
  extra_question_fields()
  questionid_column_name()
  extra_answer_fields()
  response_file_areas()
  create_editing_form()
  plugin_dir()
  plugin_baseurl()
  get_extra_question_bank_actions()
  display_question_editing_page()
  get_heading()
  set_default_options()
  get_default_value()
  set_default_value()
  save_defaults_for_new_questions()
  save_question()
  save_question_options()
  save_question_answers()
  is_answer_empty()
  fill_answer_fields()
  is_extra_answer_fields_empty()
  fill_extra_answer_fields()
  save_hints()
  count_hints_on_form()
  is_hint_empty_in_form_data()
  save_hint_options()
  save_combined_feedback_helper()
  get_question_options()
  make_question()
  make_question_instance()
  initialise_question_instance()
  initialise_core_question_metadata()
  initialise_question_hints()
  make_hint()
  initialise_custom_fields()
  initialise_combined_feedback()
  initialise_question_answers()
  make_answer()
  delete_question()
  actual_number_of_questions()
  get_random_guess_score()
  break_down_stats_and_response_analysis_by_variant()
  get_possible_responses()
  find_standard_scripts()
  finished_edit_wizard()
  import_from_xml()
  export_to_xml()
  generate_test()
  get_context_by_category_id()
  import_or_save_files()
  move_files()
  move_files_in_answers()
  move_files_in_hints()
  move_files_in_combined_feedback()
  delete_files()
  delete_files_in_answers()
  delete_files_in_hints()
  delete_files_in_combined_feedback()
  import_file()
  decode_file()

question_possible_response:: (2 methods):
  __construct()
  no_response()


Class: question_type  - X-Ref

This is the base class for Moodle question types.

There are detailed comments on each method, explaining what the method is
for, and the circumstances under which you might need to override it.

Note: the questiontype API should NOT be considered stable yet. Very few
question types have been produced yet, so we do not yet know all the places
where the current API is insufficient. I would rather learn from the
experiences of the first few question type implementors, and improve the
interface to meet their needs, rather the freeze the API prematurely and
condem everyone to working round a clunky interface for ever afterwards.

__construct()   X-Ref
No description

name()   X-Ref

return: string the name of this question type.

plugin_name()   X-Ref

return: string the full frankenstyle name for this plugin.

local_name()   X-Ref

return: string the name of this question type in the user's language.

menu_name()   X-Ref
The name this question should appear as in the create new question
dropdown. Override this method to return false if you don't want your
question type to be createable, for example if it is an abstract base type,
otherwise, you should not need to override this method.

return: mixed the desired string, or false to hide this question type in the menu.

is_real_question_type()   X-Ref

return: bool override this to return false if this is not really a

is_manual_graded()   X-Ref

return: bool true if this question type sometimes requires manual grading.

is_question_manual_graded($question, $otherquestionsinuse)   X-Ref

param: object $question a question of this type.
param: string $otherquestionsinuse comma-separate list of other question ids in this attempt.
return: bool true if a particular instance of this question requires manual grading.

is_usable_by_random()   X-Ref

return: bool true if this question type can be used by the random question type.

can_analyse_responses()   X-Ref
Whether this question type can perform a frequency analysis of student
responses.

If this method returns true, you must implement the get_possible_responses
method, and the question_definition class must implement the
classify_response method.

return: bool whether this report can analyse all the student responses

has_html_answers()   X-Ref

return: whether the question_answers.answer field needs to have

extra_question_fields()   X-Ref
If your question type has a table that extends the question table, and
you want the base class to automatically save, backup and restore the extra fields,
override this method to return an array wherer the first element is the table name,
and the subsequent entries are the column names (apart from id and questionid).

return: mixed array as above, or null to tell the base class to do nothing.

questionid_column_name()   X-Ref
If you use extra_question_fields, overload this function to return question id field name
in case you table use another name for this column


extra_answer_fields()   X-Ref
If your question type has a table that extends the question_answers table,
make this method return an array wherer the first element is the table name,
and the subsequent entries are the column names (apart from id and answerid).

return: mixed array as above, or null to tell the base class to do nothing.

response_file_areas()   X-Ref
If the quetsion type uses files in responses, then this method should
return an array of all the response variables that might have corresponding
files. For example, the essay qtype returns array('attachments', 'answers').

return: array response variable names that may have associated files.

create_editing_form($submiturl, $question, $category,$contexts, $formeditable)   X-Ref
Return an instance of the question editing form definition. This looks for a
class called edit_{$this->name()}_question_form in the file
question/type/{$this->name()}/edit_{$this->name()}_question_form.php
and if it exists returns an instance of it.

param: string $submiturl passed on to the constructor call.
return: object an instance of the form definition, or null if one could not be found.

plugin_dir()   X-Ref

return: string the full path of the folder this plugin's files live in.

plugin_baseurl()   X-Ref

return: string the URL of the folder this plugin's files live in.

get_extra_question_bank_actions(stdClass $question)   X-Ref
Get extra actions for a question of this type to add to the question bank edit menu.

This method is called if the {@link edit_menu_column} is being used in the
question bank, which it is by default since Moodle 3.8. If applicable for
your question type, you can return arn array of {@link action_menu_link}s.
These will be added at the end of the Edit menu for this question.

The $question object passed in will have a hard-to-predict set of fields,
because the fields present depend on which columns are included in the
question bank view. However, you can rely on 'id', 'createdby',
'contextid', 'hidden' and 'category' (id) being present, and so you
can call question_has_capability_on without causing performance problems.

param: stdClass $question the available information about the particular question the action is for.
return: action_menu_link[] any actions you want to add to the Edit menu for this question.

display_question_editing_page($mform, $question, $wizardnow)   X-Ref
This method should be overriden if you want to include a special heading or some other
html on a question editing page besides the question editing form.

param: question_edit_form $mform a child of question_edit_form
param: object $question
param: string $wizardnow is '' for first page.

get_heading($adding = false)   X-Ref
Method called by display_question_editing_page and by question.php to get
heading for breadcrumbs.

return: string the heading

set_default_options($questiondata)   X-Ref
Set any missing settings for this question to the default values. This is
called before displaying the question editing form.

param: object $questiondata the question data, loaded from the databsae,

get_default_value(string $name, $default)   X-Ref
Return default value for a given form element either from user_preferences table or $default.

param: string $name the name of the form element.
param: mixed $default default value.
return: string|null default value for a given  form element.

set_default_value(string $name, string $value)   X-Ref
Save the default value for a given form element in user_preferences table.

param: string $name the name of the value to set.
param: string $value the setting value.

save_defaults_for_new_questions(stdClass $fromform)   X-Ref
Save question defaults when creating new questions.

param: stdClass $fromform data from the form.

save_question($question, $form)   X-Ref
Saves (creates or updates) a question.

Given some question info and some data about the answers
this function parses, organises and saves the question
It is used by {@link question.php} when saving new data from
a form, and also by {@link import.php} when importing questions
This function in turn calls {@link save_question_options}
to save question-type specific data.

Whether we are saving a new question or updating an existing one can be
determined by testing !empty($question->id). If it is not empty, we are updating.

The question will be saved in category $form->category.

param: object $question the question object which should be updated. For a
param: object $form the object containing the information to save, as if
param: object $course not really used any more.
return: object On success, return the new question object. On failure,

save_question_options($question)   X-Ref
Saves question-type specific options

This is called by {@link save_question()} to save the question-type specific data
param: object $question  This holds the information from the editing form,
return: object $result->error or $result->notice

save_question_answers($question)   X-Ref
Save the answers, with any extra data.

Questions that use answers will call it from {@link save_question_options()}.
param: object $question  This holds the information from the editing form,
return: object $result->error or $result->notice

is_answer_empty($questiondata, $key)   X-Ref
Returns true is answer with the $key is empty in the question data and should not be saved in DB.

The questions using question_answers table may want to overload this. Default code will work
for shortanswer and similar question types.
param: object $questiondata This holds the information from the question editing form or import.
param: int $key A key of the answer in question.
return: bool True if answer shouldn't be saved in DB.

fill_answer_fields($answer, $questiondata, $key, $context)   X-Ref
Return $answer, filling necessary fields for the question_answers table.

The questions using question_answers table may want to overload this. Default code will work
for shortanswer and similar question types.
param: stdClass $answer Object to save data.
param: object $questiondata This holds the information from the question editing form or import.
param: int $key A key of the answer in question.
param: object $context needed for working with files.
return: $answer answer with filled data.

is_extra_answer_fields_empty($questiondata, $key)   X-Ref
Returns true if extra answer fields for answer with the $key is empty
in the question data and should not be saved in DB.

Questions where extra answer fields are optional will want to overload this.
param: object $questiondata This holds the information from the question editing form or import.
param: int $key A key of the answer in question.
return: bool True if extra answer data shouldn't be saved in DB.

fill_extra_answer_fields($answerextra, $questiondata, $key, $context, $extraanswerfields)   X-Ref
Return $answerextra, filling necessary fields for the extra answer fields table.

The questions may want to overload it to save files or do other data processing.
param: stdClass $answerextra Object to save data.
param: object $questiondata This holds the information from the question editing form or import.
param: int $key A key of the answer in question.
param: object $context needed for working with files.
param: array $extraanswerfields extra answer fields (without table name).
return: $answer answerextra with filled data.

save_hints($formdata, $withparts = false)   X-Ref
No description

count_hints_on_form($formdata, $withparts)   X-Ref
Count number of hints on the form.
Overload if you use custom hint controls.

param: object $formdata the data from the form.
param: bool $withparts whether to take into account clearwrong and shownumcorrect options.
return: int count of hints on the form.

is_hint_empty_in_form_data($formdata, $number, $withparts)   X-Ref
Determine if the hint with specified number is not empty and should be saved.
Overload if you use custom hint controls.

param: object $formdata the data from the form.
param: int $number number of hint under question.
param: bool $withparts whether to take into account clearwrong and shownumcorrect options.
return: bool is this particular hint data empty.

save_hint_options($formdata, $number, $withparts)   X-Ref
Save additional question type data into the hint optional field.
Overload if you use custom hint information.

param: object $formdata the data from the form.
param: int $number number of hint to get options from.
param: bool $withparts whether question have parts.
return: string value to save into the options field of question_hints table.

save_combined_feedback_helper($options, $formdata,$context, $withparts = false)   X-Ref
Can be used to {@link save_question_options()} to transfer the combined
feedback fields from $formdata to $options.

param: object $options the $question->options object being built.
param: object $formdata the data from the form.
param: object $context the context the quetsion is being saved into.
param: bool $withparts whether $options->shownumcorrect should be set.

get_question_options($question)   X-Ref
Loads the question type specific options for the question.

This function loads any question type specific options for the
question from the database into the question object. This information
is placed in the $question->options field. A question type is
free, however, to decide on a internal structure of the options field.
param: object $question The question object for the question. This object
return: bool            Indicates success or failure.

make_question($questiondata)   X-Ref
Create an appropriate question_definition for the question of this type
using data loaded from the database.

param: object $questiondata the question data loaded from the database.
return: question_definition the corresponding question_definition.

make_question_instance($questiondata)   X-Ref
Create an appropriate question_definition for the question of this type
using data loaded from the database.

param: object $questiondata the question data loaded from the database.
return: question_definition an instance of the appropriate question_definition subclass.

initialise_question_instance(question_definition $question, $questiondata)   X-Ref
Initialise the common question_definition fields.

param: question_definition $question the question_definition we are creating.
param: object $questiondata the question data loaded from the database.

initialise_core_question_metadata(question_definition $question, $questiondata)   X-Ref
Initialise the question metadata.

param: question_definition $question the question_definition we are creating.
param: object $questiondata the question data loaded from the database.

initialise_question_hints(question_definition $question, $questiondata)   X-Ref
Initialise question_definition::hints field.

param: question_definition $question the question_definition we are creating.
param: object $questiondata the question data loaded from the database.

make_hint($hint)   X-Ref
Create a question_hint, or an appropriate subclass for this question,
from a row loaded from the database.

param: object $hint the DB row from the question hints table.
return: question_hint

initialise_custom_fields(question_definition $question, $questiondata)   X-Ref
Initialise question custom fields.

param: question_definition $question the question_definition we are creating.
param: object $questiondata the question data loaded from the database.

initialise_combined_feedback(question_definition $question,$questiondata, $withparts = false)   X-Ref
Initialise the combined feedback fields.

param: question_definition $question the question_definition we are creating.
param: object $questiondata the question data loaded from the database.
param: bool $withparts whether to set the shownumcorrect field.

initialise_question_answers(question_definition $question,$questiondata, $forceplaintextanswers = true)   X-Ref
Initialise question_definition::answers field.

param: question_definition $question the question_definition we are creating.
param: object $questiondata the question data loaded from the database.
param: bool $forceplaintextanswers most qtypes assume that answers are

make_answer($answer)   X-Ref
Create a question_answer, or an appropriate subclass for this question,
from a row loaded from the database.

param: object $answer the DB row from the question_answers table plus extra answer fields.
return: question_answer

delete_question($questionid, $contextid)   X-Ref
Deletes the question-type specific data when a question is deleted.

param: int $question the question being deleted.
param: int $contextid the context this quesiotn belongs to.

actual_number_of_questions($question)   X-Ref
Returns the number of question numbers which are used by the question

This function returns the number of question numbers to be assigned
to the question. Most question types will have length one; they will be
assigned one number. The 'description' type, however does not use up a
number and so has a length of zero. Other question types may wish to
handle a bundle of questions and hence return a number greater than one.
param: object $question The question whose length is to be determined.
return: int         The number of question numbers which should be

get_random_guess_score($questiondata)   X-Ref
Calculate the score a monkey would get on a question by clicking randomly.

Some question types have significant non-zero average expected score
of the response is just selected randomly. For example 50% for a
true-false question. It is useful to know what this is. For example
it gets shown in the quiz statistics report.

For almost any open-ended question type (E.g. shortanswer or numerical)
this should be 0.

For selective response question types (e.g. multiple choice), you can probably compute this.

For particularly complicated question types the may be impossible or very
difficult to compute. In this case return null. (Or, if the expected score
is very tiny even though the exact value is unknown, it may appropriate
to return 0.)

param: stdClass $questiondata data defining a question, as returned by
return: number|null either a fraction estimating what the student would

break_down_stats_and_response_analysis_by_variant($questiondata)   X-Ref
Whether or not to break down question stats and response analysis, for a question defined by $questiondata.

param: object $questiondata The full question definition data.
return: bool

get_possible_responses($questiondata)   X-Ref
This method should return all the possible types of response that are
recognised for this question.

The question is modelled as comprising one or more subparts. For each
subpart, there are one or more classes that that students response
might fall into, each of those classes earning a certain score.

For example, in a shortanswer question, there is only one subpart, the
text entry field. The response the student gave will be classified according
to which of the possible $question->options->answers it matches.

For the matching question type, there will be one subpart for each
question stem, and for each stem, each of the possible choices is a class
of student's response.

A response is an object with two fields, ->responseclass is a string
presentation of that response, and ->fraction, the credit for a response
in that class.

Array keys have no specific meaning, but must be unique, and must be
the same if this function is called repeatedly.

param: object $question the question definition data.
return: array keys are subquestionid, values are arrays of possible

find_standard_scripts()   X-Ref
Utility method used by {@link qtype_renderer::head_code()}. It looks
for any of the files script.js or script.php that exist in the plugin
folder and ensures they get included.


finished_edit_wizard($form)   X-Ref
Returns true if the editing wizard is finished, false otherwise.

The default implementation returns true, which is suitable for all question-
types that only use one editing form. This function is used in
question.php to decide whether we can regrade any states of the edited
question and redirect to edit.php.

The dataset dependent question-type, which is extended by the calculated
question-type, overwrites this method because it uses multiple pages (i.e.
a wizard) to set up the question and associated datasets.

param: object $form  The data submitted by the previous page.
return: bool      Whether the wizard's last page was submitted or not.

import_from_xml($data, $question, qformat_xml $format, $extra=null)   X-Ref
No description

export_to_xml($question, qformat_xml $format, $extra=null)   X-Ref
No description

generate_test($name, $courseid=null)   X-Ref
Abstract function implemented by each question type. It runs all the code
required to set up and save a question of any type for testing purposes.
Alternate DB table prefix may be used to facilitate data deletion.


get_context_by_category_id($category)   X-Ref
Get question context by category id

param: int $category
return: object $context

import_or_save_files($field, $context, $component, $filearea, $itemid)   X-Ref
Save the file belonging to one text field.

param: array $field the data from the form (or from import). This will
param: object $context the context the question is in.
param: string $component indentifies the file area question.
param: string $filearea indentifies the file area questiontext,
param: int $itemid identifies the file area.
return: string the text for this field, after files have been processed.

move_files($questionid, $oldcontextid, $newcontextid)   X-Ref
Move all the files belonging to this question from one context to another.

param: int $questionid the question being moved.
param: int $oldcontextid the context it is moving from.
param: int $newcontextid the context it is moving to.

move_files_in_answers($questionid, $oldcontextid,$newcontextid, $answerstoo = false)   X-Ref
Move all the files belonging to this question's answers when the question
is moved from one context to another.

param: int $questionid the question being moved.
param: int $oldcontextid the context it is moving from.
param: int $newcontextid the context it is moving to.
param: bool $answerstoo whether there is an 'answer' question area,

move_files_in_hints($questionid, $oldcontextid, $newcontextid)   X-Ref
Move all the files belonging to this question's hints when the question
is moved from one context to another.

param: int $questionid the question being moved.
param: int $oldcontextid the context it is moving from.
param: int $newcontextid the context it is moving to.
param: bool $answerstoo whether there is an 'answer' question area,

move_files_in_combined_feedback($questionid, $oldcontextid,$newcontextid)   X-Ref
Move all the files belonging to this question's answers when the question
is moved from one context to another.

param: int $questionid the question being moved.
param: int $oldcontextid the context it is moving from.
param: int $newcontextid the context it is moving to.
param: bool $answerstoo whether there is an 'answer' question area,

delete_files($questionid, $contextid)   X-Ref
Delete all the files belonging to this question.

param: int $questionid the question being deleted.
param: int $contextid the context the question is in.

delete_files_in_answers($questionid, $contextid, $answerstoo = false)   X-Ref
Delete all the files belonging to this question's answers.

param: int $questionid the question being deleted.
param: int $contextid the context the question is in.
param: bool $answerstoo whether there is an 'answer' question area,

delete_files_in_hints($questionid, $contextid)   X-Ref
Delete all the files belonging to this question's hints.

param: int $questionid the question being deleted.
param: int $contextid the context the question is in.

delete_files_in_combined_feedback($questionid, $contextid)   X-Ref
Delete all the files belonging to this question's answers.

param: int $questionid the question being deleted.
param: int $contextid the context the question is in.
param: bool $answerstoo whether there is an 'answer' question area,

import_file($context, $component, $filearea, $itemid, $file)   X-Ref
No description

decode_file($file)   X-Ref
No description

Class: question_possible_response  - X-Ref

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

__construct($responseclass, $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