Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

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

Code for handling and processing questions. This is code that is module independent, i.e., can be used by any module that uses questions, like quiz, lesson, etc. This script also loads the questiontype classes. Code for handling the editing of questions is in question/editlib.php

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

Defines 64 functions

  question_reorder_qtypes()
  question_save_qtype_order()
  questions_in_use()
  question_context_has_any_questions()
  match_grade_options()
  question_category_delete_safe()
  question_category_in_use()
  delete_question_bank_entry()
  question_delete_question()
  question_delete_context()
  question_delete_course()
  question_delete_course_category()
  question_save_from_deletion()
  question_delete_activity()
  question_move_question_tags_to_new_context()
  idnumber_exist_in_question_category()
  question_move_questions_to_category()
  move_question_set_references()
  question_move_category_to_context()
  question_preload_questions()
  question_load_questions()
  _tidy_question()
  get_question_options()
  question_sort_tags()
  print_question_icon()
  sort_categories_by_tree()
  question_get_default_category()
  question_get_top_category()
  question_get_top_categories_for_contexts()
  question_make_default_categories()
  question_categorylist()
  question_categorylist_parents()
  get_import_export_formats()
  question_default_export_filename()
  question_has_capability_on()
  question_require_capability_on()
  question_edit_url()
  question_extend_settings_navigation()
  question_get_question_capabilities()
  question_get_all_capabilities()
  question_rewrite_question_urls()
  question_rewrite_question_preview_urls()
  question_pluginfile()
  core_question_question_preview_pluginfile()
  question_page_type_list()
  question_module_uses_questions()
  core_question_find_next_unused_idnumber()
  get_question_bank_entry()
  get_question_version()
  get_next_version()
  is_latest()
  question_preview_url()
  question_preview_popup_params()
  question_hash()
  question_make_export_url()
  question_get_export_single_question_url()
  question_remove_stale_questions_from_category()
  flatten_category_tree()
  add_indented_names()
  question_category_select_menu()
  get_categories_for_contexts()
  question_category_options()
  question_add_context_in_key()
  question_fix_top_names()

Functions that are not part of a class:

question_reorder_qtypes($sortedqtypes, $tomove, $direction)   X-Ref
Move one question type in a list of question types. If you try to move one element
off of the end, nothing will change.

return: array an array $index => $qtype, with $index from 0 to n in order, and
param: array $sortedqtypes An array $qtype => anything.
param: string $tomove one of the keys from $sortedqtypes
param: integer $direction +1 or -1

question_save_qtype_order($neworder, $config = null)   X-Ref
Save a new question type order to the config_plugins table.

param: array $neworder An arra $index => $qtype. Indices should start at 0 and be in order.
param: object $config get_config('question'), if you happen to have it around, to save one DB query.

questions_in_use($questionids)   X-Ref
Check if the question is used.

return: boolean whether any of these questions are being used by any part of Moodle.
param: array $questionids of question ids.

question_context_has_any_questions($context)   X-Ref
Determine whether there are any questions belonging to this context, that is whether any of its
question categories contain any questions. This will return true even if all the questions are
hidden.

return: boolean whether any of the question categories beloning to this context have
param: mixed $context either a context object, or a context id.

match_grade_options($gradeoptionsfull, $grade, $matchgrades = 'error')   X-Ref
Check whether a given grade is one of a list of allowed options. If not,
depending on $matchgrades, either return the nearest match, or return false
to signal an error.

return: false|int|string either 'fixed' value or false if error.
param: array $gradeoptionsfull list of valid options
param: int $grade grade to be tested
param: string $matchgrades 'error' or 'nearest'

question_category_delete_safe($category)   X-Ref
Category is about to be deleted,
1/ All questions are deleted for this question category.
2/ Any questions that can't be deleted are moved to a new category
NOTE: this function is called from lib/db/upgrade.php

param: object|core_course_category $category course category object

question_category_in_use($categoryid, $recursive = false)   X-Ref
Tests whether any question in a category is used by any part of Moodle.

return: boolean whether any question in this category is in use.
param: integer $categoryid a question category id.
param: boolean $recursive whether to check child categories too.

delete_question_bank_entry($entryid)   X-Ref
Check if there is more versions left for the entry.
If not delete the entry.

param: int $entryid

question_delete_question($questionid)   X-Ref
Deletes question and all associated data from the database

It will not delete a question if it is used somewhere, instead it will just delete the reference.

param: int $questionid The id of the question being deleted

