-
Notifications
You must be signed in to change notification settings - Fork 305
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start documenting core_question and qbank_
- Loading branch information
Showing
4 changed files
with
185 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
--- | ||
title: Question type plugins | ||
tags: | ||
- Plugins | ||
- Question | ||
- qtype | ||
description: Question type plugins implement the different types of question that the core Question subsystem can handle. | ||
--- | ||
|
||
Question types are one of the plugins used by the question subsystem. To see how they fit in, please read | ||
[this overview of the question subsystems](../subsystems/question/). | ||
|
||
Question types have to do many things: | ||
|
||
1. `edit_..._form.php` - Provide an editing form so that teachers can create and edit questions of this type. | ||
2. `questiontypes.php` - Define a class to handle loading and saving data from this form. | ||
3. ... and related methods providing metadata about this question types. | ||
4. ... and import and export in any Question formats that the type wants to support. | ||
5. `question.php` - this class represents one instance of this question type, while it is being attempted by a user. It must do many things | ||
6. ... Start a new attempt (e.g. in a multiple choice question, this is where we randomly shuffle the choices). | ||
7. ... or if we are continuing an existing attmept, re-initalise the question to the same state, using the data from the DB. | ||
8. ... Tell the question engine what data this question type is expecting to be submitted. | ||
9. ... Analyse those submitted responses: e.g. has it changed? is it complete. | ||
10. ... Automatically grade the response to give a 'fraction' (mark between 0 and 1) and a state (correct / partially correct / incorrect). | ||
11. ... check access to files for the file API. | ||
12. `renderer.php` - to display the key bits of this question types for the `core_question_renderer` to combine into the overall question display. | ||
13. Implements Backup and restore, and all the other standard parts of a Moodle plugin like DB tables. | ||
14. Track [users preferences for the settings used for newly created questions](./qtype/newquestiondefaults). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
--- | ||
title: Question type plugins - defaults for new questions | ||
tags: | ||
- Plugins | ||
- Question | ||
- qtype | ||
description: A way for question types to remember a user's preferred settings for creating questions of a given type. | ||
documentationDraft: true | ||
--- | ||
|
||
Many question types are quite flexible, and so have a lot of options on their editing form. Quite often, when a teacher | ||
is creating a number of questions, it is likely that the teacher will want to keep using the same values for some options. | ||
Therefore, the question system has a way for question types to easily save certain settings, and re-use them. | ||
|
||
Note, this is only done when a teacher creates and saves a new question. We don't save the preferences when a teacher edits | ||
an existing question (which might have been created by someone else with different preferences). | ||
|
||
Here is how you implement this: | ||
|
||
### Decide which settings should be saved | ||
|
||
It does not make sense to save all settings. For example, it woule by stupid to remember the name and question text, | ||
because these are things that make a particular question what it is, and will alwasy be different. So, we only want to | ||
save settings where that makes sense. For example do you want the choices in your multiple-choice question numbered | ||
'a, b, c, ...' or '1, 2, 3, ...' or not numbered at all? You need to think about this. Looking through what other question | ||
types do is probably a good way to get a feel for what sorts of things it makes sense to remember. | ||
|
||
### In the form class - use any previously saved defaults | ||
|
||
Before implementing this feature, your form class is likely to have code like | ||
|
||
```php | ||
$mform->setDefault('shuffleanswers', 1); | ||
``` | ||
|
||
For all the settings where you want to implement this feature, need to change the hard-coded default (`1` here) to instead | ||
fetch the default from the user's preferences using the `get_default_value` method: | ||
|
||
```php | ||
$mform->setDefault('shuffleanswers', $this->get_default_value('shuffleanswers', 1)); | ||
``` | ||
|
||
### In the question-type class | ||
|
||
Here we need to override the method `save_defaults_for_new_questions` to save the values these settings. For example: | ||
|
||
```php | ||
public function save_defaults_for_new_questions(stdClass $fromform): void { | ||
parent::save_defaults_for_new_questions($fromform); | ||
$this->set_default_value('shuffleanswers', $fromform->shuffleanswers); | ||
} | ||
``` | ||
|
||
All the settings save here should match the ones fetched by `get_default_value` in the form. | ||
You need to call `parent` because Moodle core saves some of the settings that apply to all question types. | ||
|
||
### Privacy provider | ||
|
||
Because this feature works using user preferences, you need to declare that in your privacy provider. | ||
|
||
This is boring but necessary. Easiest way to see what to do is to [copy another quetion type](https://github.com/moodle/moodle/blob/master/question/type/match/classes/privacy/provider.php). | ||
|
||
Note, it is necessary for your provider to declare the ones saved by core. (I suppose, ideally, someone would make a helpful base class, or trait, to make it easier to implement this.) | ||
|
||
### Automated tests | ||
|
||
Always a good idea. You are likely to need: | ||
|
||
1. [Unit tests for the privacy provider](https://github.com/moodle/moodle/blob/master/question/type/match/tests/privacy/provider_test.php). | ||
2. Behat test to show that the saved settings are re-used. Many question types have | ||
[a `behat/add.feature` file where it is easy to add coverage for this](https://github.com/moodle/moodle/blob/master/question/type/match/tests/behat/add.feature). | ||
|
||
The links in that list go to examples of how these are implemented in `qtype_match`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
--- | ||
title: Questions API | ||
tags: | ||
- API | ||
- Subsystem | ||
- Question | ||
documentationDraft: true | ||
--- | ||
|
||
The question subsystem in Moodle manages the creation, editing and management of interactive questions, | ||
and then enables those questions to be presented to users so they can be attempted. It is useful to | ||
consider these as separate subcomponents. | ||
|
||
## The question engine | ||
|
||
This is the part that makes questions work when users attempt or otherwise interact with questions as part of a learning experience. | ||
|
||
The main user of this in the standard Moodle package is mod_quiz, but there is also qbank_previewquestion, and numerous plugins, includin | ||
[filter_embedquestion](https://moodle.org/plugins/filter_embedquestion). | ||
|
||
The goal of this part of the system is to allow the widest ranges of interactive learning experiences to be created, therefore the question | ||
engine supports two types of plugin: | ||
|
||
### [Question types (qtype_)](../../plugintypes/qtype/index.md) | ||
|
||
This defines what the question is. For example a multiple choice or drag-drop question question, or | ||
a text input question graded as eith a string (e.g. shortanswer or [pattern-match](https://moodle.org/plugins/qtype_pmatch)) | ||
or as a number. It might be something much more complex, like a [crossword](https://moodle.org/plugins/qtype_crossword), or a [coding exercise](https://moodle.org/plugins/qtype_coderunner). | ||
|
||
### Question behaviours (qbehaviour_) | ||
|
||
These let Moodle support different ways for a student to interact with questions. | ||
For example it might be like a classic exams, where initially the student just inputs their answers to all the questions, which are then | ||
only graded, and feedback given later (qbehaviour_deferredfeedback). Or it the student might have a 'Check' button in each question | ||
so their work can be graded immediately (qbahviour_immediatefeebdack). It might even be that after their first try, if that is not right, | ||
the students can immediately Try again, to see if they can correct their mistake based on the initial feedback (qbehaviour_interactive). | ||
|
||
### Core question engine | ||
|
||
So, core question engine mostly serves orchestrates these two plugin types working together to present a attempt at a particular question to a user. | ||
Some key classes here are: | ||
|
||
1. `question_engine` - this class is the main entry point into this part of the API. | ||
2. `question_attempt` - this represents a users attempt at on question. Since most of the time user's attempt a group of related | ||
questions together, and even more important class is `question_usage_by_activity`. | ||
3. `question state` - as stated above, question types and behaviours should have as much freedom as possible to present interesting | ||
educational interactions to users. But, on the other hand, parts of the system that use questions (e.g. the quiz) need to have some | ||
idea what is going on with each question. The various question states try to find an appropriate compromise, so the state of each | ||
question can be tracked, but withough restricting the freedom of the question behaviours to work how they want. | ||
4. `question_display_options` - when questions are used, e.g. in a quiz, there may be limitations one what the user can see. For example, | ||
perhaps the student is only allowed to see the grade and feedback on their attempt after all students have finished. The display options | ||
class is how the quiz can control which bits should be visible when a question is rendered. In addition, depending what state we are in | ||
with the question behviour might also affect what is visible right now, so qbehaviour_plugins can modify the display options based | ||
on the current state of the question_attempt, as part of the rendering process. | ||
5. `core_question_renderer` - renders the overall layout of the questions. It works with the applicable qtype_ and qbehaviour_ renderer to | ||
rendner the details of the current attempt. | ||
|
||
## Question bank | ||
|
||
The question bank provies the UI where teachers create, edit and manage questions. | ||
|
||
### [Question bank plugins (qbank_)](../../plugintypes/qbank/index.md) | ||
|
||
These add features to the qusetion bank. The core question bank code mainly just ties all these features together. | ||
|
||
### Question import/export plugins (qformat_) | ||
|
||
Allow questions to be exported and imported in a variety of formats. Use by plugins like qbank_exportquestions, qbank_importquestions and qbank_exporttoxml. | ||
|
||
### [Question types (qtype_)](../../plugintypes/qtype/index.md) | ||
|
||
Question types do not only interact with the question engine. They also need to work with the question bank, so that teachers | ||
can create and edit questions of their type. |