question_delete_context($contextid)   X-Ref
All question categories and their questions are deleted for this context id.

return: array only returns an empty array for backwards compatibility.
param: int $contextid The contextid to delete question categories from

question_delete_course($course, $notused = false)   X-Ref
All question categories and their questions are deleted for this course.

return: bool always true.
param: stdClass $course an object representing the activity
param: bool $notused this argument is not used any more. Kept for backwards compatibility.

question_delete_course_category($category, $newcategory, $notused=false)   X-Ref
Category is about to be deleted,
1/ All question categories and their questions are deleted for this course category.
2/ All questions are moved to new category

return: boolean
param: stdClass|core_course_category $category course category object
param: stdClass|core_course_category $newcategory empty means everything deleted, otherwise id of
param: bool $notused this argument is no longer used. Kept for backwards compatibility.

question_save_from_deletion($questionids, $newcontextid, $oldplace, $newcategory = null)   X-Ref
Creates a new category to save the questions in use.

return: mixed false on
param: array $questionids of question ids
param: object $newcontextid the context to create the saved category in.
param: string $oldplace a textual description of the think being deleted,
param: object $newcategory

question_delete_activity($cm, $notused = false)   X-Ref
All question categories and their questions are deleted for this activity.

return: boolean
param: object $cm the course module object representing the activity
param: bool $notused the argument is not used any more. Kept for backwards compatibility.

question_move_question_tags_to_new_context(array $questions, context $newcontext)   X-Ref
This function will handle moving all tag instances to a new context for a
given list of questions.

Questions can be tagged in up to two contexts:
1.) The context the question exists in.
2.) The course context (if the question context is a higher context.
E.g. course category context or system context.

This means a question that exists in a higher context (e.g. course cat or
system context) may have multiple groups of tags in any number of child
course contexts.

Questions in the course category context can be move "down" a context level
into one of their child course contexts or activity contexts which affects the
availability of that question in other courses / activities.

In this case it makes the questions no longer available in the other course or
activity contexts so we need to make sure that the tag instances in those other
contexts are removed.

param: stdClass[] $questions The list of question being moved (must include
param: context $newcontext The Moodle context the questions are being moved to

idnumber_exist_in_question_category($questionidnumber, $categoryid, $limitfrom = 0, $limitnum = 1)   X-Ref
Check if an idnumber exist in the category.

return: array
param: int $questionidnumber
param: int $categoryid
param: int $limitfrom
param: int $limitnum

question_move_questions_to_category($questionids, $newcategoryid)   X-Ref
This function should be considered private to the question bank, it is called from
question/editlib.php question/contextmoveq.php and a few similar places to to the
work of actually moving questions and associated data. However, callers of this
function also have to do other work, which is why you should not call this method
directly from outside the questionbank.

return: bool
param: array $questionids of question ids.
param: integer $newcategoryid the id of the category to move to.

move_question_set_references(int $oldcategoryid, int $newcatgoryid,int $oldcontextid, int $newcontextid, bool $delete = false)   X-Ref
Update the questioncontextid field for all question_set_references records given a new context id

param: int $oldcategoryid Old category to be moved.
param: int $newcatgoryid New category that will receive the questions.
param: int $oldcontextid Old context to be moved.
param: int $newcontextid New context that will receive the questions.
param: bool $delete If the action is delete.

question_move_category_to_context($categoryid, $oldcontextid, $newcontextid)   X-Ref
This function helps move a question cateogry to a new context by moving all
the files belonging to all the questions to the new context.
Also moves subcategories.

param: integer $categoryid the id of the category being moved.
param: integer $oldcontextid the old context id.
param: integer $newcontextid the new context id.

question_preload_questions($questionids = null, $extrafields = '', $join = '', $extraparams = [], $orderby = '')   X-Ref
Given a list of ids, load the basic information about a set of questions from
the questions table. The $join and $extrafields arguments can be used together
to pull in extra data. See, for example, the usage in mod/quiz/attemptlib.php, and
read the code below to see how the SQL is assembled. Throws exceptions on error.

return: array partially complete question objects. You need to call get_question_options
param: array $questionids array of question ids to load. If null, then all
param: string $extrafields extra SQL code to be added to the query.
param: string $join extra SQL code to be added to the query.
param: array $extraparams values for any placeholders in $join.
param: string $orderby what to order the results by. Optional, default is unspecified order.

question_load_questions($questionids, $extrafields = '', $join = '')   X-Ref
Load a set of questions, given a list of ids. The $join and $extrafields arguments can be used
together to pull in extra data. See, for example, the usage in mod/quiz/attempt.php, and
read the code below to see how the SQL is assembled. Throws exceptions on error.

return: array|string question objects.
param: array $questionids array of question ids.
param: string $extrafields extra SQL code to be added to the query.
param: string $join extra SQL code to be added to the query.

_tidy_question($question, $category, array $tagobjects = null, array $filtercourses = null)   X-Ref
Private function to factor common code out of get_question_options().

param: object $question the question to tidy.
param: stdClass $category The question_categories record for the given $question.
param: stdClass[]|null $tagobjects The tags for the given $question.
param: stdClass[]|null $filtercourses The courses to filter the course tags by.

get_question_options(&$questions, $loadtags = false, $filtercourses = null)   X-Ref
Updates the question objects with question type specific
information by calling {@see get_question_options()}

Can be called either with an array of question objects or with a single
question object.

return: bool Indicates success or failure.
param: mixed $questions Either an array of question objects to be updated
param: bool $loadtags load the question tags from the tags table. Optional, default false.
param: stdClass[] $filtercourses The courses to filter the course tags by.

question_sort_tags($tagobjects, $categorycontext, $filtercourses = null)   X-Ref
Sort question tags by course or normal tags.

This function also search tag instances that may have a context id that don't match either a course or
question context and fix the data setting the correct context id.

return: stdClass $sortedtagobjects Sorted tag objects.
param: stdClass[] $tagobjects The tags for the given $question.
param: stdClass $categorycontext The question categories context.
param: stdClass[]|null $filtercourses The courses to filter the course tags by.

print_question_icon($question)   X-Ref
Print the icon for the question type

return: string the HTML for the img tag.
param: object $question The question object for which the icon is required.

sort_categories_by_tree(&$categories, $id = 0, $level = 1)   X-Ref
Returns the categories with their names ordered following parent-child relationships.
finally it tries to return pending categories (those being orphaned, whose parent is
incorrect) to avoid missing any category from original array.

return: array
param: array $categories
param: int $id
param: int $level

question_get_default_category($contextid)   X-Ref
Get the default category for the context.

return: object|bool the default question category for that context, or false if none.
param: integer $contextid a context id.

question_get_top_category($contextid, $create = false)   X-Ref
Gets the top category in the given context.
This function can optionally create the top category if it doesn't exist.

return: bool|stdClass The top question category for that context, or false if none.
param: int $contextid A context id.
param: bool $create Whether create a top category if it doesn't exist.

question_get_top_categories_for_contexts($contextids)   X-Ref
Gets the list of top categories in the given contexts in the array("categoryid,categorycontextid") format.

return: array
param: array $contextids List of context ids

question_make_default_categories($contexts)   X-Ref
Gets the default category in the most specific context.
If no categories exist yet then default ones are created in all contexts.

return: object The default category - the category in the course context
param: array $contexts  The context objects for this context and all parent contexts.

question_categorylist($categoryid)   X-Ref
Get the list of categories.

return: array of question category ids of the category and all subcategories.
param: int $categoryid

question_categorylist_parents(int $categoryid)   X-Ref
Get all parent categories of a given question category in decending order.

return: array of question category ids of all parents categories.
param: int $categoryid for which you want to find the parents.

get_import_export_formats($type)   X-Ref
Get list of available import or export formats

return: array sorted list of import/export formats available
param: string $type 'import' if import list, otherwise export list assumed

question_default_export_filename($course, $category)   X-Ref
Create a reasonable default file name for exporting questions from a particular
category.

return: string the filename.
param: object $course the course the questions are in.
param: object $category the question category.

question_has_capability_on($questionorid, $cap, $notused = -1)   X-Ref
Check capability on category.

return: bool this user has the capability $cap for this question $question?
param: int|stdClass|question_definition $questionorid object or id.
param: string $cap 'add', 'edit', 'view', 'use', 'move' or 'tag'.
param: int $notused no longer used.

question_require_capability_on($question, $cap)   X-Ref
Require capability on question.

return: bool true if the user has the capability. Throws exception if not.
param: int|stdClass|question_definition $question object or id.
param: string $cap 'add', 'edit', 'view', 'use', 'move' or 'tag'.

question_edit_url($context)   X-Ref
Gets the question edit url.

return: string|bool A URL for editing questions in this context.
param: object $context a context

question_extend_settings_navigation(navigation_node $navigationnode, $context, $baseurl = '/question/edit.php')   X-Ref
Adds question bank setting links to the given navigation node if caps are met
and loads the navigation from the plugins.
Qbank plugins can extend the navigation_plugin_base and add their own navigation node,
this method will help to autoload those nodes in the question bank navigation.

return: navigation_node Returns the question branch that was added
param: navigation_node $navigationnode The navigation node to add the question branch to
param: object $context
param: string $baseurl the url of the base where the api is implemented from

question_get_question_capabilities()   X-Ref
Get the array of capabilities for question.

return: array all the capabilities that relate to accessing particular questions.

question_get_all_capabilities()   X-Ref
Get the question bank caps.

return: array all the question bank capabilities.

question_rewrite_question_urls($text, $file, $contextid, $component, $filearea,array $ids, $itemid, array $options=null)   X-Ref
Helps call file_rewrite_pluginfile_urls with the right parameters.

return: string
param: string $text text being processed
param: string $file the php script used to serve files
param: int $contextid context ID
param: string $component component
param: string $filearea filearea
param: array $ids other IDs will be used to check file permission
param: int $itemid item ID
param: array $options options

question_rewrite_question_preview_urls($text, $questionid, $filecontextid, $filecomponent, $filearea, $itemid,$previewcontextid, $previewcomponent, $options = null)   X-Ref
Rewrite the PLUGINFILE urls in part of the content of a question, for use when
viewing the question outside an attempt (for example, in the question bank
listing or in the quiz statistics report).

return: string $questiontext with URLs rewritten.
param: string $text the question text.
param: int $questionid the question id.
param: int $filecontextid the context id of the question being displayed.
param: string $filecomponent the component that owns the file area.
param: string $filearea the file area name.
param: int|null $itemid the file's itemid
param: int $previewcontextid the context id where the preview is being displayed.
param: string $previewcomponent component responsible for displaying the preview.
param: array $options text and file options ('forcehttps'=>false)

question_pluginfile($course, $context, $component, $filearea, $args, $forcedownload, $options = [])   X-Ref
Called by pluginfile.php to serve files related to the 'question' core
component and for files belonging to qtypes.

For files that relate to questions in a question_attempt, then we delegate to
a function in the component that owns the attempt (for example in the quiz,
or in core question preview) to get necessary inforation.

(Note that, at the moment, all question file areas relate to questions in
attempts, so the If at the start of the last paragraph is always true.)

Does not return, either calls send_file_not_found(); or serves the file.

return: array|bool
param: stdClass $course course settings object
param: stdClass $context context object
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.
param: array $options additional options affecting the file serving

core_question_question_preview_pluginfile($previewcontext, $questionid, $filecontext, $filecomponent,$filearea, $args, $forcedownload, $options = [])   X-Ref
Serve questiontext files in the question text when they are displayed in this report.

param: context $previewcontext the context in which the preview is happening.
param: int $questionid the question id.
param: context $filecontext the file (question) context.
param: string $filecomponent the component the file belongs to.
param: string $filearea the file area.
param: array $args remaining file args.
param: bool $forcedownload
param: array $options additional options affecting the file serving.

question_page_type_list($pagetype, $parentcontext, $currentcontext)   X-Ref
Return a list of page types

return: array
param: string $pagetype current page type
param: stdClass $parentcontext Block's parent context
param: stdClass $currentcontext Current context of block

question_module_uses_questions($modname)   X-Ref
Does an activity module use the question bank?

return: bool true if the module uses questions.
param: string $modname The name of the module (without mod_ prefix).

core_question_find_next_unused_idnumber(?string $oldidnumber, int $categoryid)   X-Ref
If $oldidnumber ends in some digits then return the next available idnumber of the same form.

So idnum -> null (no digits at the end) idnum0099 -> idnum0100 (if that is unused,
else whichever of idnum0101, idnume0102, ... is unused. idnum9 -> idnum10.

return: string|null suggested new idnumber for a question in that category, or null if one cannot be found.
param: string|null $oldidnumber a question idnumber, or can be null.
param: int $categoryid a question category id.

get_question_bank_entry(int $questionid)   X-Ref
Get the question_bank_entry object given a question id.

return: false|mixed
param: int $questionid Question id.

get_question_version($questionid)   X-Ref
Get the question versions given a question id in a descending sort .

return: array
param: int $questionid Question id.

get_next_version(int $questionbankentryid)   X-Ref
Get the next version number to create base on a Question bank entry id.

return: int next version number.
param: int $questionbankentryid Question bank entry id.

is_latest(string $version, string $questionbankentryid)   X-Ref
Checks if question is the latest version.

return: bool
param: string $version Question version to check.
param: string $questionbankentryid Entry to check against.

question_preview_url($questionid, $preferredbehaviour = null,$maxmark = null, $displayoptions = null, $variant = null, $context = null)   X-Ref
Generate the URL for starting a new preview of a given question with the given options.

return: moodle_url the URL.
param: integer $questionid the question to preview.
param: string $preferredbehaviour the behaviour to use for the preview.
param: float $maxmark the maximum to mark the question out of.
param: question_display_options $displayoptions the display options to use.
param: int $variant the variant of the question to preview. If null, one will
param: object $context context to run the preview in (affects things like

question_preview_popup_params()   X-Ref
Popup params for the question preview.

return: array that can be passed as $params to the {@see popup_action()} constructor.

question_hash($question)   X-Ref
Creates a stamp that uniquely identifies this version of the question

In future we want this to use a hash of the question data to guarantee that
identical versions have the same version stamp.

return: string A unique version stamp
param: object $question

question_make_export_url($contextid, $categoryid, $format, $withcategories,$withcontexts, $filename)   X-Ref
Create url for question export.

return: moodle_url export file url
param: int $contextid
param: int $categoryid
param: string $format
param: string $withcategories
param: string $withcontexts
param: string $filename

question_get_export_single_question_url($question)   X-Ref
Get the URL to export a single question (exportone.php).

return: moodle_url the requested URL.
param: stdClass|question_definition $question the question definition as obtained from

question_remove_stale_questions_from_category($categoryid)   X-Ref
Remove stale questions from a category.

While questions should not be left behind when they are not used any more,
it does happen, maybe via restore, or old logic, or uncovered scenarios. When
this happens, the users are unable to delete the question category unless
they move those stale questions to another one category, but to them the
category is empty as it does not contain anything. The purpose of this function
is to detect the questions that may have gone stale and remove them.

You will typically use this prior to checking if the category contains questions.

The stale questions (unused and hidden to the user) handled are:
- hidden questions
- random questions

param: int $categoryid The category ID.

flatten_category_tree(&$categories, $id, $depth = 0, $nochildrenof = -1)   X-Ref
Private method, only for the use of add_indented_names().

Recursively adds an indentedname field to each category, starting with the category
with id $id, and dealing with that category and all its children, and
return a new array, with those categories in the right order.

return: array a new array of categories, in the right order for the tree.
param: array $categories an array of categories which has had childids
param: int $id the category to start the indenting process from.
param: int $depth the indent depth. Used in recursive calls.
param: int $nochildrenof

add_indented_names($categories, $nochildrenof = -1)   X-Ref
Format categories into an indented list reflecting the tree structure.

return: array The formatted list of categories.
param: array $categories An array of category objects, for example from the.
param: int $nochildrenof

question_category_select_menu($contexts, $top = false, $currentcat = 0,$selected = "", $nochildrenof = -1)   X-Ref
Output a select menu of question categories.
Categories from this course and (optionally) published categories from other courses
are included. Optionally, only categories the current user may edit can be included.

param: array $contexts
param: bool $top
param: int $currentcat
param: integer $selected optionally, the id of a category to be selected by
param: int $nochildrenof

get_categories_for_contexts($contexts, $sortorder = 'parent, sortorder, name ASC', $top = false)   X-Ref
Get all the category objects, including a count of the number of questions in that category,
for all the categories in the lists $contexts.

return: array of category objects.
param: mixed $contexts either a single contextid, or a comma-separated list of context ids.
param: string $sortorder used as the ORDER BY clause in the select statement.
param: bool $top Whether to return the top categories or not.

question_category_options($contexts, $top = false, $currentcat = 0,$popupform = false, $nochildrenof = -1, $escapecontextnames = true)   X-Ref
Output an array of question categories.

return: array
param: array $contexts The list of contexts.
param: bool $top Whether to return the top categories or not.
param: int $currentcat
param: bool $popupform
param: int $nochildrenof
param: boolean $escapecontextnames Whether the returned name of the thing is to be HTML escaped or not.

question_add_context_in_key($categories)   X-Ref
Add context in categories key.

return: array
param: array $categories The list of categories.

question_fix_top_names($categories, $escape = true)   X-Ref
Finds top categories in the given categories hierarchy and replace their name with a proper localised string.

return: array The same question category list given to the function, with the top category names being translated.
param: array $categories An array of question categories.
param: boolean $escape Whether the returned name of the thing is to be HTML escaped or not.