<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Finns</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Finns"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Finns"/>
	<updated>2026-07-30T18:56:12Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=MoodleNet&amp;diff=64084</id>
		<title>MoodleNet</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=MoodleNet&amp;diff=64084"/>
		<updated>2024-03-05T12:55:09Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Migrate from V2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Moodlenet-logo.png|400px]]&lt;br /&gt;
== What is MoodleNet? ==&lt;br /&gt;
[https://moodle.net/ MoodleNet] is a flexible Open Education Technology platform for curating collections of the best known Open Educational (and other) Resources. You&#039;ll find more general information in the [https://docs.moodle.org/moodlenet/Main_Page MoodleNet user documentation].&lt;br /&gt;
&lt;br /&gt;
If you are looking to get started as a MoodleNet developer, we have some courses on Moodle Academy. Both are a bit old but will be updated soon.&lt;br /&gt;
* [https://moodle.academy/course/view.php?id=13# Introduction to MoodleNet] &lt;br /&gt;
* [https://moodle.academy/course/view.php?id=74 MoodleNet for Developers course with Moodle Academy] &lt;br /&gt;
Checkout issues and releases on https://github.com/moodle/moodlenet&lt;br /&gt;
&lt;br /&gt;
== Current status ==&lt;br /&gt;
We have just released MoodleNet 4.0.0. You can follow the releases on Moodle&#039;s Jira tracker at [https://tracker.moodle.org/projects/MDLNET?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&amp;amp;status=unreleased MDLNET]. &lt;br /&gt;
== Roadmap ==&lt;br /&gt;
See [https://tracker.moodle.org/secure/RapidBoard.jspa?rapidView=120&amp;amp;projectKey=MDLNET&amp;amp;view=detail our work on new features in the tracker].&lt;br /&gt;
== Quick start guide ==&lt;br /&gt;
====System Requirements====&lt;br /&gt;
To install MoodleNet, we recommend using the following on your system:&lt;br /&gt;
*[https://nodejs.org NodeJS] 16 &lt;br /&gt;
*[https://nodejs.org/en/knowledge/getting-started/npm/what-is-npm/ npm] 8&lt;br /&gt;
*[https://www.arangodb.com/ ArangoDB] 3.10&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Later versions should probably work but have not been tested yet.&lt;br /&gt;
====Deploy an ArangoDB instance====&lt;br /&gt;
MoodleNet uses [https://www.arangodb.com/ ArangoDB] as main database&lt;br /&gt;
&lt;br /&gt;
You can choose how and where to deploy your ArangoDB, as long as it can be reached by MoodleNet process&lt;br /&gt;
&lt;br /&gt;
An easy way to install run ArangDB locally as a service is by using Docker[https://hub.docker.com/_/arangodb] e.g. :&lt;br /&gt;
 docker run -d --restart unless-stopped -e ARANGO_NO_AUTH=1 -p 8529:8529 --name=mn-3-db arangodb:3.10&lt;br /&gt;
Possibly tweaking some options as you like, e.g. mounting a volume|directory for data or setting a password&lt;br /&gt;
====Install MoodleNet ====&lt;br /&gt;
Install Moodlenet by simply issuing the following npm command&lt;br /&gt;
 npm create @moodlenet@latest path/to/installation/folder&lt;br /&gt;
That will install all MoodleNet core packages in the chosen folder&lt;br /&gt;
&lt;br /&gt;
it will also create a default configuration file (&#039;&#039;&#039;default.config.json&#039;&#039;&#039;) and a default cryptographic key-pair for the system (&#039;&#039;&#039;default.crypto.privateKey , default.crypto.publicKey&#039;&#039;&#039;)&lt;br /&gt;
====Start MoodleNet process ====&lt;br /&gt;
To start MoodleNet issue the following command from within the installation directory&lt;br /&gt;
 npm start&lt;br /&gt;
open your browser on http://localhost:8080&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notice:&#039;&#039;&#039; on the first run the system will have to compile the webapp, so you&#039;ll get a 404 until ready. It should take a few minutes.&lt;br /&gt;
====MoodleNet configuration file====&lt;br /&gt;
MoodleNet configuration file (&#039;&#039;&#039;default.config.json&#039;&#039;&#039;) holds all static system configs.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how the default config looks like after install:&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;pkgs&amp;quot;: {&lt;br /&gt;
     &amp;quot;@moodlenet/core&amp;quot;: {&lt;br /&gt;
       &amp;quot;baseFsFolder&amp;quot;: &amp;quot;/path/to/installation/dir/fs&amp;quot;,&lt;br /&gt;
       &amp;quot;instanceDomain&amp;quot;: &amp;quot;&amp;lt;nowiki&amp;gt;http://localhost:8080&amp;lt;/nowiki&amp;gt;&amp;quot;,&lt;br /&gt;
       &amp;quot;npmRegistry&amp;quot;: &amp;quot;&amp;lt;nowiki&amp;gt;https://registry.npmjs.org&amp;lt;/nowiki&amp;gt;&amp;quot;,&lt;br /&gt;
       &amp;quot;mainLogger&amp;quot;: {&lt;br /&gt;
         &amp;quot;consoleLevel&amp;quot;: &amp;quot;info&amp;quot;,&lt;br /&gt;
         &amp;quot;file&amp;quot;: {&lt;br /&gt;
           &amp;quot;path&amp;quot;: &amp;quot;./log/moodlenet.%DATE%.log&amp;quot;,&lt;br /&gt;
           &amp;quot;level&amp;quot;: &amp;quot;info&amp;quot;&lt;br /&gt;
         }&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;@moodlenet/crypto&amp;quot;: {&lt;br /&gt;
       &amp;quot;keys&amp;quot;: {&lt;br /&gt;
         &amp;quot;alg&amp;quot;: &amp;quot;RS256&amp;quot;,&lt;br /&gt;
         &amp;quot;type&amp;quot;: &amp;quot;PKCS8&amp;quot;,&lt;br /&gt;
         &amp;quot;private&amp;quot;: &amp;quot;/path/to/installation/dir/default.crypto.privateKey&amp;quot;,&lt;br /&gt;
         &amp;quot;public&amp;quot;: &amp;quot;/path/to/installation/dir/default.crypto.publicKey&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;@moodlenet/arangodb&amp;quot;: {&lt;br /&gt;
       &amp;quot;connectionCfg&amp;quot;: {&lt;br /&gt;
         &amp;quot;url&amp;quot;: &amp;quot;&amp;lt;nowiki&amp;gt;http://localhost:8529&amp;lt;/nowiki&amp;gt;&amp;quot;&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;@moodlenet/http-server&amp;quot;: {&lt;br /&gt;
       &amp;quot;port&amp;quot;: 8080,&lt;br /&gt;
       &amp;quot;defaultRpcUploadMaxSize&amp;quot;: &amp;quot;5MB&amp;quot;&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;@moodlenet/ed-resource&amp;quot;: {&lt;br /&gt;
       &amp;quot;resourceUploadMaxSize&amp;quot;: &amp;quot;1.2GB&amp;quot;&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;@moodlenet/simple-email-auth&amp;quot;: {&lt;br /&gt;
       &amp;quot;newUserNotPublisher&amp;quot;: false&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;@moodlenet/email-service&amp;quot;: {&lt;br /&gt;
       &amp;quot;nodemailerTransport&amp;quot;: {&lt;br /&gt;
         &amp;quot;jsonTransport&amp;quot;: true&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;@moodlenet/system-entities&amp;quot;: {&lt;br /&gt;
       &amp;quot;rootPassword&amp;quot;: &amp;quot;eqhb30x9iq5&amp;quot;&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;@moodlenet/react-app&amp;quot;: {&lt;br /&gt;
       &amp;quot;defaultImageUploadMaxSize&amp;quot;: &amp;quot;1MB&amp;quot;&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
Here are some relevant configs you may want to check and tweak:&lt;br /&gt;
*&#039;&#039;&#039;@moodlenet/arangodb.connectionCfg.url&#039;&#039;&#039; : the default config assumes you installed ArangoDB without password with standard port on the same host&lt;br /&gt;
*&#039;&#039;&#039;@moodlenet/core.baseFsFolder&#039;&#039;&#039; : path (better absolute path instead of relative to MoodleNet process cwd) to the system root folder for system filesystem persistency, if you want to change the system-filesystem-root after the system already run, move or clone the existing folder somewhere else and set this config properly to point to the new path&lt;br /&gt;
*&#039;&#039;&#039;@moodlenet/core.instanceDomain&#039;&#039;&#039; : the public domain of your moodlenet instance (e.g. &amp;lt;nowiki&amp;gt;https://moodlenet.example.com&amp;lt;/nowiki&amp;gt;) - the default one (&amp;lt;nowiki&amp;gt;http://localhost:8080&amp;lt;/nowiki&amp;gt;) is ok for testing and dev&lt;br /&gt;
*&#039;&#039;&#039;@moodlenet/email-service.nodemailerTransport&#039;&#039;&#039; : the [https://nodemailer.com/ nodemailer] [https://nodemailer.com/smtp/ transport configuration] for the system email service. It can be a simple smtp url string, or a [https://nodemailer.com/smtp/ nodemailer standard config object]. &#039;&#039;&#039;Notice&#039;&#039;&#039;: with the default configuration &#039;&#039;&#039;{ &amp;quot;jsonTransport&amp;quot;: true }&#039;&#039;&#039; the system won&#039;t send any email, it will simply log them)&lt;br /&gt;
*&#039;&#039;&#039;@moodlenet/system-entities.rootPassword&#039;&#039;&#039; : a static root password for edge cases - you&#039;ll use it to give the first admin permission to a user (see below) - this property is optional, if not set the root user is disabled&lt;br /&gt;
*&#039;&#039;&#039;@moodlenet/http-server.port&#039;&#039;&#039; : the HTTP server port to listen&lt;br /&gt;
Moodlenet&#039;s HTTP service doesn&#039;t support HTTPS. &lt;br /&gt;
&lt;br /&gt;
It&#039;s always a good practice to back Moodlenet with a HTTP reverse proxy (e.g. nginx, Apache) and it is a must if you want to publish over HTTPS, configuring TLS on it.&lt;br /&gt;
====Default authentication system====&lt;br /&gt;
Moodlenet comes with a simple email+password authentication system (pkg @moodlenet/simple-email-auth) that lets users signup and login with a verified email&lt;br /&gt;
&lt;br /&gt;
Users can sign up with their email, receive in their inbox a confirmation link to click and create their user-account&lt;br /&gt;
====Assign admin privileges to your user====&lt;br /&gt;
As you deploy a new instance, no user is present in the system. &lt;br /&gt;
&lt;br /&gt;
Signup with your email and create your user.&lt;br /&gt;
&lt;br /&gt;
Test login, then logout and browse to the hidden page &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;http://localhost:8080/login/root&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;, here you can type in the &#039;&#039;&#039;rootPassword&#039;&#039;&#039; (specified in config file) to login as root.&lt;br /&gt;
&lt;br /&gt;
Open the avatar menu on top right header, and click &#039;&#039;&#039;admin&#039;&#039;&#039; link&lt;br /&gt;
&lt;br /&gt;
Click on &#039;&#039;&#039;Users&#039;&#039;&#039; section on the left, and see your user listed there. Activate the &#039;&#039;&#039;admin&#039;&#039;&#039; icon to give yourself admin privileges&lt;br /&gt;
&lt;br /&gt;
Now you can log out and login back with your email, see you gained the &#039;&#039;&#039;admin&#039;&#039;&#039; link in your avatar menu&lt;br /&gt;
&lt;br /&gt;
Admins can directly use that admin page feature anytime to assign and remove admin privileges to other users&lt;br /&gt;
== Update the system==&lt;br /&gt;
You can easily upgrade MoodleNet keeping system packages always up-to-date with the minor and patch releases by issuing the command&lt;br /&gt;
 npm update&lt;br /&gt;
from within the installation directory, the same where you start the system&lt;br /&gt;
&lt;br /&gt;
Since MoodleNet is npm-package based, it leverages all npm features for upgrades and new packages installation&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;npm update&#039;&#039;&#039; does not upgrade packages for breaking-change versions (major versions, or minor versions for &#039;&#039;&#039;0.x.y&#039;&#039;&#039; versions, as from [https://github.com/npm/node-semver#caret-ranges-123-025-004 node-semver specs])&lt;br /&gt;
&lt;br /&gt;
In case you need to upgrade MoodleNet system packages to newer major versions you may want to either edit manually the main &#039;&#039;&#039;package.json&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Or, better, use the utility [https://www.npmjs.com/package/npm-check-updates npm-check-updates]:&lt;br /&gt;
 # for a dry run:&lt;br /&gt;
 npx npm-check-updates&lt;br /&gt;
 &lt;br /&gt;
 # to update all packages writing newest version refs in package.json:&lt;br /&gt;
 npx npm-check-updates -u&lt;br /&gt;
 npm update&lt;br /&gt;
== Migrate from V2==&lt;br /&gt;
If you have a v2 running and want to migrate it to v3 , you can use the [https://www.npmjs.com/package/@moodlenet/v2-migrate-v3 @moodlenet/v2-migrate-v3]&lt;br /&gt;
&lt;br /&gt;
The v3 system must have access to Moodlenet-V2 persistencies: &lt;br /&gt;
&lt;br /&gt;
* the running arangoDB instance &lt;br /&gt;
* MN2 filesystem folder as configured in [https://gitlab.com/moodlenet/moodlenet/-/tree/1c8c7eb9b9aa2a3ee912871c670480b3e5fa0f70/packages/ce-platform#set-environment-variables V2 env variable &#039;&#039;&#039;STATICASSETS_FS_ROOT_FOLDER&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
V2 persistencies will be used in read-only&lt;br /&gt;
&lt;br /&gt;
Edit the &#039;&#039;&#039;default.config.json&#039;&#039;&#039; adding a &#039;&#039;&#039;@moodlenet/v2-migrate-v3&#039;&#039;&#039; section beside the others, it should look like that&lt;br /&gt;
     &amp;quot;@moodlenet/v2-migrate-v3&amp;quot;: {&lt;br /&gt;
       &amp;quot;v2DbConnectionCfg&amp;quot;: {&lt;br /&gt;
         &amp;quot;url&amp;quot;: &amp;quot;&amp;lt;nowiki&amp;gt;http://your-mn-v2-arangodb-host:8529&amp;lt;/nowiki&amp;gt;&amp;quot;&lt;br /&gt;
       },&lt;br /&gt;
       &amp;quot;v2AssetFolder&amp;quot;: &amp;quot;/path/to/v2/asset/folder&amp;quot;&lt;br /&gt;
     }&lt;br /&gt;
After Moodlenet v3 is installed (as above but choosing the early 3.0 version &#039;&#039;&#039;npm create @moodlenet@3.0&#039;&#039;&#039; – caution: @3.0.0 wouldn&#039;t work!), issue the following command from the installation folder&lt;br /&gt;
 npm install @moodlenet/v2-migrate-v3@0.5.1&lt;br /&gt;
Then just restart the system, the migration will be done, services will be restarted and you can log in.&lt;br /&gt;
&lt;br /&gt;
After migration completed this package can be safely uninstalled.&lt;br /&gt;
&lt;br /&gt;
==MoodleNet architecture==&lt;br /&gt;
MoodleNet is a full stack TypeScript/JavaScript system using:&lt;br /&gt;
*NodeJs&lt;br /&gt;
**NPM Packages [https://nodejs.org/en/knowledge/getting-started/npm/what-is-npm/]&lt;br /&gt;
**ESM Modules [https://nodejs.org/api/esm.html#introduction]&lt;br /&gt;
*Browsers&lt;br /&gt;
**ReactJs 18 [https://reactjs.org/]&lt;br /&gt;
**HTML5 [https://html.spec.whatwg.org/multipage/]&lt;br /&gt;
**CSS3 [https://www.w3.org/Style/CSS/]&lt;br /&gt;
==MoodleNet development environment ==&lt;br /&gt;
*NodeJs ^16 https://nodejs.org/&lt;br /&gt;
*ArangoDB ^3 (we suggest using [https://www.docker.com/ Docker])&lt;br /&gt;
* We recommend the open source IDE Visual Studio Code https://code.visualstudio.com/&lt;br /&gt;
===Setup development environment ===&lt;br /&gt;
&#039;&#039;&#039;From the command line interface (CLI):&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ensure ArangoDB is running on localhost. You may run it in a Docker container issuing a command as below:&lt;br /&gt;
 docker run -e ARANGO_NO_AUTH=1 -p 8529:8529 --name=mn3-dev arangodb:3.10&lt;br /&gt;
Clone the repository, you may wish to fork it, but that&#039;s not required:&lt;br /&gt;
 git clone &amp;lt;nowiki&amp;gt;https://gitlab.com/moodlenet/moodlenet.git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Change to the project&#039;s folder:&lt;br /&gt;
 cd moodlenet&lt;br /&gt;
Install and initialise the project:&lt;br /&gt;
 npm install&lt;br /&gt;
Install a development server:&lt;br /&gt;
 npm run dev-install-backend my-dev # &amp;lt;- my-dev: an arbitrary dev-installation name&lt;br /&gt;
In the example we chose &#039;&#039;&#039;my-dev&#039;&#039;&#039; as installation name, the tool will then setup a dev installation in &#039;&#039;&#039;./.dev-machines/my-dev&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can create as many dev installations as you wish.&lt;br /&gt;
&lt;br /&gt;
Run development backend:&lt;br /&gt;
 npm run dev-start-backend my-dev # &amp;lt;- my-dev : the name you chose when installed&lt;br /&gt;
The first run of the system may take some time to install.&lt;br /&gt;
&lt;br /&gt;
The default configuration for dev includes the config &#039;&#039;&#039;@moodlenet/react-app.noWebappServer: true&#039;&#039;&#039; that prevents the server to expensively build and serve the webapp,&lt;br /&gt;
&lt;br /&gt;
so you&#039;ll get all backend services served on http://localhost:8080, except for the webapp.&lt;br /&gt;
&lt;br /&gt;
Instead, you&#039;ll want to run a webpack+HMR serving the webapp issuing&lt;br /&gt;
 npm run dev-start-webapp my-dev # &amp;lt;- my-dev: the installation server to point to&lt;br /&gt;
Once all started, browse http://localhost:3000, any edits to webapp related code will be Hot-Module-Replaced&lt;br /&gt;
=== Mono-Repository management with Lerna.js===&lt;br /&gt;
MoodleNet project takes leverages [https://lerna.js.org/ lerna.js] to manage multi-package mono-repository .&lt;br /&gt;
&lt;br /&gt;
Please refer to [https://lerna.js.org/ Lerna documentation] to understand how it manages mono-repo and project-packages dependency linking in the development environment.&lt;br /&gt;
&lt;br /&gt;
Questions? Please take a look in the [https://moodle.org/mod/forum/view.php?id=8726 MoodleNet Community] and [https://tracker.moodle.org/projects/MDLNET/summary Tracker] for answers or to ask for help.&lt;br /&gt;
*[https://moodledev.io/general/development/tracker Using Tracker]&lt;br /&gt;
*[https://www.npmjs.com/package/@moodlenet/ce-platform Code repository]&lt;br /&gt;
*[https://docs.moodle.org/moodlenet/Main_Page MoodleNet user documentation]&lt;br /&gt;
*[https://moodle.org/mod/forum/view.php?id=8726 MoodleNet news and discussion]&lt;br /&gt;
*[https://tracker.moodle.org/secure/RapidBoard.jspa?rapidView=167&amp;amp;view=detail MoodleNet Issue Tracker]&lt;br /&gt;
*[https://gitlab.com/moodlenet/moodlenet/-/issues MoodleNet Gitlab Issues]&lt;br /&gt;
[[es:MoodleNet]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Overview_of_the_Moodle_question_engine&amp;diff=64038</id>
		<title>Overview of the Moodle question engine</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Overview_of_the_Moodle_question_engine&amp;diff=64038"/>
		<updated>2023-11-22T07:37:54Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Database tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Question_engine_2}}&lt;br /&gt;
This page summarises how the new question engine works.&lt;br /&gt;
&lt;br /&gt;
Previous section: [[Question Engine 2:Overview|Design]]&lt;br /&gt;
&lt;br /&gt;
{{Work in progress}}&lt;br /&gt;
&lt;br /&gt;
==What does a question engine have to do?==&lt;br /&gt;
&lt;br /&gt;
We are in a question engine for online assessment. Clearly, we have questions, but we don&#039;t need to worry about them much here, they come from the question bank. We can take them as given.&lt;br /&gt;
&lt;br /&gt;
We are really interested in what happens when a student attempts some questions (for example, when they attempt a quiz). We can handle this by thinking about the student&#039;s attempt at each question separately, and then aggregate those separate question attempts into the set of those that comprise the student&#039;s attempt at a particular activity.&lt;br /&gt;
&lt;br /&gt;
For each question attempt, we need some notion of what state it is currently in (in-progress, completed correctly, ...) whether it has been graded, and if so, what mark was awarded. Also, there may be some state private to the question when it is started. For example the calculated question assigns random values to each variable when the question is attempted, and the choices for a multiple choice question may be shuffled.&lt;br /&gt;
&lt;br /&gt;
Given the current state of a question, we need to be able to display it in HTML. The question may need to be displayed in various ways. For example, perhaps students are not allowed to see the information about the grades awarded yet, but if a teacher reviews it they should see the grades. Teachers may also need to see other bits of interface, like edit links. There may be one or more questions displayed embedded in a particular HTML page, for example a page of a quiz attempt.&lt;br /&gt;
&lt;br /&gt;
Finally, the question needs to move from one state to another. There two sorts of way that can happen. First, the student may have interacted with some questions that have been displayed as part of a HTML page, and then submitted that page. That is, the question engine needs to directly process data submitted as part of a HTTP POST request. Second, the student may have performed some other action (for example clicked the Start attempt or Submit all and finish buttons in the quiz), and as a result, some other part of the Moodle code may wish to cause some questions to change state.&lt;br /&gt;
&lt;br /&gt;
Not only to we need to consider the current state of each question. We also need a record of the whole history of what happened. For example a teacher may wish to review everything the student did. Or, when we regrade an interactive question, we need to play back the entire sequence of what the student did.&lt;br /&gt;
&lt;br /&gt;
To be flexible, the question engine needs to cope with any question-type plug-in. It also needs to be flexible in the ways questions behave. For example some questions can only be graded manually by a teacher. Automatically graded questions can be configured to behave in different ways, for example in interactively with immediate feedback and multiple tries during a single question attempt, or with deferred feedback, where the questions are only graded when the student does submit all and finish.&lt;br /&gt;
&lt;br /&gt;
==The state of a question==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sideblock right&amp;quot; style=&amp;quot;width: 18em;&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;content&amp;quot;&amp;gt;&#039;&#039;Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won&#039;t usually need your flowcharts; they&#039;ll be obvious.&#039;&#039;&#039;&#039; -- Fred Brooks, [http://en.wikipedia.org/wiki/The_Mythical_Man-Month The Mythical Man Month]&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As noted above, a key issues is representing the state of a question that is being attempted, and, indeed, the complete history of the states it has passed through. This is the responsibility of the &#039;&#039;&#039;question_attempt&#039;&#039;&#039; class. As we have noted, we are not just interested in the current state of the question, but the complete history of states a question has been through. Therefore, a question_attempt, largely consists of a list of &#039;&#039;&#039;question_attempt_step&#039;&#039;&#039;s. &lt;br /&gt;
&lt;br /&gt;
===Attempt steps===&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;&#039;question_attempt_step&#039;&#039;&#039; has the following fields:&lt;br /&gt;
; state : The state the question is at this step. This will be a &#039;&#039;&#039;question_state&#039;&#039;&#039; like question_state::$correct.&lt;br /&gt;
; fraction : The score the student got for this question so far. This will start off null, and later change. See the note about scores below.&lt;br /&gt;
; timecreated : The timestamp of when the action that created this state happened.&lt;br /&gt;
; userid : The user whose action created this state. During the attempt, this will be the id of the user who attempted the question, but suppose a teacher manually grades the finished question later, then it will be the id of the teacher.&lt;br /&gt;
&lt;br /&gt;
In addition to these fields, each step has an associative array (that is, name =&amp;gt; value pairs) of extra data. We noted above that the most common cause of a question moving from one state to another was as the result of a HTTP POST request. Well, a POST request basically comprises a set of name =&amp;gt; value pairs. For a typical step, the data array will hold those parts of the post data that belong to this question.&lt;br /&gt;
&lt;br /&gt;
Not all state changes are caused by a POST request. Some are caused by API calls like $quba-&amp;gt;finish_question(...). Internally, all these API calls are handled by converting them to special sets of name =&amp;gt; value pairs. This means that every action is represented in the same way, which makes it much easier to implement processing like re-grading. Internally, every change of action is caused by a call to the $questionattempt-&amp;gt;process_action($dataarray, ...) method. As an example, $quba-&amp;gt;finish_question(...) gets handled by calling $questionattempt-&amp;gt;process_action(array(&#039;!finish&#039; =&amp;gt; 1)).&lt;br /&gt;
&lt;br /&gt;
===A note about scores===&lt;br /&gt;
&lt;br /&gt;
The question engine stores scores in two different ways.&lt;br /&gt;
&lt;br /&gt;
Normally, each question in a, say, quiz attempt, will be worth a certain number of marks. For example, question 1 may be worth 5 marks, question 2 worth 3 marks, and so on.&lt;br /&gt;
&lt;br /&gt;
However, sometimes these marks have to change. For example, perhaps question 2 is now thought to be unsound, and so we want to change the scoring of the quiz so that it now is worth zero marks. But then later we may re-consider, and want to set it back to being worth 3 marks again.&lt;br /&gt;
&lt;br /&gt;
In order to make it easy to handle this sort of change, almost all scores are internally stored on a scale of 0 to 1. Then there is a field $questionattempt-&amp;gt;maxmark. To get the actual mark for a question you need to compute $fraction * $questionattempt-&amp;gt;maxmark.&lt;br /&gt;
&lt;br /&gt;
In the code, things called &#039;&#039;&#039;fraction&#039;&#039;&#039; are always on the 0 to 1 scale; things called &#039;&#039;&#039;mark&#039;&#039;&#039; are always on the scale of fraction * maxmark. Marks are what is displayed to users in the UI.&lt;br /&gt;
&lt;br /&gt;
===More about question attempts===&lt;br /&gt;
&lt;br /&gt;
As mentioned before, a &#039;&#039;&#039;question_attempt&#039;&#039;&#039; is mainly a list of question_attempt_steps. However, it also stores some other important information.&lt;br /&gt;
&lt;br /&gt;
First, we need to know what this attempt is, so there are some links to other objects. There is a link to the &#039;&#039;&#039;question_definition&#039;&#039;&#039; of the question being attempted. There is a link to the &#039;&#039;&#039;question_behaviour&#039;&#039;&#039; that controls how the question behaves. Also, the question_attempt will be part of some student&#039;s work for some activity. For example, it may be part of a quiz attempt. The collection of all question_attempts that make up that quiz attempt (or whatever) is represented by a class called &#039;&#039;&#039;question_usage_by_activity&#039;&#039;&#039;, of which more in a moment. We store the id of this $quba, and the index number of this question within the usage.&lt;br /&gt;
&lt;br /&gt;
Second, there is some metadata, stored in the following fields:&lt;br /&gt;
; maxmark : How many marks this question is worth. All scores that are stored as fractions need to be multiplied by this before being displayed.&lt;br /&gt;
; minfraction : I said above that fraction scores were stored on a scale of 0 to 1. That was a lie. Some questions can return negative marks. For example, a multiple choice question with 5 choices may return +1 for right, and -0.25 for wrong, so that the average score for guessing is 0. Or, if certainty based marking is used, and the student is confident but wrong, they may be awarded a negative mark. The correct statement is that fraction scores are on a scale of minfraction to 1.&lt;br /&gt;
; flagged : Questions can be flagged. This is an on/off boolean that can be toggled by the student. Think of this as a simple form of bookmarking. That is stored here. (The history of changes to the flagged state are not considered important. That is why toggling the flag does not create a new step.)&lt;br /&gt;
&lt;br /&gt;
Thirdly, and finally, some information is recorded to make it easier to run reports efficiently.&lt;br /&gt;
; questionsummary : This is a plain-text summary of the question the student was asked. (This makes most sense if you think of a question with randomisation like calculated questions. This field sumarieses the specific question the student was asked.)&lt;br /&gt;
; responsesummary : This is a plain-text summary of the response the student gave.&lt;br /&gt;
; rightanswer : This is a plain-text summary of what the right answer is.&lt;br /&gt;
&lt;br /&gt;
===Question usages===&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;question_usage_by_activity&#039;&#039;&#039; class, in terms of data storage, is really little more than a list of question attempts.&lt;br /&gt;
&lt;br /&gt;
The little extra comprises:&lt;br /&gt;
; owningplugin : the part of Moodle that this usage belongs to. For example &#039;mod_quiz&#039; or &#039;core_question_preview&#039;.&lt;br /&gt;
; context : the context that the usage belongs to. For a quiz attempt, this will be the quiz context.&lt;br /&gt;
; preferredbehaviour : The behaviour that should be used, where possible, when a question is added to this usage.&lt;br /&gt;
&lt;br /&gt;
===Question behaviours===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
===More on question states===&lt;br /&gt;
&lt;br /&gt;
[[Image:Question_state_diagram.png|right|400px]]&lt;br /&gt;
As above, question_attempt_steps::state field is one of the question_state constants. There are quite a lot of these states (about 16) and the state diagram here may help to understand them.&lt;br /&gt;
&lt;br /&gt;
However, please be aware that although this diagram only shows particular state transitions, it is really up to the behaviour to decide how the question attempt moves from one state to another. Anything is possible, at least in theory. The diagram tried to show what might be sensible.&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Summary of the properties of the various states:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! State         !! is_active !! is_finished !! is_graded !! is_correct !! is_partially_correct !! is_incorrect !! is_gave_up !! is_commented&lt;br /&gt;
|-&lt;br /&gt;
| notstarted    ||           ||             ||           ||            ||                      ||              ||            ||             &lt;br /&gt;
|-&lt;br /&gt;
| unprocessed   ||           ||             ||           ||            ||                      ||              ||            ||             &lt;br /&gt;
|-&lt;br /&gt;
| todo          ||     Y     ||             ||           ||            ||                      ||              ||            ||             &lt;br /&gt;
|-&lt;br /&gt;
| invalid       ||     Y     ||             ||           ||            ||                      ||              ||            ||             &lt;br /&gt;
|-&lt;br /&gt;
| complete      ||     Y     ||             ||           ||            ||                      ||              ||            ||             &lt;br /&gt;
|-&lt;br /&gt;
| needsgrading  ||           ||      Y      ||           ||            ||                      ||              ||            ||             &lt;br /&gt;
|-&lt;br /&gt;
| finished      ||           ||      Y      ||           ||            ||                      ||              ||            ||             &lt;br /&gt;
|-&lt;br /&gt;
| gaveup        ||           ||      Y      ||           ||            ||                      ||              ||     Y      ||             &lt;br /&gt;
|-&lt;br /&gt;
| gradedwrong   ||           ||      Y      ||     Y     ||            ||                      ||      Y       ||            ||             &lt;br /&gt;
|-&lt;br /&gt;
| gradedpartial ||           ||      Y      ||     Y     ||            ||           Y          ||              ||            ||              &lt;br /&gt;
|-&lt;br /&gt;
| gradedright   ||           ||      Y      ||     Y     ||     Y      ||                      ||              ||            ||             &lt;br /&gt;
|-&lt;br /&gt;
| manfinished   ||           ||      Y      ||           ||            ||                      ||              ||            ||      Y      &lt;br /&gt;
|-&lt;br /&gt;
| mangaveup     ||           ||      Y      ||           ||            ||                      ||              ||     Y      ||      Y      &lt;br /&gt;
|-&lt;br /&gt;
| mangrwrong    ||           ||      Y      ||     Y     ||            ||                      ||      Y       ||            ||      Y      &lt;br /&gt;
|-&lt;br /&gt;
| mangrpartial  ||           ||      Y      ||     Y     ||            ||           Y          ||              ||            ||      Y      &lt;br /&gt;
|-&lt;br /&gt;
| mangrright    ||           ||      Y      ||     Y     ||     Y      ||                      ||              ||            ||      Y      &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Database tables==&lt;br /&gt;
&lt;br /&gt;
[[Image:Question engine 2 database.png|right|400px]]&lt;br /&gt;
&lt;br /&gt;
As explained above, all the state is represented by the classes question_usage_by_activity, which is a list of question_attempts, each of which is a list of question_attempt_steps. This is naturally stored in three linked database tables, except that because each step can contain an arbitrary list of name =&amp;gt; value pairs, we get a fourth question_attempt_step_data table. This is shown in the diagram.&lt;br /&gt;
&amp;lt;br style=&amp;quot;clear:both&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Detailed data about an attempt===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
    quiza.userid,&lt;br /&gt;
    quiza.quiz,&lt;br /&gt;
    quiza.id AS quizattemptid,&lt;br /&gt;
    quiza.attempt,&lt;br /&gt;
    quiza.sumgrades,&lt;br /&gt;
    qu.preferredbehaviour,&lt;br /&gt;
    qa.slot,&lt;br /&gt;
    qa.behaviour,&lt;br /&gt;
    qa.questionid,&lt;br /&gt;
    qa.variant,&lt;br /&gt;
    qa.maxmark,&lt;br /&gt;
    qa.minfraction,&lt;br /&gt;
    qa.flagged,&lt;br /&gt;
    qas.sequencenumber,&lt;br /&gt;
    qas.state,&lt;br /&gt;
    qas.fraction,&lt;br /&gt;
    timestamptz &#039;epoch&#039; + qas.timecreated * interval &#039;1 second&#039;,  -- or FROM_UNIXTIME(qas.timecreated) if you are on MySQL.&lt;br /&gt;
    qas.userid,&lt;br /&gt;
    qasd.name,&lt;br /&gt;
    qasd.value,&lt;br /&gt;
    qa.questionsummary,&lt;br /&gt;
    qa.rightanswer,&lt;br /&gt;
    qa.responsesummary&lt;br /&gt;
&lt;br /&gt;
FROM mdl_quiz_attempts quiza&lt;br /&gt;
JOIN mdl_question_usages qu ON qu.id = quiza.uniqueid&lt;br /&gt;
JOIN mdl_question_attempts qa ON qa.questionusageid = qu.id&lt;br /&gt;
JOIN mdl_question_attempt_steps qas ON qas.questionattemptid = qa.id&lt;br /&gt;
LEFT JOIN mdl_question_attempt_step_data qasd ON qasd.attemptstepid = qas.id&lt;br /&gt;
&lt;br /&gt;
WHERE quiza.id = 675767&lt;br /&gt;
&lt;br /&gt;
ORDER BY quiza.userid, quiza.attempt, qa.slot, qas.sequencenumber, qasd.name&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Key processes==&lt;br /&gt;
&lt;br /&gt;
These two sequence diagrams summarise what happens during the two key operations, displaying a page of the quiz, and processing the student&#039;s responses.&lt;br /&gt;
&lt;br /&gt;
[[Image:Question_processing.png|800px]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
In the next section, [[Developing a Question Behaviour|Developing a Question Behaviour]] I describe what a developer will need to do to create a Question behaviour plugin for the new system.&lt;br /&gt;
&lt;br /&gt;
* Back to [[Question_Engine_2|Question Engine 2]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_engine&amp;diff=63886</id>
		<title>Question engine</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_engine&amp;diff=63886"/>
		<updated>2023-05-21T16:19:52Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Question types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Question development}}&lt;br /&gt;
&lt;br /&gt;
Moodle has a powerful question engine with a modular structure to allow question type plug-ins. The question engine is responsible for rendering the questions and for processing student responses. It is used by the [[Quiz developer docs|quiz module]] and it is planned that in future it will be used by the Lesson and other modules.&lt;br /&gt;
&lt;br /&gt;
Historically the question engine started as a part of the quiz module. Only since Moodle 1.6 is it a separate core component of Moodle that can be used by any other Moodle component or module. During this restructuring the code was moved from mod/quiz/ to question/ and the tables and functions were renamed. Wherever the old table or function name contained &#039;quiz_&#039; the new one will contain &#039;question_&#039;&lt;br /&gt;
&lt;br /&gt;
==Terminology==&lt;br /&gt;
&lt;br /&gt;
When talking about the question engine there are certain terms that can cause confusion because they can be used with different meanings. In Moodle we have adopted a certain terminology that will be explained below.&lt;br /&gt;
&lt;br /&gt;
===Questions===&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;&#039;question&#039;&#039;&#039; is the set of definitions (question name, question text, possible answers, grading rules, feedback, etc.) that constitute a reusable assessment item. So it includes much more than what one would in everyday language call a question.&lt;br /&gt;
In the terminology of the [http://en.wikipedia.org/wiki/QTI QTI] specification a &#039;question&#039; is more appropriately called an &#039;&#039;&#039;assessment item&#039;&#039;&#039; or just &#039;item&#039; for short. &lt;br /&gt;
&lt;br /&gt;
There are different types of questions, like for example multiple-choice questions or numerical questions. These are referred to as &#039;&#039;&#039;[[Question engine#Question types|question types]]&#039;&#039;&#039; in Moodle.&lt;br /&gt;
&lt;br /&gt;
Since version 1.5 Moodle is able to handle so-called &#039;&#039;&#039;[[Adaptive questions]]&#039;&#039;&#039;, also known as &#039;adaptive items&#039; in QTI speak. These are questions that interact with the student by going through several states depending on the student responses. For example a complicated mathematical question that is answered incorrectly, but is likely to be incorrect because of a common mistake, could provide the user with a hint towards this mistake, apply a penalty and allow a second attempt at this question. Quizzes can be run in &#039;adaptive mode&#039;, in which case Moodle provides buttons to mark each question individually.&lt;br /&gt;
&lt;br /&gt;
===Answers===&lt;br /&gt;
&lt;br /&gt;
In Moodle the term &#039;&#039;&#039;&#039;answer&#039;&#039;&#039;&#039; is used exclusively for the &#039;&#039;&#039;teacher-defined answers&#039;&#039;&#039; of a question. It is easy to get confused between these teacher-defined answers and the answers that the students actually give. We have therefore adopted the convention to refer to the student-supplied answers as &#039;responses&#039; and to reserve the term &#039;answers&#039; to apply to teacher-defined answers. In question types that rely on teacher-supplied answers these are used in the grading process by comparing them with the student responses. Of course not all question types use teacher-defined answers but use some more intelligent way to process the student responses. &lt;br /&gt;
&lt;br /&gt;
Perhaps one should also stress that &#039;answer&#039; is not always used in the sense of &#039;correct answer&#039;. For example every choice in a multiple-choice question is referred to as an answer. Other systems use the term &#039;distractor&#039; for wrong answers. &lt;br /&gt;
&lt;br /&gt;
In Moodle we always use the term &#039;&#039;&#039;&#039;responses&#039;&#039;&#039;&#039; to refer to the students&#039; responses to a question. This term is always used in plural, although for some questiontypes there is only one possible response.&lt;br /&gt;
&lt;br /&gt;
There is unfortunately, for historical reasons, one exception to the above rule: The question_states table has a field &#039;answer&#039; whose purpose it actually is to hold the student&#039;s responses.&lt;br /&gt;
&lt;br /&gt;
===Attempts===&lt;br /&gt;
&lt;br /&gt;
In Moodle the term &#039;&#039;&#039;&#039;attempt&#039;&#039;&#039;&#039; is used in the sense of &amp;quot;Attempt at a quiz&amp;quot; (or another activity involving questions). Depending on the quiz settings, a student may be allowed several attempts at a quiz. An attempt is finished when the student clicks on the corresponding button on the attempt page. Students do not have to complete an attempt in one visit. They can navigate away from the quiz page and return later to continue the same attempt.&lt;br /&gt;
&lt;br /&gt;
Each module that uses the question engine should hold its own data for the attempts in its own tables. When the module calls the question engine functions it is often expected to pass an attempt object.&lt;br /&gt;
&lt;br /&gt;
Within one and the same quiz attempt a student may make several attempts at answering a particular question, at least if the questiontype allows it and the quiz is set up in adaptive mode. These will always be referred to as &#039;&#039;&#039;&#039;question sessions&#039;&#039;&#039;&#039; or sometimes &#039;attempts at a question, never just as &#039;attempts&#039;.&lt;br /&gt;
&lt;br /&gt;
===Sessions, States, Events===&lt;br /&gt;
&lt;br /&gt;
When a new attempt is started, a new &#039;&#039;&#039;session&#039;&#039;&#039; is started for each question. So in a sense a session is for a question what an attempt is for a whole quiz. A question session lasts no longer than an attempt and for each question there can only by one session within one attempt.&lt;br /&gt;
&lt;br /&gt;
Moodle allows the student to interact with a question repeatedly within one session and each such interaction leads to a new &#039;&#039;&#039;state&#039;&#039;&#039;. The first state is created when the session is created. A new state is then created when a student saves, validates or submits an answer or .... The student&#039;s responses and, if appropriate, the results of response processing (grading) are stored in the new state that gets created.&lt;br /&gt;
&lt;br /&gt;
The type of &#039;&#039;&#039;event&#039;&#039;&#039; that led to the creation of a particular state is saved along with the state. The types of events currently used are:&lt;br /&gt;
;open :A new session has just been created and this is the opening state. Usually it doesn&#039;t hold student responses yet (except where a quiz attempt is based on a previous attempt because the &#039;attemptonlast&#039; option is set).&lt;br /&gt;
;save:The student has clicked the save button.&lt;br /&gt;
;validate:The student has asked for his responses to be validated. This means it is checked that they are valid responses. In the case of mathematical questions which requires the input of a mathematical expression in some linear format the question type may want to display the validated result back to the student in typeset form. Similar things may apply to other subject-specific question types. If a student response is found to be invalid the student is told so but no penalty is applied. The invalid response is stored with the state.&lt;br /&gt;
;grade:The student has pressed the submit button. The grade is calculated and stored with the attempt.&lt;br /&gt;
;duplicategrade:The student has pressed the submit button but the response to this question has not actually changed. This happens a lot in quizzes with several questions on one page where the student may have changed the responses for one question only. I believe that states created by this type of event are not stored in the database.&lt;br /&gt;
;close:The last state in a session which is now closed. Currently a session closes only when the attempt closes, either because the student requests it or because the timelimit elapses.&lt;br /&gt;
&lt;br /&gt;
There are now plans to introduce another event type&lt;br /&gt;
;submit:The student has submitted his responses for grading but grading has not yet taken place. This will be used by teacher-marked question types like the essay questions for example.&lt;br /&gt;
&lt;br /&gt;
==Code documentation==&lt;br /&gt;
&lt;br /&gt;
The code is documented according to [http://www.phpdoc.org/ PHPdocumentor] conventions. The explanations here in the wiki are meant to complement this.&lt;br /&gt;
&lt;br /&gt;
Inline comments should be used liberally in the code. The following conventions make it easier to search for comments with special meaning:&lt;br /&gt;
* use TODO in comments about things that need to be done&lt;br /&gt;
* use ??? in comments that are questions about the code&lt;br /&gt;
&lt;br /&gt;
Code is organised into packages&lt;br /&gt;
* Package questionbank - code that relates to the questionbank system&lt;br /&gt;
** Subpackage questiontypes - code that relates to the question types, including the question type base class.&lt;br /&gt;
** Subpackage importexport - code that relates to importing and exporting questions.&lt;br /&gt;
&lt;br /&gt;
Generally, the base classes default_questiontype and qformat_default should contain most of the documentation, since all question types should follow the same interface. There is no value in repeating the same information on all the various subclasses. The subclasses should concentrate on describing any new methods they have that do not come from the base class.&lt;br /&gt;
&lt;br /&gt;
See the [http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.quickstart.pkg.html#coding.phpcomments PHPdocumentor manual] for more advice on writing good comments.&lt;br /&gt;
&lt;br /&gt;
Moodle PHPdocs can be seen here: http://phpdocs.moodle.org/.&lt;br /&gt;
&lt;br /&gt;
==API==&lt;br /&gt;
&lt;br /&gt;
The library lib/questionlib.php contains all functions that need to be available to any module wanting to use questions (this is new in Moodle 1.6, in Moodle 1.5 this was part of mod/quiz/locallib.php). Loading this library instantiates all questiontype classes by loading the questiontype.php files&lt;br /&gt;
&lt;br /&gt;
A description of the API still needs to be written. Also lib/questionlib.php should be cleaned up a bit to distinguish between the API functions and the helper functions.&lt;br /&gt;
&lt;br /&gt;
==Organisation==&lt;br /&gt;
The default questiontype class is defined in &#039;&#039;&#039;question/type/questiontype.php&#039;&#039;&#039; (in Moodle 1.5 this was still in mod/quiz/locallib.php). The individual questiontypes extend this class in their own questiontype.php file. For documentation of the questiontype classes one should often look at the documentation of the default question type because much of the documentation that is in the default class is not repeated in the other questiontype classes.&lt;br /&gt;
&lt;br /&gt;
While questiontypes are realized as classes, the question engine is not written in a truly object-oriented way. Instead it follows the Moodle model of using objects mostly only as alternatives to arrays to hold database records. So none of the question, attempt, and state objects that play a central role in the module have any methods. Only the questiontype objects have methods. Strangely enough the quiz module instantiates one object of each questiontype class at the start and then reuses their methods for the different questions. If one is used to the Moodle way of programming then this is easy enough to handle.&lt;br /&gt;
&lt;br /&gt;
==Objects and data structures==&lt;br /&gt;
&lt;br /&gt;
Key to understanding how the question engine works is to understand how the different kinds of object work together. The most important ones are:&lt;br /&gt;
&lt;br /&gt;
*Questions&lt;br /&gt;
*Attempts&lt;br /&gt;
*States&lt;br /&gt;
&lt;br /&gt;
Questions are data created by the teacher. Attempts and States are data created by the student when interacting with a quiz. &lt;br /&gt;
&lt;br /&gt;
The Moodle quiz module allows students to make several attempts at a quiz. Data about such an &#039;&#039;&#039;attempt&#039;&#039;&#039; is stored in an attempt object. The Moodle question engine was optimized to deal with such attempts and therefore every module wanting to use the question engine also has to implement the attempt object and pass it to many of the question engine functions. The attempt object holds for example information about how the quiz was randomized for this attempt and the ordering of the questions and answers.&lt;br /&gt;
&lt;br /&gt;
Moodle allows students to interact repeatedly with a single question. So for example the student might initially just save an answer, later mark it, then correct it if it was marked incorrect. When the student first views a question within a particular attempt a &#039;&#039;&#039;question session&#039;&#039;&#039; and the first question state is created. Each time the student interacts with the question a new &#039;&#039;&#039;question state&#039;&#039;&#039; is created. So states are indexed by user id, attempt id and question id.&lt;br /&gt;
&lt;br /&gt;
===Database structure===&lt;br /&gt;
All this data needs to be kept in Moodle&#039;s database. How this is achieved is explained on a separate page about the &#039;&#039;&#039;[[Quiz database structure]]&#039;&#039;&#039;, which also contains a useful diagram.&lt;br /&gt;
&lt;br /&gt;
As is customary in Moodle, most runtime objects simply represent the data from a particular database record. So for example a $quiz object has fields corresponding to all the fields in the [[Quiz database structure#quiz|quiz table]]. In some cases the objects have some additional fields that are added at runtime. This is particularly the case for $question and $state objects. These additional fields are also described on the page about the &#039;&#039;&#039;[[Quiz database structure]]&#039;&#039;&#039;. Many functions that are used to process these objects make use of the additional fields and it is therefore necessary to use the correct functions for creating these objects.&lt;br /&gt;
&lt;br /&gt;
===Runtime objects===&lt;br /&gt;
Some objects used by the quiz module are purely runtime object and do not correspond to a database table. The structure of these objects is explained in detail on a separate page about the &#039;&#039;&#039;[[Quiz runtime objects]]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The main script of the quiz module is attempt.php which will have to deal with all these objects. Studying the &#039;&#039;&#039;[[Quiz attempt|explanation of attempt.php]]&#039;&#039;&#039; is therefore a good way to start to study the quiz module code.&lt;br /&gt;
&lt;br /&gt;
==Response storage==&lt;br /&gt;
&lt;br /&gt;
The student&#039;s responses to a question are stored in &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state-&amp;gt;responses&amp;lt;/syntaxhighlight&amp;gt;. Questiontypes are completely free to implement the storage mechanism of their responses (and other state information) the way they want. Still, the standard questiontypes all follow a similar model. The default storage model and the questiontype specific variations are explained below.&lt;br /&gt;
&lt;br /&gt;
The flexibility for the questiontypes to choose their response storage mechanism freely and to convert from the storage model to the runtime model is provided by a set of three functions, which allow to initialise the runtime &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state-&amp;gt;responses&amp;lt;/syntaxhighlight&amp;gt; field, to convert from the runtime to the storage model and vice versa:&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;create_session_and_responses()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
:Initializes the $state object, in particular the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state-&amp;gt;responses&amp;lt;/syntaxhighlight&amp;gt; field&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;restore_session_and_responses()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
:Loads the question type specific session data from the database into the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state&amp;lt;/syntaxhighlight&amp;gt; object, in particular it loads the responses that have been saved for the given &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state&amp;lt;/syntaxhighlight&amp;gt; into the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state-&amp;gt;responses&amp;lt;/syntaxhighlight&amp;gt; field.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;save_session_and_responses()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
:Saves the question type specific session data from the $state object to the database. In particular, for most questiontypes, it saves the responses from the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state-&amp;gt;responses&amp;lt;/syntaxhighlight&amp;gt; to the database.&lt;br /&gt;
&lt;br /&gt;
The generic quiz module code saves the contents form the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;nowiki&amp;gt;$state-&amp;gt;responses[&#039;&#039;]&amp;lt;/nowiki&amp;gt;&amp;lt;/syntaxhighlight&amp;gt; field to the answer field in the [[Quiz database structure#quiz_states|quiz_states table]] and also automatically restores the contents of this field to &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;nowiki&amp;gt;$state-&amp;gt;responses[&#039;&#039;]&amp;lt;/nowiki&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;. This means that any questiontype, which only expects a single value as its response can skip the implementation of the three methods described above. All questiontypes that have multiple value responses need to implement these methods. &lt;br /&gt;
&lt;br /&gt;
The default questiontypes handle this problem by serializing/de-serializing the responses to/from the answer field in the quiz_states table. However, it is also possible (and may be better practice) to extend the quiz_states table with a questiontype specific table, i.e. take the id of the quiz_states record as a foreign key in the questiontype specific table. Because the value of &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;nowiki&amp;gt;$state-&amp;gt;responses[&#039;&#039;]&amp;lt;/nowiki&amp;gt;&amp;lt;/syntaxhighlight&amp;gt; is set to the value of the answer field, questiontypes that serialize their response need to overwrite (in &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;save_session_and_responses()&amp;lt;/syntaxhighlight&amp;gt;) whatever value the generic code set this field to with their serialized value (usually achieved with a simple set_field). &lt;br /&gt;
&lt;br /&gt;
In the method &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;restore_session_and_responses()&amp;lt;/syntaxhighlight&amp;gt; the serialized value can be read from &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;nowiki&amp;gt;$state-&amp;gt;responses[&#039;&#039;]&amp;lt;/nowiki&amp;gt;&amp;lt;/syntaxhighlight&amp;gt; because this is where the value from answer field of the quiz_states table has been moved. Care needs to be taken that this array value is then unset or the whole array overwritten, so that the array does not accidentally contain a value with the empty string index.&lt;br /&gt;
&lt;br /&gt;
==Response processing==&lt;br /&gt;
&lt;br /&gt;
The runtime model for responses dictates the structure of the $state-&amp;gt;responses array. Starting with the names of the form elements this section goes through the relevant processing steps and thus attempts to clarify why the keys of the $state-&amp;gt;responses array can differ for different questiontypes; even more, it explains how the array keys are chosen and set.&lt;br /&gt;
&lt;br /&gt;
Although it may initially seem strange to start with the naming convention of the form fields, the reason for this will become clear later on. The controls (i.e. the form fields) of a question get printed by the method &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;print_question_formulation_and_controls()&amp;lt;/syntaxhighlight&amp;gt;. The convention only dictates that the name of the control element(s) must begin with the value of &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$question-&amp;gt;name_prefix&amp;lt;/syntaxhighlight&amp;gt;. The &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$question-&amp;gt;name_prefix&amp;lt;/syntaxhighlight&amp;gt; is a string starting with &amp;quot;resp&amp;quot; followed by the question id and an underscore, e.g. &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;resp56_&amp;lt;/syntaxhighlight&amp;gt;. In the default case, when there is only a single control element (this includes the case of a list of equally named radio buttons), no postfix is appended to the name prefix. For questiontypes that allow or require multiple form elements, an arbitrary string can be appended to the name prefix to form the name of these form elements. The postfix must not include any relational data (i.e. ids of records in the quiz_answers table), because this can lead to problems with regrading of versioned questions.&lt;br /&gt;
&lt;br /&gt;
After the printing of the question the server only sees it again when it is submitted. So the submitted data will contain several values indexed by strings starting with &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;respXX_&amp;lt;/syntaxhighlight&amp;gt;. Upon submission, the function &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;quiz_process_responses()&amp;lt;/syntaxhighlight&amp;gt; is called, which assigns the submitted responses to the state of the question with id XX, using the postfix (i.e. everything after the underscore) as array keys. In the default case with only one control element the name only consists of the name prefix. This explains why the default index of the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state-&amp;gt;responses&amp;lt;/syntaxhighlight&amp;gt; array is the empty string. The value of each array element is obviously the value that was submitted by the form, basically a raw response.&lt;br /&gt;
&lt;br /&gt;
The function &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;quiz_process_responses()&amp;lt;/syntaxhighlight&amp;gt; in turn calls the questiontype specific method &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;grade_responses()&amp;lt;/syntaxhighlight&amp;gt; to assign a grade to the submitted responses and &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;compare_responses()&amp;lt;/syntaxhighlight&amp;gt; to determine whether the response was identical to the previous submission and to avoid regrading the same responses repeatedly. These questiontype specific functions need to be aware of the expected keys of the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state-&amp;gt;responses&amp;lt;/syntaxhighlight&amp;gt; array.&lt;br /&gt;
&lt;br /&gt;
Finally, the methods &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;restore_session_and_responses()&amp;lt;/syntaxhighlight&amp;gt; and &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;save_session_and_responses()&amp;lt;/syntaxhighlight&amp;gt; also need to know the questiontype specific layout of the &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$state-&amp;gt;responses array&amp;lt;/syntaxhighlight&amp;gt; and restore or save the information, e.g. by converting from or to the data representation.&lt;br /&gt;
&lt;br /&gt;
==Question types==&lt;br /&gt;
{{Questiontype developer docs}}&lt;br /&gt;
The quiz module is itself modular and allows question type plug-ins. For each question type there should be a page, accessible via the menu at the right, which provides at least the details about&lt;br /&gt;
*Database tables&lt;br /&gt;
*Response storage&lt;br /&gt;
*Question options object&lt;br /&gt;
*State options object&lt;br /&gt;
[[Question type code flow]]&lt;br /&gt;
&lt;br /&gt;
It is hoped that Moodlers will contribute a lot of non-core question types in the future. For this, see [https://docs.moodle.org/en/How_to_write_a_question_type_plugin Question type plugin how to].&lt;br /&gt;
&lt;br /&gt;
==Grades==&lt;br /&gt;
&lt;br /&gt;
The handling of grades is a bit complicated because there are so many different grades around that get rescaled and combined in various ways. This section should summarize how this is done and why.&lt;br /&gt;
&lt;br /&gt;
The following grade fields are being used:&lt;br /&gt;
*$question-&amp;gt;defaultgrade&lt;br /&gt;
::This is the default value for the maximum grade for this question. This is set up when the teacher creates the question and it is stored in an int(10) field in the [[Quiz database structure#quiz_questions|quiz_questions]] table. However when the question is actually used in a particular quiz the teacher can overrule this default and this is stored in:&lt;br /&gt;
*$question-&amp;gt;maxgrade&lt;br /&gt;
::This is the maximum grade that the teacher has assigned to this question in the context of the current quiz. This is by default equal to $questions-&amp;gt;defaultgrade but the teacher can change this when editing the quiz. In the database it is stored in an int(10) field in the [[Quiz database structure#quiz_question_instances|quiz_question_instances table]].&lt;br /&gt;
*$question-&amp;gt;penalty&lt;br /&gt;
&lt;br /&gt;
*$state-&amp;gt;raw_grade&lt;br /&gt;
*$state-&amp;gt;grade&lt;br /&gt;
*$state-&amp;gt;penalty&lt;br /&gt;
*$state-&amp;gt;sumpenalty&lt;br /&gt;
&lt;br /&gt;
*$attempt-&amp;gt;sumgrades&lt;br /&gt;
&lt;br /&gt;
The maximum grades set by the teacher, $question-&amp;gt;defaultgrade and $question-&amp;gt;maxgrade, are integers. All student-obtained grades are in principle floating point numbers. For historical reasons they are stored in the database as varchar(10) fields. Care has to be taken when writing to the database to make sure all grades are correctly rounded and squeezed into a string of no more than 10 characters, otherwise the writing to database will fail, see bug 4220.&lt;br /&gt;
&lt;br /&gt;
The final outcome of the calculation of the grade for a user at a particular quiz is stored in the &#039;grade&#039; field of the [[Quiz database structure#quiz_grades|quiz_grades table]]. This field has type double.&lt;br /&gt;
&lt;br /&gt;
==Penalty mechanism==&lt;br /&gt;
&lt;br /&gt;
===What it is for===&lt;br /&gt;
&lt;br /&gt;
When the quiz is run in adaptive mode the student can interact with a question repeatedly. So in particular the student can try again when he gets a wrong answer. Clearly the final mark for the question must reflect the fact that the student did not get it right originally. Therefore a penalty is subtracted from the final mark.&lt;br /&gt;
&lt;br /&gt;
===How the penalty is determined===&lt;br /&gt;
&lt;br /&gt;
First of all penalties are relevant only if a quiz is run in adaptive mode. Only in this case can a student have a second attempt and therefore only in this mode can there be any occasion to subtract a penalty.&lt;br /&gt;
&lt;br /&gt;
Even in adaptive mode the penalty mechanism is only used when it is selected in the quiz options. If &amp;quot;Apply penalties&amp;quot; is set to &amp;quot;No&amp;quot; then the final mark for the question is the mark for the last graded response.&lt;br /&gt;
&lt;br /&gt;
Each question has a &#039;penalty&#039; field (which should really be called &#039;penaltyfactor&#039;) which is a number between 0 and 1. The penalty for a wrong response is calculated as the product ($quiz-&amp;gt;penalty * $quiz-&amp;gt;grade), i.e., as the product of the penaltyfactor with the maximum achievable grade for the question. This product is stored in $state-&amp;gt;penalty. So $quiz-&amp;gt;penalty is the fraction of the maximum grade that is subtracted as a penalty for each wrong response.&lt;br /&gt;
&lt;br /&gt;
The $quiz-&amp;gt;penalty field has a default value of 0.1, both in the database and in mod/quiz/defaults.php. This default can of course be overwritten by the admin on the quiz configuration page. This admin-selected default is (as usual for admin defaults) stored in $CFG-&amp;gt;quiz_penalty. The teacher can choose a different penalty factor for each individual question when adding or editing a question. (In Moodle 1.8 the default value of 0.1 is actually hardcoded at line 87 of moodle/question/type/edit_question_form.php)&lt;br /&gt;
&lt;br /&gt;
Now if a student makes repeated wrong attempts (or partially correct attempts) the penalties for all these attempts are added up in $state-&amp;gt;sumpenalties. The mark for the question is then calculated as the mark for the last graded response minus the sum of the penalties.&lt;br /&gt;
&lt;br /&gt;
One curious fact about $state-&amp;gt;sumpenalties is that, for efficiency reasons, it is not stored in the quiz_states table but instead in the &#039;sumpenalty&#039; field of the quiz_newest_states table. That way it only has to be stored once per attempt rather than once per response.&lt;br /&gt;
&lt;br /&gt;
===Where it is done in the code===&lt;br /&gt;
&lt;br /&gt;
The function quiz_apply_penalty_and_timelimit() subtracts the penalty in $state-&amp;gt;sumpenalty from the raw grade in $state-&amp;gt;raw_grade to obtain $state-&amp;gt;grade for the response. However it is ensured that the grade of a new attempt at the question never falls below the previously achieved grade. This function also increases $state-&amp;gt;sumpenalty by the amount in $state-&amp;gt;penalty. The assumption is that $state-&amp;gt;penalty has just been set appropriately by the code calling this function, e.g., quiz_process_responses.&lt;br /&gt;
&lt;br /&gt;
==Files belonging to questions==&lt;br /&gt;
&lt;br /&gt;
This talks about the situation in relation to the Moodle 2.0 file API.&lt;br /&gt;
&lt;br /&gt;
===File areas===&lt;br /&gt;
&lt;br /&gt;
There are various file areas associated with each question.&lt;br /&gt;
&lt;br /&gt;
For example there is a file are &#039;questiontext&#039;, belonging to the &#039;question&#039; core component, which stores any images or other embedded files used by the question text. There are also &#039;generalfeedback&#039; and &#039;question_answer&#039; file areas.&lt;br /&gt;
&lt;br /&gt;
There may also be some file areas specific to each question type. For example the &#039;qtype_multichoice&#039; component has a &#039;correctfeedback&#039; file area (among others).&lt;br /&gt;
&lt;br /&gt;
All these file areas belong to the context that is the context of $question-&amp;gt;category.&lt;br /&gt;
&lt;br /&gt;
===Serving files and access checks===&lt;br /&gt;
&lt;br /&gt;
This is a bit complicated because, although the files belong to the question system or a particular question type, then whether the user should be able to see a particular file (for example an image in the general feedback) is influenced by whichever part of Moodle is using the question (for example the quiz module or question preview).&lt;br /&gt;
&lt;br /&gt;
The easiest way to explain is probably to show the call-stack for determining whether a particular image is displayed, then you can go and read the code.&lt;br /&gt;
&lt;br /&gt;
For the request .../pluginfile.php/123/question/questiontext/234/345/image.png for an impage in the questiontext of a question in a quiz attempt.&lt;br /&gt;
&lt;br /&gt;
(here, 123 is the contextid, 234 if the attemptid (corresponding to question_attempts.id) and 345 is the questionid.)&lt;br /&gt;
&lt;br /&gt;
# pluginfile.php&lt;br /&gt;
# question_pluginfile() &#039;&#039;in lib/questionlib.php&#039;&#039;&lt;br /&gt;
# quiz_question_pluginfile() &#039;&#039;in mod/quiz/lib.php&#039;&#039;&lt;br /&gt;
# quiz_attempt-&amp;gt;check_file_access() &#039;&#039;in mod/quiz/attemptlib.php&#039;&#039;&lt;br /&gt;
# question-&amp;gt;check_file_access() &#039;&#039;in lib/questionlib.php&#039;&#039;&lt;br /&gt;
# qtype_&#039;&#039;whatever&#039;&#039;-&amp;gt;check_file_access() &#039;&#039;in question/type/whatever/quetsiontype.php&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If, instead, the question was appearing in the question preview pop-up window, the call stack would be&lt;br /&gt;
&lt;br /&gt;
# pluginfile.php&lt;br /&gt;
# question_pluginfile() &#039;&#039;in lib/questionlib.php&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;question_preview_question_pluginfile()&#039;&#039;&#039; &#039;&#039;in question/previewlib.php&#039;&#039;&lt;br /&gt;
# question-&amp;gt;check_file_access() &#039;&#039;in lib/questionlib.php&#039;&#039;&lt;br /&gt;
# qtype_&#039;&#039;whatever&#039;&#039;-&amp;gt;check_file_access() &#039;&#039;in question/type/whatever/quetsiontype.php&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(the different bit is highlighted in bold).&lt;br /&gt;
&lt;br /&gt;
If, instead, the image url was .../pluginfile.php/123/qtype_multichoice/correctfeedback/234/345/image.png, the call stack would be&lt;br /&gt;
&lt;br /&gt;
# pluginfile.php&lt;br /&gt;
# &#039;&#039;&#039;qtype_multichoice_pluginfile()&#039;&#039;&#039; &#039;&#039;in question/type/multichoice/lib.php&#039;&#039;&lt;br /&gt;
# question_pluginfile() &#039;&#039;in lib/questionlib.php&#039;&#039;&lt;br /&gt;
# quiz_question_pluginfile() &#039;&#039;in mod/quiz/lib.php&#039;&#039;&lt;br /&gt;
# quiz_attempt-&amp;gt;check_file_access() &#039;&#039;in mod/quiz/attemptlib.php&#039;&#039;&lt;br /&gt;
# question-&amp;gt;check_file_access() &#039;&#039;in lib/questionlib.php&#039;&#039;&lt;br /&gt;
# qtype_multichoice-&amp;gt;check_file_access() &#039;&#039;in question/type/multichoice/quetsiontype.php&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Roughly speaking, qtype_whatever-&amp;gt;check_file_access() takes the same $question, $state and $options objects as print_question_formulation_and_controls, so, for example, you can do the same permissions check when trying to access a file in the feedback as was done when deciding whether to display the feedback.&lt;br /&gt;
&lt;br /&gt;
The quiz_question_pluginfile or question_preview_question_pluginfile functions are responsible for getting the right $question, $state, $options based on the $attemptid and $questionid in the URL. They also do some basic access checks.&lt;br /&gt;
&lt;br /&gt;
All the other functions are really just about dispatching the request to the right place to be handled.&lt;br /&gt;
&lt;br /&gt;
==Question engine upgrade helper 2.1 ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Site administration &amp;gt; Question engine upgrade helper&#039;&#039; has a menu to assist quiz conversion. It contains links for:&lt;br /&gt;
*List quizzes still to upgrade&lt;br /&gt;
*List already upgrade quizzes than can be reset&lt;br /&gt;
*Extract test case&lt;br /&gt;
*Config cron&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Question engine]]&lt;br /&gt;
[[Category:Quiz]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Quiz&amp;diff=63883</id>
		<title>Quiz</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Quiz&amp;diff=63883"/>
		<updated>2023-05-18T13:59:11Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Quiz developer docs}}&lt;br /&gt;
&lt;br /&gt;
The quiz is a complex module, although attempts have been made to re-organise the code to keep things managable.&lt;br /&gt;
&lt;br /&gt;
This page is only intended to give a high level overview. To really understand the quiz, you will have to look at the code, much of which should be clear and well commented.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==What the quiz does and does not do==&lt;br /&gt;
&lt;br /&gt;
The quiz module uses the [[Question bank]] to manage the questions that teachers create, and the [[Question engine]] to display and process questions when students attempt them. You are particularly advised to read [[Using the question engine from module]].&lt;br /&gt;
&lt;br /&gt;
The quiz module itself is only responsible for&lt;br /&gt;
# letting teachers assemble questions into quizzes.&lt;br /&gt;
# controlling which students can attempt the quiz when.&lt;br /&gt;
# providing access so that students can review their past attempts and the feedback (if the teacher permits it).&lt;br /&gt;
# providing reports on the outcomes for teachers.&lt;br /&gt;
&lt;br /&gt;
Displaying the results is delegated to [[Quiz reports|quiz report]] sub-plugins. Note that some fairly core functionality is implemented in the reports. For example deleting and regrading attempts is handled by &amp;lt;tt&amp;gt;quiz_overview&amp;lt;/tt&amp;gt; report, and bulk manual grading is handled by &amp;lt;tt&amp;gt;quiz_grading&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A lot of the details of when and if students can access the quiz are handled by [[Quiz access rules|quiz access rule]] sub-plugins.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Code overview==&lt;br /&gt;
&lt;br /&gt;
All the code has PHPdoc comments which provides a lot of detailed explanation. That is not repeated here.&lt;br /&gt;
&lt;br /&gt;
This is a [[Modules|standard Moodle activity module]], so inside &amp;lt;tt&amp;gt;mod/quiz&amp;lt;/tt&amp;gt; there are all the things you would expect to see like &amp;lt;tt&amp;gt;db/&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;lib.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;locallib.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;view.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;version.php&amp;lt;/tt&amp;gt; and so on.&lt;br /&gt;
&lt;br /&gt;
The scripts that are directly accessed by the user are listed on [[Quiz user interface overview]], and I will not list them again here. It would probably also help to look at the [[Quiz database structure]] before trying to understand the back-end code.&lt;br /&gt;
&lt;br /&gt;
The back-end code is organised thus:&lt;br /&gt;
; lib.php&lt;br /&gt;
: All the functions that are called by the Moodle core. For performance reasons it is important that this does not include any other files.&lt;br /&gt;
; locallib.php&lt;br /&gt;
: This contains all the other quiz library functions that do not have a more specific home. Including this file also includes all the other quiz libraries that you might need.&lt;br /&gt;
; mod_form.php&lt;br /&gt;
: The module settings form, as you would expect for any Moodle activity module.&lt;br /&gt;
; editlib.php&lt;br /&gt;
: This defines the functions that are used when at teacher edits the quiz. Thus, they are mostly called from &amp;lt;tt&amp;gt;edit.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
; attemptlib.php&lt;br /&gt;
: This defines the &amp;lt;tt&amp;gt;quiz&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;quiz_attempt&amp;lt;/tt&amp;gt; classes. These are all about what happens when a student (or other user) is looking at the quiz, so they provide a personalised view of the quiz data from the point of view of that user. Thus these classes are mainly used by the &amp;lt;tt&amp;gt;view.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;startattempt.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;attempt.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;processattempt.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;summary.php&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;review.php&amp;lt;/tt&amp;gt; scripts.&lt;br /&gt;
; accessmanager.php&lt;br /&gt;
: This provides the interface point that the rest of the quiz code uses to access the [[Quiz access rules|quiz access rule]] sub-plugins.&lt;br /&gt;
; renderer.php&lt;br /&gt;
: the quiz uses the [[Themes 2.0 overriding a renderer|Moodle 2.x renderer system]] to generate the HTML for all the student-visible parts of the UI. This means that theme designer have a lot of freedom as to how the quiz is displayed to students. Perhaps one day the editing UI will also be re-factored. As is standard for a Moodle plug-in, this file defines the renderer class.&lt;br /&gt;
; settings.php &amp;amp; settingslib.php&lt;br /&gt;
: define the admin settings for the quiz.&lt;br /&gt;
; accessmanager_form.php, addrandomform.php &amp;amp; override_form.php&lt;br /&gt;
: Used by &amp;lt;tt&amp;gt;accessmanager.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;addrandom.php&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;overridedit.php&amp;lt;/tt&amp;gt; respectively.&lt;br /&gt;
; module.js&lt;br /&gt;
: JavaScript used by &amp;lt;tt&amp;gt;attempt.php&amp;lt;/tt&amp;gt; and to a lesser extent &amp;lt;tt&amp;gt;view.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;summary.php&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;review.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
; edit.js&lt;br /&gt;
:JavaScript used by &amp;lt;tt&amp;gt;edit.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Quiz navigation fake block==&lt;br /&gt;
&lt;br /&gt;
During the quiz attempt (so, on &amp;lt;tt&amp;gt;attempt.php&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;summary,php&amp;lt;/tt&amp;gt; (from Moodle 2.2 onwards) and &amp;lt;tt&amp;gt;review.php&amp;lt;/tt&amp;gt;) we display a navigation UI that looks like a block. This uses the &amp;lt;tt&amp;gt;block_manager::add_fake_block&amp;lt;/tt&amp;gt; feature.&lt;br /&gt;
&lt;br /&gt;
The block contents is produce by classes in &amp;lt;tt&amp;gt;attemptlib.php&amp;lt;/tt&amp;gt; working with methods in the renderer. The navigation relies on some JavaScript in &amp;lt;tt&amp;gt;module.js&amp;lt;/tt&amp;gt; because it is vitally important that every time the user moves from one page of the quiz attempt to another, we save their answers. The javascript turns click on the navigation links into form submissions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Quiz layout==&lt;br /&gt;
&lt;br /&gt;
Information about the structure of a quiz is stored in the &amp;lt;tt&amp;gt;quiz.qestions&amp;lt;/tt&amp;gt; column and the &amp;lt;tt&amp;gt;quiz_question_instances&amp;lt;/tt&amp;gt; table. The layout is a comma-separated list of question ids, with 0s to represent page-breaks.&lt;br /&gt;
&lt;br /&gt;
There are methods in &amp;lt;tt&amp;gt;locallib.php&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;editlib.php&amp;lt;/tt&amp;gt; to manipulate this structure.&lt;br /&gt;
&lt;br /&gt;
When a quiz attempt is stared, the questions are added to a &amp;lt;tt&amp;gt;question_usage_by_activity&amp;lt;/tt&amp;gt; object ($quba) that is managed by the question bank. The $quba indexes things by &#039;slot&#039; rather than question.id, so the quiz layout gets rewritten and stored in &amp;lt;tt&amp;gt;quiz_attempts.layout&amp;lt;/tt&amp;gt;. This is done in &amp;lt;tt&amp;gt;startattempt.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
One of the options is to randomise the order of the question in the quiz. This is done by shuffling &amp;lt;tt&amp;gt;quiz_attempts.layout&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;startattempt.php&amp;lt;/tt&amp;gt; also handles selecting a real question to go in each place where the teacher has added a &#039;Random question from category X&#039; to the quiz. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Goals of an online assessment system]] - a summary of what the quiz is trying to achieve, and the developments that might be done in the future.&lt;br /&gt;
* [[Question bank]]&lt;br /&gt;
* [[Question engine]] - also [[Question_Engine_2]], which needs to be merged into it. In particular, see [[Using the question engine from module]].&lt;br /&gt;
* [[Quiz Usability portal]] - docs from the project to re-design the editing interface in Moodle 2.1.&lt;br /&gt;
* [[Quiz support in the Mobile app]] - Quiz support in the Mobile app is one of the most requested features by users&lt;br /&gt;
&lt;br /&gt;
[[Category:Quiz]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Web_services:Files&amp;diff=63862</id>
		<title>Web services:Files</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Web_services:Files&amp;diff=63862"/>
		<updated>2023-04-11T19:14:47Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These APIs will be used to browse Moodle files by Moodle Web Services.&lt;br /&gt;
&lt;br /&gt;
===class moodle_file_external()===&lt;br /&gt;
&lt;br /&gt;
This class implements the interface to moodle files, for browsing, downloading and uploading files.  It is defined in files/externals.php.&lt;br /&gt;
&lt;br /&gt;
We cannot return the whole files tree by web service API, because to make sure the web services is working in every language and platform, we need to define a fixed data structure of return value, but the files tree can change all the time. See more information about web services at: [[External_services_description]].&lt;br /&gt;
&lt;br /&gt;
The class contains following methods:&lt;br /&gt;
&lt;br /&gt;
====get_files====&lt;br /&gt;
This function is used to browse files.&lt;br /&gt;
&lt;br /&gt;
It takes 5 parameters, all of them are optional, if you provide no parameters, it will return the top level content of moodle repository.&lt;br /&gt;
&lt;br /&gt;
* contextid&lt;br /&gt;
* component&lt;br /&gt;
* filearea&lt;br /&gt;
* itemid&lt;br /&gt;
* filename&lt;br /&gt;
* filepath&lt;br /&gt;
&lt;br /&gt;
It will return an array, can be described as PHP array:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$files = array(&lt;br /&gt;
  &#039;path&#039; =&amp;gt; array(array(&#039;name&#039;=&amp;gt;&#039;root&#039;, &#039;path=&amp;gt;&#039;/&#039;), array(&#039;name&#039;=&amp;gt;&#039;subdir&#039;, &#039;path=&amp;gt;&#039;/sub/&#039;)),&lt;br /&gt;
  &#039;files&#039; =&amp;gt; array(&lt;br /&gt;
       array(&#039;filename&#039;=&amp;gt;&#039;readme&#039;, &#039;filepath&#039;=&amp;gt;&#039;/&#039;, &#039;filearea&#039;=&amp;gt;&#039;forum&#039;, &#039;itemid&#039;=&amp;gt;110, &#039;contextid&#039;=&amp;gt;1, &#039;isdir&#039;=&amp;gt;true),&lt;br /&gt;
       array(&#039;filename&#039;=&amp;gt;&#039;changes&#039;, &#039;filepath&#039;=&amp;gt;&#039;/&#039;, &#039;filearea&#039;=&amp;gt;&#039;forum&#039;, &#039;itemid&#039;=&amp;gt;112, &#039;contextid&#039;=&amp;gt;1, &#039;isdir&#039;=&amp;gt;false),&lt;br /&gt;
     )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The service name is &amp;quot;moodle_file_get_files&amp;quot;, defined in lib/db/services.php.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====upload====&lt;br /&gt;
This function is used to upload a file to user private area.&lt;br /&gt;
&lt;br /&gt;
It takes 7 parameters, all of them are mandatory:&lt;br /&gt;
&lt;br /&gt;
* contextid&lt;br /&gt;
* component&lt;br /&gt;
* filearea&lt;br /&gt;
* itemid&lt;br /&gt;
* filepath&lt;br /&gt;
* filename&lt;br /&gt;
* filecontent&lt;br /&gt;
&lt;br /&gt;
It will return a boolean value, true/false.&lt;br /&gt;
&lt;br /&gt;
The service name is &amp;quot;moodle_file_upload&amp;quot;, defined in lib/db/services.php&lt;br /&gt;
&lt;br /&gt;
Sample code (using Zend Framework):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$url = MOODLE_WSROOT. &#039;?wstoken=xxxxxxxxxxxxxxxxxxxxxx&#039;;&lt;br /&gt;
$zend = new Zend_XmlRpc_Client($url);&lt;br /&gt;
$srv = $zend-&amp;gt;getProxy();&lt;br /&gt;
$files = $srv-&amp;gt;moodle_file_get_files($contextid, $component, $filearea, $itemid, $filepath, $filename);&lt;br /&gt;
$file = $srv-&amp;gt;moodle_file_upload($contextid, &#039;user&#039;, &#039;private&#039;, 0, &#039;/&#039;, &#039;info.txt&#039;, base64_encode(&#039;this is file content&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Using_the_question_engine_from_module&amp;diff=63839</id>
		<title>Using the question engine from module</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Using_the_question_engine_from_module&amp;diff=63839"/>
		<updated>2023-03-19T10:14:36Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Outputting the questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Question_engine_2}}&lt;br /&gt;
This page explains how to use the new Moodle [[Question Engine 2|question engine]] in an activity module you are developing.&lt;br /&gt;
&lt;br /&gt;
Previous section: [[Developing_a_Question_Type|Developing a Question Type]]&lt;br /&gt;
&lt;br /&gt;
The first example of a module that uses the question engine is the quiz module. Looking at how the quiz code works will let you see a real working example of what is explained on this page. Another, much simpler example to look at is &amp;lt;tt&amp;gt;question/preview.php&amp;lt;/tt&amp;gt;, and https://github.com/moodleou/moodle-filter_embedquestion/blob/master/showquestion.php is simpler still.&lt;br /&gt;
&lt;br /&gt;
Note that all the question engine code has extensive PHP documentor comments that should explain the purpose of every class and method. This document is supposed to provide an overview of the key points to get you started. It does not attempt to duplicate all the details in the PHPdocs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The key class you will be working with is &amp;lt;tt&amp;gt;question_usage_by_activity&amp;lt;/tt&amp;gt;. This tracks an attempt at some questions, for example a quiz attempt. The usage should provide all the interface methods you need to do things with the question engine. You should rarely need to dive deeper into the inner workings of the question engine than this.&lt;br /&gt;
&lt;br /&gt;
A usage is a collection of &amp;lt;tt&amp;gt;question_attempt&amp;lt;/tt&amp;gt; objects. A question attempt represents the state of the user&#039;s attempt at one question within the usage. When you add a question to the usage, you get back a &#039;&#039;&#039;slot&#039;&#039;&#039; number. This serves to index that question within the attempt. Using slot numbers like this means that the same question can be added more than once to the same usage. A lot of the usage API calls take this slot number to indicate which question attempt to operate on. Other API methods let you perform batch actions on all the question attempts within the usage.&lt;br /&gt;
&lt;br /&gt;
==Starting an attempt at some questions==&lt;br /&gt;
&lt;br /&gt;
The example code in this section all came from &amp;lt;tt&amp;gt;mod/quiz/startattempt.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Creating the usage===&lt;br /&gt;
&lt;br /&gt;
To create a new usage, ask the question engine:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba = question_engine::make_questions_usage_by_activity(&#039;mod_quiz&#039;, $quizobj-&amp;gt;get_context());&lt;br /&gt;
$quba-&amp;gt;set_preferred_behaviour($quizobj-&amp;gt;get_quiz()-&amp;gt;preferredbehaviour);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will see that the constructor takes the plugin name (using the Moodle 2.0 &#039;frankenstyle&#039; naming convention) and the context that owns the usage. Usages should be cleaned up automatically when a context is deleted or a plugin un-installed. You also have to tell the usage which behaviour should be used when creating the attempt at each question.&lt;br /&gt;
&lt;br /&gt;
===Adding questions===&lt;br /&gt;
&lt;br /&gt;
Having got a usage, you will probably then want to add some questions to it. The question data you loaded from the database (probably using the &amp;lt;tt&amp;gt;get_question_options&amp;lt;/tt&amp;gt; function) come in a form suitable for data handling like import/export, backup/restore, and so on. We need to convert that to an &amp;lt;tt&amp;gt;question_definition&amp;lt;/tt&amp;gt; object. That can be done using the &amp;lt;tt&amp;gt;question_bank::make_question&amp;lt;/tt&amp;gt; method. Alternatively, you could just use the &amp;lt;tt&amp;gt;question_bank::load_question&amp;lt;/tt&amp;gt; method, but that can only load one question at a time.&lt;br /&gt;
&lt;br /&gt;
Once you have a &amp;lt;tt&amp;gt;question_definition&amp;lt;/tt&amp;gt; object, you add it to the usage by calling the &amp;lt;tt&amp;gt;add_question&amp;lt;/tt&amp;gt; method passing the question definition, and also the score you want this question marked out of. You get back the slot number that has been assigned to this question. The slot numbers are allocated in order, starting from 1. You can rely on that numbering convention. For example, the quiz module uses the slot numbers to make sure the grade for each question lines up properly in the reports.&lt;br /&gt;
&lt;br /&gt;
Here is the applicable code from the quiz module (some code to handle random questions and question shuffling omitted)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$slot = 0;&lt;br /&gt;
$questions = [];&lt;br /&gt;
$maxmark = [];&lt;br /&gt;
$page = [];&lt;br /&gt;
foreach ($quizobj-&amp;gt;get_questions() as $questiondata) {&lt;br /&gt;
    $slot += 1;&lt;br /&gt;
    $maxmark[$slot] = $questiondata-&amp;gt;maxmark;&lt;br /&gt;
    $page[$slot] = $questiondata-&amp;gt;page;&lt;br /&gt;
    $questions[$slot] = question_bank::make_question($questiondata);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Starting the question attempts===&lt;br /&gt;
&lt;br /&gt;
The usage does not do much when the question is added. Before the user can start interacting with the question, you have to start it. You can either do that in bulk:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba-&amp;gt;start_all_questions();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or you can start just one particular question using the &amp;lt;tt&amp;gt;start_question($slot)&amp;lt;/tt&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
===Saving the usage===&lt;br /&gt;
&lt;br /&gt;
So far, all these method calls have just built up a data structure in memory. If you want to keep it, you have to save it in the database. Fortunately, that is easy:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The usage is stored as a row in the &amp;lt;tt&amp;gt;question_usages&amp;lt;/tt&amp;gt; table (plus rows in other tables). To get the id of the usage, call &amp;lt;tt&amp;gt;$quba-&amp;gt;get_id()&amp;lt;/tt&amp;gt; after you have saved it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Displaying questions==&lt;br /&gt;
&lt;br /&gt;
Suppose that you wish to display a page that contains several questions from the usage. The questions to display will be the ones whose slot numbers are in an array called &amp;lt;tt&amp;gt;$slotsonpage&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The example code in this section is derived from code used by &amp;lt;tt&amp;gt;mod/quiz/attempt.php&amp;lt;/tt&amp;gt;. However, the quiz code is split between &amp;lt;tt&amp;gt;mod/quiz/attempt.php&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;quiz_attempt&amp;lt;/tt&amp;gt; class in &amp;lt;tt&amp;gt;mod/quiz/attemptlib.php&amp;lt;/tt&amp;gt;. That separation means that if I used the real quiz code in this tutorial, it would be unnecessarily hard to understand. Instead, I have simplified the examples below. If you are interested, you should be able to match up what you see below with the real quiz code.&lt;br /&gt;
&lt;br /&gt;
===Loading the usage===&lt;br /&gt;
&lt;br /&gt;
At the end of the last section, you had just saved the usage to the database. To display the questions as part of a different script, they must be loaded from the database again. Once again you ask the question engine to do this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($usageid);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The id that you pass to this method is the id you got from &amp;lt;tt&amp;gt;$quba-&amp;gt;get_id()&amp;lt;/tt&amp;gt; after saving the usage.&lt;br /&gt;
&lt;br /&gt;
===The question form===&lt;br /&gt;
&lt;br /&gt;
Within the page, all the questions have to be wrapped in a HTML &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;form&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; tag. This form needs to POST to a scripts that processes the submitted data ([[#Processing_responses|see below]]).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;&amp;lt;form id=&amp;quot;responseform&amp;quot; method=&amp;quot;post&amp;quot; action=&amp;quot;&#039; . $processurl .&lt;br /&gt;
        &#039;&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot; accept-charset=&amp;quot;utf-8&amp;quot;&amp;gt;&#039;, &amp;quot;\n&amp;lt;div&amp;gt;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.core_question_engine.init_form&#039;,&lt;br /&gt;
        array(&#039;#responseform&#039;), false, &#039;core_question_engine&#039;);&lt;br /&gt;
&lt;br /&gt;
echo &#039;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;slots&amp;quot; value=&amp;quot;&#039; . implode(&#039;,&#039;, $slotsonpage) . &amp;quot;\&amp;quot; /&amp;gt;\n&amp;quot;;&lt;br /&gt;
echo &#039;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;scrollpos&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;enctype&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;accept-charset&amp;lt;/tt&amp;gt; parameters are important. Please copy them. The form must have an id, and you must then write some JavaScript that passes that id to to the &amp;lt;tt&amp;gt;question_init_form&amp;lt;/tt&amp;gt; function. That function is defined in &amp;lt;tt&amp;gt;question/qengine.js&amp;lt;/tt&amp;gt; if you want to find out what it does and why it is important.&lt;br /&gt;
&lt;br /&gt;
You should output a hidden form field &amp;lt;tt&amp;gt;slots&amp;lt;/tt&amp;gt; that contains a comma-separated list of the slot numbers that appear on this page. That is not absolutely necessary, but it will make processing the form submission much more efficient.&lt;br /&gt;
&lt;br /&gt;
Another nicety is the &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field. Some question behaviours, for example the interactive behaviour, have submit buttons that do something to the question. When the user clicks this button, it is nice if when the page re-displays, it is scrolled to exactly the same place where it was. The question engine has JavaScript which, if it finds a &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field, will automatically save the scroll position to it when a button is clicked, and cause the page to scroll to that position when it reloads.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Outputting the questions===&lt;br /&gt;
&lt;br /&gt;
Finally, you can actually print the questions. Well, there is one more thing to take care of first. To control how the question appears, you must prepare a &amp;lt;tt&amp;gt;question_display_options&amp;lt;/tt&amp;gt; object that describes what should be visible. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = new question_display_options();&lt;br /&gt;
$options-&amp;gt;marks = question_display_options::MAX_ONLY;&lt;br /&gt;
$options-&amp;gt;markdp = 2; // Display marks to 2 decimal places.&lt;br /&gt;
$options-&amp;gt;feedback = question_display_options::VISIBLE;&lt;br /&gt;
$options-&amp;gt;generalfeedback = question_display_options::HIDDEN;&lt;br /&gt;
// etc.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(In the quiz code, the display options actually come from the quiz settings.) Then you really are ready to output the questions&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
foreach ($slotsonpage as $displaynumber =&amp;gt; $slot) {&lt;br /&gt;
    echo $quba-&amp;gt;render_question($slot, $options, $displaynumber);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;tt&amp;gt;$displaynumber&amp;lt;/tt&amp;gt; is the &#039;question number&#039; you want printed next to each question. This is not necessarily the same as the slot number. For example, in the quiz, Description &#039;questions&#039; are not numbered, although they take up a slot. It does not have to be a single integer and can also be combined with alphabetic glyphs if you have some other scheme for identifying questions in your activity. For example you could pass &#039;4.3.1&#039;, &#039;2a)&#039; &#039;2b)&#039;, or &#039;7 of 10&#039; if that is what your activity needs. If you don&#039;t pass in a number to display, that is, if you pass null, then the question is printed without a Question X heading.&lt;br /&gt;
&lt;br /&gt;
==Processing responses==&lt;br /&gt;
&lt;br /&gt;
Once again, the example here are inspired by real code from the quiz module, in this case &amp;lt;tt&amp;gt;mod/quiz/processattempt.php&amp;lt;/tt&amp;gt;, but simplified to remove mention of the &amp;lt;tt&amp;gt;quiz_attempt&amp;lt;/tt&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The simple case===&lt;br /&gt;
&lt;br /&gt;
Normally, you just need to do something like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$timenow = time();&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($usageid);&lt;br /&gt;
$quba-&amp;gt;process_all_actions($timenow);&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Behind the scenes there is, of course, a lot going on, including the use of the &amp;lt;tt&amp;gt;slots&amp;lt;/tt&amp;gt; parameter to control which questions are processed.&lt;br /&gt;
&lt;br /&gt;
There may also be additional work you need to do. For example, in the quiz (before the &amp;lt;tt&amp;gt;commit_sql()&amp;lt;/tt&amp;gt; line) there is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if ($attempt-&amp;gt;timefinish) {&lt;br /&gt;
    $attempt-&amp;gt;sumgrades = $quba-&amp;gt;get_total_mark();&lt;br /&gt;
}&lt;br /&gt;
$attempt-&amp;gt;timemodified = $timenow;&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;quiz_attempts&#039;, $attempt);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===More selective processing===&lt;br /&gt;
&lt;br /&gt;
If you want something other than the default processing, you can use code like &amp;lt;tt&amp;gt;$submitteddata = $quba-&amp;gt;extract_responses($slot); $quba-&amp;gt;process_action($slot, $submitteddata);&amp;lt;/tt&amp;gt; or something similar.&lt;br /&gt;
&lt;br /&gt;
===Handling scrollpos===&lt;br /&gt;
&lt;br /&gt;
You will remember that when we printed the questions, we created a &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field. Presumably, after you have processed the submission, you will redirect the user back to a page to display the questions again. In that case, you need to get the &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; parameter, and add it on to the URL you redirect to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// With the other required/optional_param calls at the start of processattempt.php.&lt;br /&gt;
$scrollpos = optional_param(&#039;scrollpos&#039;, &#039;&#039;, PARAM_RAW);&lt;br /&gt;
&lt;br /&gt;
// ... a bit later in the file&lt;br /&gt;
$nexturl = new moodle_url(/* something */);&lt;br /&gt;
if ($scrollpos !== &#039;&#039;) {&lt;br /&gt;
    $nexturl-&amp;gt;param(&#039;scrollpos&#039;, (int) $scrollpos);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ... after all the processing is done.&lt;br /&gt;
redirect($nexturl);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reports==&lt;br /&gt;
&lt;br /&gt;
Places like the quiz reports, we need to get data about a lot of usages at the same time. There are methods on the &amp;lt;tt&amp;gt;question_engine_data_mapper&amp;lt;/tt&amp;gt; to do this. You should never access the data in the question engine tables directly.&lt;br /&gt;
&lt;br /&gt;
For example from the quiz grades report. (Again the example code has been simplified.)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// $qubaids is an array of integer ids.&lt;br /&gt;
$qubaidscondition = new qubaid_list($qubaids);&lt;br /&gt;
&lt;br /&gt;
$dm = new question_engine_data_mapper();&lt;br /&gt;
$latesstepdata = $dm-&amp;gt;load_questions_usages_latest_steps(&lt;br /&gt;
        $qubaidscondition, $slots);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;qubaid_list&amp;lt;/tt&amp;gt; is a subclass of the &amp;lt;tt&amp;gt;qubaid_condition&amp;lt;/tt&amp;gt; class. This is an efficient way to represent a set of usage ids in a way that can be used in database queries. The other main subclass is &amp;lt;tt&amp;gt;qubaid_join&amp;lt;/tt&amp;gt;. That could be used like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$qubaidscondition = new qubaid_join(&#039;{quiz_attempts} quiza&#039;, &#039;quiza.uniqueid&#039;,&lt;br /&gt;
        &#039;quiza.quiz = :quizaquiz&#039;, array(&#039;quizaquiz&#039; =&amp;gt; $quizid))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another example, from the quiz manual grading report is&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$dm = new question_engine_data_mapper();&lt;br /&gt;
$statesummary = $dm-&amp;gt;load_questions_usages_question_state_summary(&lt;br /&gt;
        $qubaidscondition, $slots);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Perhaps the use of the class &amp;lt;tt&amp;gt;question_engine_data_mapper&amp;lt;/tt&amp;gt; should be hidden inside a helper class &amp;lt;tt&amp;gt;question_engine_reporter&amp;lt;/tt&amp;gt;?)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Other methods==&lt;br /&gt;
&lt;br /&gt;
===Methods to help with settings UI===&lt;br /&gt;
&lt;br /&gt;
When you want to present users with a choice of question behaviour (for example, the quiz How questions behave option) use&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = question_engine::get_behaviour_options();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Question marks are stored in the database to a fixed number of decimal places. To get a list of possible decimal place display options, use&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = question_engine::get_dp_options();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Clean-up methods===&lt;br /&gt;
&lt;br /&gt;
To delete usages you no longer need:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// A single usage ...&lt;br /&gt;
question_engine::delete_questions_usage_by_activity($qubaid);&lt;br /&gt;
&lt;br /&gt;
// ... or many.&lt;br /&gt;
question_engine::delete_questions_usage_by_activities(&lt;br /&gt;
        new qubaid_join(&#039;{quiz_attempts} quiza&#039;, &#039;quiza.uniqueid&#039;,&lt;br /&gt;
        &#039;quiza.quiz = :quizaquiz&#039;, array(&#039;quizaquiz&#039; =&amp;gt; $quizid)));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Changing the score of a question in all attempts===&lt;br /&gt;
&lt;br /&gt;
Suppose you change the number of marks awarded to question 2 in the quiz, you need to change that information in every attempt at that quiz, you can do that with a call like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
question_engine::set_max_mark_in_attempts($qubaids, $slot, $newmaxmark);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Re-grading a question===&lt;br /&gt;
&lt;br /&gt;
You only need to re-grade a question when the question definition is edited, for example to change the scoring rules. If you are just changing the maximum possible score for a question, see the previous sub-section.&lt;br /&gt;
&lt;br /&gt;
This code example is adapted from &amp;lt;tt&amp;gt;mod/quiz/report/overview/report.php&amp;lt;/tt&amp;gt;. It re-grades selected slots within a quiz attempt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($attempt-&amp;gt;uniqueid);&lt;br /&gt;
&lt;br /&gt;
foreach ($slots as $slot) {&lt;br /&gt;
    $oldfraction[$slot] = $quba-&amp;gt;get_question_fraction($slot);&lt;br /&gt;
    $quba-&amp;gt;regrade_question($slot);&lt;br /&gt;
    $newfraction[$slot] = $quba-&amp;gt;get_question_fraction($slot);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
$attempt-&amp;gt;sumgrades = $quba-&amp;gt;get_total_mark();&lt;br /&gt;
update_record(&#039;quiz_attempts&#039;, $attempt);&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
In the next section, [[Question Engine 2:Implementation plan|Implementation plan]] outlines how I will implement this proposal.&lt;br /&gt;
&lt;br /&gt;
* https://github.com/moodleou/moodle-filter_embedquestion/blob/master/showquestion.php is probably the simplest example code that displays a question and lets a user interact with it.&lt;br /&gt;
&lt;br /&gt;
* The PHP documenter comments that explain the purposes of every method in the question engine code.&lt;br /&gt;
* Back to [[Question_Engine_2|Question Engine 2]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Using_the_question_engine_from_module&amp;diff=63838</id>
		<title>Using the question engine from module</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Using_the_question_engine_from_module&amp;diff=63838"/>
		<updated>2023-03-19T09:53:53Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Adding questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Question_engine_2}}&lt;br /&gt;
This page explains how to use the new Moodle [[Question Engine 2|question engine]] in an activity module you are developing.&lt;br /&gt;
&lt;br /&gt;
Previous section: [[Developing_a_Question_Type|Developing a Question Type]]&lt;br /&gt;
&lt;br /&gt;
The first example of a module that uses the question engine is the quiz module. Looking at how the quiz code works will let you see a real working example of what is explained on this page. Another, much simpler example to look at is &amp;lt;tt&amp;gt;question/preview.php&amp;lt;/tt&amp;gt;, and https://github.com/moodleou/moodle-filter_embedquestion/blob/master/showquestion.php is simpler still.&lt;br /&gt;
&lt;br /&gt;
Note that all the question engine code has extensive PHP documentor comments that should explain the purpose of every class and method. This document is supposed to provide an overview of the key points to get you started. It does not attempt to duplicate all the details in the PHPdocs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The key class you will be working with is &amp;lt;tt&amp;gt;question_usage_by_activity&amp;lt;/tt&amp;gt;. This tracks an attempt at some questions, for example a quiz attempt. The usage should provide all the interface methods you need to do things with the question engine. You should rarely need to dive deeper into the inner workings of the question engine than this.&lt;br /&gt;
&lt;br /&gt;
A usage is a collection of &amp;lt;tt&amp;gt;question_attempt&amp;lt;/tt&amp;gt; objects. A question attempt represents the state of the user&#039;s attempt at one question within the usage. When you add a question to the usage, you get back a &#039;&#039;&#039;slot&#039;&#039;&#039; number. This serves to index that question within the attempt. Using slot numbers like this means that the same question can be added more than once to the same usage. A lot of the usage API calls take this slot number to indicate which question attempt to operate on. Other API methods let you perform batch actions on all the question attempts within the usage.&lt;br /&gt;
&lt;br /&gt;
==Starting an attempt at some questions==&lt;br /&gt;
&lt;br /&gt;
The example code in this section all came from &amp;lt;tt&amp;gt;mod/quiz/startattempt.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Creating the usage===&lt;br /&gt;
&lt;br /&gt;
To create a new usage, ask the question engine:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba = question_engine::make_questions_usage_by_activity(&#039;mod_quiz&#039;, $quizobj-&amp;gt;get_context());&lt;br /&gt;
$quba-&amp;gt;set_preferred_behaviour($quizobj-&amp;gt;get_quiz()-&amp;gt;preferredbehaviour);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will see that the constructor takes the plugin name (using the Moodle 2.0 &#039;frankenstyle&#039; naming convention) and the context that owns the usage. Usages should be cleaned up automatically when a context is deleted or a plugin un-installed. You also have to tell the usage which behaviour should be used when creating the attempt at each question.&lt;br /&gt;
&lt;br /&gt;
===Adding questions===&lt;br /&gt;
&lt;br /&gt;
Having got a usage, you will probably then want to add some questions to it. The question data you loaded from the database (probably using the &amp;lt;tt&amp;gt;get_question_options&amp;lt;/tt&amp;gt; function) come in a form suitable for data handling like import/export, backup/restore, and so on. We need to convert that to an &amp;lt;tt&amp;gt;question_definition&amp;lt;/tt&amp;gt; object. That can be done using the &amp;lt;tt&amp;gt;question_bank::make_question&amp;lt;/tt&amp;gt; method. Alternatively, you could just use the &amp;lt;tt&amp;gt;question_bank::load_question&amp;lt;/tt&amp;gt; method, but that can only load one question at a time.&lt;br /&gt;
&lt;br /&gt;
Once you have a &amp;lt;tt&amp;gt;question_definition&amp;lt;/tt&amp;gt; object, you add it to the usage by calling the &amp;lt;tt&amp;gt;add_question&amp;lt;/tt&amp;gt; method passing the question definition, and also the score you want this question marked out of. You get back the slot number that has been assigned to this question. The slot numbers are allocated in order, starting from 1. You can rely on that numbering convention. For example, the quiz module uses the slot numbers to make sure the grade for each question lines up properly in the reports.&lt;br /&gt;
&lt;br /&gt;
Here is the applicable code from the quiz module (some code to handle random questions and question shuffling omitted)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$slot = 0;&lt;br /&gt;
$questions = [];&lt;br /&gt;
$maxmark = [];&lt;br /&gt;
$page = [];&lt;br /&gt;
foreach ($quizobj-&amp;gt;get_questions() as $questiondata) {&lt;br /&gt;
    $slot += 1;&lt;br /&gt;
    $maxmark[$slot] = $questiondata-&amp;gt;maxmark;&lt;br /&gt;
    $page[$slot] = $questiondata-&amp;gt;page;&lt;br /&gt;
    $questions[$slot] = question_bank::make_question($questiondata);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Starting the question attempts===&lt;br /&gt;
&lt;br /&gt;
The usage does not do much when the question is added. Before the user can start interacting with the question, you have to start it. You can either do that in bulk:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba-&amp;gt;start_all_questions();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or you can start just one particular question using the &amp;lt;tt&amp;gt;start_question($slot)&amp;lt;/tt&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
===Saving the usage===&lt;br /&gt;
&lt;br /&gt;
So far, all these method calls have just built up a data structure in memory. If you want to keep it, you have to save it in the database. Fortunately, that is easy:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The usage is stored as a row in the &amp;lt;tt&amp;gt;question_usages&amp;lt;/tt&amp;gt; table (plus rows in other tables). To get the id of the usage, call &amp;lt;tt&amp;gt;$quba-&amp;gt;get_id()&amp;lt;/tt&amp;gt; after you have saved it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Displaying questions==&lt;br /&gt;
&lt;br /&gt;
Suppose that you wish to display a page that contains several questions from the usage. The questions to display will be the ones whose slot numbers are in an array called &amp;lt;tt&amp;gt;$slotsonpage&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The example code in this section is derived from code used by &amp;lt;tt&amp;gt;mod/quiz/attempt.php&amp;lt;/tt&amp;gt;. However, the quiz code is split between &amp;lt;tt&amp;gt;mod/quiz/attempt.php&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;quiz_attempt&amp;lt;/tt&amp;gt; class in &amp;lt;tt&amp;gt;mod/quiz/attemptlib.php&amp;lt;/tt&amp;gt;. That separation means that if I used the real quiz code in this tutorial, it would be unnecessarily hard to understand. Instead, I have simplified the examples below. If you are interested, you should be able to match up what you see below with the real quiz code.&lt;br /&gt;
&lt;br /&gt;
===Loading the usage===&lt;br /&gt;
&lt;br /&gt;
At the end of the last section, you had just saved the usage to the database. To display the questions as part of a different script, they must be loaded from the database again. Once again you ask the question engine to do this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($usageid);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The id that you pass to this method is the id you got from &amp;lt;tt&amp;gt;$quba-&amp;gt;get_id()&amp;lt;/tt&amp;gt; after saving the usage.&lt;br /&gt;
&lt;br /&gt;
===The question form===&lt;br /&gt;
&lt;br /&gt;
Within the page, all the questions have to be wrapped in a HTML &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;form&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; tag. This form needs to POST to a scripts that processes the submitted data ([[#Processing_responses|see below]]).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;&amp;lt;form id=&amp;quot;responseform&amp;quot; method=&amp;quot;post&amp;quot; action=&amp;quot;&#039; . $processurl .&lt;br /&gt;
        &#039;&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot; accept-charset=&amp;quot;utf-8&amp;quot;&amp;gt;&#039;, &amp;quot;\n&amp;lt;div&amp;gt;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.core_question_engine.init_form&#039;,&lt;br /&gt;
        array(&#039;#responseform&#039;), false, &#039;core_question_engine&#039;);&lt;br /&gt;
&lt;br /&gt;
echo &#039;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;slots&amp;quot; value=&amp;quot;&#039; . implode(&#039;,&#039;, $slotsonpage) . &amp;quot;\&amp;quot; /&amp;gt;\n&amp;quot;;&lt;br /&gt;
echo &#039;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;scrollpos&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;enctype&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;accept-charset&amp;lt;/tt&amp;gt; parameters are important. Please copy them. The form must have an id, and you must then write some JavaScript that passes that id to to the &amp;lt;tt&amp;gt;question_init_form&amp;lt;/tt&amp;gt; function. That function is defined in &amp;lt;tt&amp;gt;question/qengine.js&amp;lt;/tt&amp;gt; if you want to find out what it does and why it is important.&lt;br /&gt;
&lt;br /&gt;
You should output a hidden form field &amp;lt;tt&amp;gt;slots&amp;lt;/tt&amp;gt; that contains a comma-separated list of the slot numbers that appear on this page. That is not absolutely necessary, but it will make processing the form submission much more efficient.&lt;br /&gt;
&lt;br /&gt;
Another nicety is the &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field. Some question behaviours, for example the interactive behaviour, have submit buttons that do something to the question. When the user clicks this button, it is nice if when the page re-displays, it is scrolled to exactly the same place where it was. The question engine has JavaScript which, if it finds a &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field, will automatically save the scroll position to it when a button is clicked, and cause the page to scroll to that position when it reloads.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Outputting the questions===&lt;br /&gt;
&lt;br /&gt;
Finally, you can actually print the questions. Well, there is one more thing to take care of first. To control how the question appears, you must prepare a &amp;lt;tt&amp;gt;question_display_options&amp;lt;/tt&amp;gt; object that describes what should be visible. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = new question_display_options();&lt;br /&gt;
$options-&amp;gt;marks = question_display_options::MAX_ONLY;&lt;br /&gt;
$options-&amp;gt;markdp = 2; // Display marks to 2 decimal places.&lt;br /&gt;
$options-&amp;gt;feedback = question_display_options::VISIBLE;&lt;br /&gt;
$options-&amp;gt;generalfeedback = question_display_options::HIDDEN;&lt;br /&gt;
// etc.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(In the quiz code, the display options actually come from the quiz settings.) Then you really are ready to output the questions&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
foreach ($slotsonpage as $displaynumber =&amp;gt; $slot) {&lt;br /&gt;
    echo $quba-&amp;gt;render_question($slot, $options, $displaynumber);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;tt&amp;gt;$displaynumber&amp;lt;/tt&amp;gt; is the &#039;question number&#039; you want printed next to each question. This is not necessarily the same as the slot number. For example, in the quiz, Description &#039;questions&#039; are not numbered, although they take up a slot. It does not have to be a single integer (once MDL-62358 is fixed) if you have some other scheme for identifiying quesitions in your activity. For example you could pass &#039;4.3.1&#039; or &#039;7 of 10&#039; if that is what your activity needs. If you don&#039;t pass in a number to display, that is, if you pass null, then the question is printed without a Question X heading.&lt;br /&gt;
&lt;br /&gt;
==Processing responses==&lt;br /&gt;
&lt;br /&gt;
Once again, the example here are inspired by real code from the quiz module, in this case &amp;lt;tt&amp;gt;mod/quiz/processattempt.php&amp;lt;/tt&amp;gt;, but simplified to remove mention of the &amp;lt;tt&amp;gt;quiz_attempt&amp;lt;/tt&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The simple case===&lt;br /&gt;
&lt;br /&gt;
Normally, you just need to do something like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$timenow = time();&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($usageid);&lt;br /&gt;
$quba-&amp;gt;process_all_actions($timenow);&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Behind the scenes there is, of course, a lot going on, including the use of the &amp;lt;tt&amp;gt;slots&amp;lt;/tt&amp;gt; parameter to control which questions are processed.&lt;br /&gt;
&lt;br /&gt;
There may also be additional work you need to do. For example, in the quiz (before the &amp;lt;tt&amp;gt;commit_sql()&amp;lt;/tt&amp;gt; line) there is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if ($attempt-&amp;gt;timefinish) {&lt;br /&gt;
    $attempt-&amp;gt;sumgrades = $quba-&amp;gt;get_total_mark();&lt;br /&gt;
}&lt;br /&gt;
$attempt-&amp;gt;timemodified = $timenow;&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;quiz_attempts&#039;, $attempt);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===More selective processing===&lt;br /&gt;
&lt;br /&gt;
If you want something other than the default processing, you can use code like &amp;lt;tt&amp;gt;$submitteddata = $quba-&amp;gt;extract_responses($slot); $quba-&amp;gt;process_action($slot, $submitteddata);&amp;lt;/tt&amp;gt; or something similar.&lt;br /&gt;
&lt;br /&gt;
===Handling scrollpos===&lt;br /&gt;
&lt;br /&gt;
You will remember that when we printed the questions, we created a &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field. Presumably, after you have processed the submission, you will redirect the user back to a page to display the questions again. In that case, you need to get the &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; parameter, and add it on to the URL you redirect to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// With the other required/optional_param calls at the start of processattempt.php.&lt;br /&gt;
$scrollpos = optional_param(&#039;scrollpos&#039;, &#039;&#039;, PARAM_RAW);&lt;br /&gt;
&lt;br /&gt;
// ... a bit later in the file&lt;br /&gt;
$nexturl = new moodle_url(/* something */);&lt;br /&gt;
if ($scrollpos !== &#039;&#039;) {&lt;br /&gt;
    $nexturl-&amp;gt;param(&#039;scrollpos&#039;, (int) $scrollpos);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ... after all the processing is done.&lt;br /&gt;
redirect($nexturl);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reports==&lt;br /&gt;
&lt;br /&gt;
Places like the quiz reports, we need to get data about a lot of usages at the same time. There are methods on the &amp;lt;tt&amp;gt;question_engine_data_mapper&amp;lt;/tt&amp;gt; to do this. You should never access the data in the question engine tables directly.&lt;br /&gt;
&lt;br /&gt;
For example from the quiz grades report. (Again the example code has been simplified.)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// $qubaids is an array of integer ids.&lt;br /&gt;
$qubaidscondition = new qubaid_list($qubaids);&lt;br /&gt;
&lt;br /&gt;
$dm = new question_engine_data_mapper();&lt;br /&gt;
$latesstepdata = $dm-&amp;gt;load_questions_usages_latest_steps(&lt;br /&gt;
        $qubaidscondition, $slots);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;qubaid_list&amp;lt;/tt&amp;gt; is a subclass of the &amp;lt;tt&amp;gt;qubaid_condition&amp;lt;/tt&amp;gt; class. This is an efficient way to represent a set of usage ids in a way that can be used in database queries. The other main subclass is &amp;lt;tt&amp;gt;qubaid_join&amp;lt;/tt&amp;gt;. That could be used like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$qubaidscondition = new qubaid_join(&#039;{quiz_attempts} quiza&#039;, &#039;quiza.uniqueid&#039;,&lt;br /&gt;
        &#039;quiza.quiz = :quizaquiz&#039;, array(&#039;quizaquiz&#039; =&amp;gt; $quizid))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another example, from the quiz manual grading report is&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$dm = new question_engine_data_mapper();&lt;br /&gt;
$statesummary = $dm-&amp;gt;load_questions_usages_question_state_summary(&lt;br /&gt;
        $qubaidscondition, $slots);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Perhaps the use of the class &amp;lt;tt&amp;gt;question_engine_data_mapper&amp;lt;/tt&amp;gt; should be hidden inside a helper class &amp;lt;tt&amp;gt;question_engine_reporter&amp;lt;/tt&amp;gt;?)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Other methods==&lt;br /&gt;
&lt;br /&gt;
===Methods to help with settings UI===&lt;br /&gt;
&lt;br /&gt;
When you want to present users with a choice of question behaviour (for example, the quiz How questions behave option) use&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = question_engine::get_behaviour_options();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Question marks are stored in the database to a fixed number of decimal places. To get a list of possible decimal place display options, use&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = question_engine::get_dp_options();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Clean-up methods===&lt;br /&gt;
&lt;br /&gt;
To delete usages you no longer need:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// A single usage ...&lt;br /&gt;
question_engine::delete_questions_usage_by_activity($qubaid);&lt;br /&gt;
&lt;br /&gt;
// ... or many.&lt;br /&gt;
question_engine::delete_questions_usage_by_activities(&lt;br /&gt;
        new qubaid_join(&#039;{quiz_attempts} quiza&#039;, &#039;quiza.uniqueid&#039;,&lt;br /&gt;
        &#039;quiza.quiz = :quizaquiz&#039;, array(&#039;quizaquiz&#039; =&amp;gt; $quizid)));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Changing the score of a question in all attempts===&lt;br /&gt;
&lt;br /&gt;
Suppose you change the number of marks awarded to question 2 in the quiz, you need to change that information in every attempt at that quiz, you can do that with a call like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
question_engine::set_max_mark_in_attempts($qubaids, $slot, $newmaxmark);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Re-grading a question===&lt;br /&gt;
&lt;br /&gt;
You only need to re-grade a question when the question definition is edited, for example to change the scoring rules. If you are just changing the maximum possible score for a question, see the previous sub-section.&lt;br /&gt;
&lt;br /&gt;
This code example is adapted from &amp;lt;tt&amp;gt;mod/quiz/report/overview/report.php&amp;lt;/tt&amp;gt;. It re-grades selected slots within a quiz attempt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($attempt-&amp;gt;uniqueid);&lt;br /&gt;
&lt;br /&gt;
foreach ($slots as $slot) {&lt;br /&gt;
    $oldfraction[$slot] = $quba-&amp;gt;get_question_fraction($slot);&lt;br /&gt;
    $quba-&amp;gt;regrade_question($slot);&lt;br /&gt;
    $newfraction[$slot] = $quba-&amp;gt;get_question_fraction($slot);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
$attempt-&amp;gt;sumgrades = $quba-&amp;gt;get_total_mark();&lt;br /&gt;
update_record(&#039;quiz_attempts&#039;, $attempt);&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
In the next section, [[Question Engine 2:Implementation plan|Implementation plan]] outlines how I will implement this proposal.&lt;br /&gt;
&lt;br /&gt;
* https://github.com/moodleou/moodle-filter_embedquestion/blob/master/showquestion.php is probably the simplest example code that displays a question and lets a user interact with it.&lt;br /&gt;
&lt;br /&gt;
* The PHP documenter comments that explain the purposes of every method in the question engine code.&lt;br /&gt;
* Back to [[Question_Engine_2|Question Engine 2]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Using_the_question_engine_from_module&amp;diff=63837</id>
		<title>Using the question engine from module</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Using_the_question_engine_from_module&amp;diff=63837"/>
		<updated>2023-03-19T09:51:37Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Adding questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Question_engine_2}}&lt;br /&gt;
This page explains how to use the new Moodle [[Question Engine 2|question engine]] in an activity module you are developing.&lt;br /&gt;
&lt;br /&gt;
Previous section: [[Developing_a_Question_Type|Developing a Question Type]]&lt;br /&gt;
&lt;br /&gt;
The first example of a module that uses the question engine is the quiz module. Looking at how the quiz code works will let you see a real working example of what is explained on this page. Another, much simpler example to look at is &amp;lt;tt&amp;gt;question/preview.php&amp;lt;/tt&amp;gt;, and https://github.com/moodleou/moodle-filter_embedquestion/blob/master/showquestion.php is simpler still.&lt;br /&gt;
&lt;br /&gt;
Note that all the question engine code has extensive PHP documentor comments that should explain the purpose of every class and method. This document is supposed to provide an overview of the key points to get you started. It does not attempt to duplicate all the details in the PHPdocs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The key class you will be working with is &amp;lt;tt&amp;gt;question_usage_by_activity&amp;lt;/tt&amp;gt;. This tracks an attempt at some questions, for example a quiz attempt. The usage should provide all the interface methods you need to do things with the question engine. You should rarely need to dive deeper into the inner workings of the question engine than this.&lt;br /&gt;
&lt;br /&gt;
A usage is a collection of &amp;lt;tt&amp;gt;question_attempt&amp;lt;/tt&amp;gt; objects. A question attempt represents the state of the user&#039;s attempt at one question within the usage. When you add a question to the usage, you get back a &#039;&#039;&#039;slot&#039;&#039;&#039; number. This serves to index that question within the attempt. Using slot numbers like this means that the same question can be added more than once to the same usage. A lot of the usage API calls take this slot number to indicate which question attempt to operate on. Other API methods let you perform batch actions on all the question attempts within the usage.&lt;br /&gt;
&lt;br /&gt;
==Starting an attempt at some questions==&lt;br /&gt;
&lt;br /&gt;
The example code in this section all came from &amp;lt;tt&amp;gt;mod/quiz/startattempt.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Creating the usage===&lt;br /&gt;
&lt;br /&gt;
To create a new usage, ask the question engine:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba = question_engine::make_questions_usage_by_activity(&#039;mod_quiz&#039;, $quizobj-&amp;gt;get_context());&lt;br /&gt;
$quba-&amp;gt;set_preferred_behaviour($quizobj-&amp;gt;get_quiz()-&amp;gt;preferredbehaviour);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will see that the constructor takes the plugin name (using the Moodle 2.0 &#039;frankenstyle&#039; naming convention) and the context that owns the usage. Usages should be cleaned up automatically when a context is deleted or a plugin un-installed. You also have to tell the usage which behaviour should be used when creating the attempt at each question.&lt;br /&gt;
&lt;br /&gt;
===Adding questions===&lt;br /&gt;
&lt;br /&gt;
Having got a usage, you will probably then want to add some questions to it. The question data you loaded from the database (probably using the &amp;lt;tt&amp;gt;get_question_options&amp;lt;/tt&amp;gt; function) come in a form suitable for data handling like import/export, backup/restore, and so on. We need to convert that to an &amp;lt;tt&amp;gt;question_definition&amp;lt;/tt&amp;gt; object. That can be done using the &amp;lt;tt&amp;gt;question_bank::make_question&amp;lt;/tt&amp;gt; method. Alternatively, you could just use the &amp;lt;tt&amp;gt;question_bank::load_question&amp;lt;/tt&amp;gt; method, but that can only load one question at a time.&lt;br /&gt;
&lt;br /&gt;
Once you have a &amp;lt;tt&amp;gt;question_definition&amp;lt;/tt&amp;gt; object, you add it to the usage by calling the &amp;lt;tt&amp;gt;add_question&amp;lt;/tt&amp;gt; method passing the question definition, and also the score you want this question marked out of. You get back the slot number that has been assigned to this question. The slot numbers are allocated in order, starting from 1. You can rely on that numbering convention. For example, the quiz module uses the slot numbers to make sure the grade for each question lines up properly in the reports.&lt;br /&gt;
&lt;br /&gt;
Here is the applicable code from the quiz module (some code to handle random questions and answer shuffling omitted)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$slot = 0;&lt;br /&gt;
$questions = [];&lt;br /&gt;
$maxmark = [];&lt;br /&gt;
$page = [];&lt;br /&gt;
foreach ($quizobj-&amp;gt;get_questions() as $questiondata) {&lt;br /&gt;
    $slot += 1;&lt;br /&gt;
    $maxmark[$slot] = $questiondata-&amp;gt;maxmark;&lt;br /&gt;
    $page[$slot] = $questiondata-&amp;gt;page;&lt;br /&gt;
    $questions[$slot] = question_bank::make_question($questiondata);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Starting the question attempts===&lt;br /&gt;
&lt;br /&gt;
The usage does not do much when the question is added. Before the user can start interacting with the question, you have to start it. You can either do that in bulk:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba-&amp;gt;start_all_questions();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or you can start just one particular question using the &amp;lt;tt&amp;gt;start_question($slot)&amp;lt;/tt&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
===Saving the usage===&lt;br /&gt;
&lt;br /&gt;
So far, all these method calls have just built up a data structure in memory. If you want to keep it, you have to save it in the database. Fortunately, that is easy:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The usage is stored as a row in the &amp;lt;tt&amp;gt;question_usages&amp;lt;/tt&amp;gt; table (plus rows in other tables). To get the id of the usage, call &amp;lt;tt&amp;gt;$quba-&amp;gt;get_id()&amp;lt;/tt&amp;gt; after you have saved it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Displaying questions==&lt;br /&gt;
&lt;br /&gt;
Suppose that you wish to display a page that contains several questions from the usage. The questions to display will be the ones whose slot numbers are in an array called &amp;lt;tt&amp;gt;$slotsonpage&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The example code in this section is derived from code used by &amp;lt;tt&amp;gt;mod/quiz/attempt.php&amp;lt;/tt&amp;gt;. However, the quiz code is split between &amp;lt;tt&amp;gt;mod/quiz/attempt.php&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;quiz_attempt&amp;lt;/tt&amp;gt; class in &amp;lt;tt&amp;gt;mod/quiz/attemptlib.php&amp;lt;/tt&amp;gt;. That separation means that if I used the real quiz code in this tutorial, it would be unnecessarily hard to understand. Instead, I have simplified the examples below. If you are interested, you should be able to match up what you see below with the real quiz code.&lt;br /&gt;
&lt;br /&gt;
===Loading the usage===&lt;br /&gt;
&lt;br /&gt;
At the end of the last section, you had just saved the usage to the database. To display the questions as part of a different script, they must be loaded from the database again. Once again you ask the question engine to do this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($usageid);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The id that you pass to this method is the id you got from &amp;lt;tt&amp;gt;$quba-&amp;gt;get_id()&amp;lt;/tt&amp;gt; after saving the usage.&lt;br /&gt;
&lt;br /&gt;
===The question form===&lt;br /&gt;
&lt;br /&gt;
Within the page, all the questions have to be wrapped in a HTML &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;form&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; tag. This form needs to POST to a scripts that processes the submitted data ([[#Processing_responses|see below]]).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;&amp;lt;form id=&amp;quot;responseform&amp;quot; method=&amp;quot;post&amp;quot; action=&amp;quot;&#039; . $processurl .&lt;br /&gt;
        &#039;&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot; accept-charset=&amp;quot;utf-8&amp;quot;&amp;gt;&#039;, &amp;quot;\n&amp;lt;div&amp;gt;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.core_question_engine.init_form&#039;,&lt;br /&gt;
        array(&#039;#responseform&#039;), false, &#039;core_question_engine&#039;);&lt;br /&gt;
&lt;br /&gt;
echo &#039;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;slots&amp;quot; value=&amp;quot;&#039; . implode(&#039;,&#039;, $slotsonpage) . &amp;quot;\&amp;quot; /&amp;gt;\n&amp;quot;;&lt;br /&gt;
echo &#039;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;scrollpos&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;enctype&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;accept-charset&amp;lt;/tt&amp;gt; parameters are important. Please copy them. The form must have an id, and you must then write some JavaScript that passes that id to to the &amp;lt;tt&amp;gt;question_init_form&amp;lt;/tt&amp;gt; function. That function is defined in &amp;lt;tt&amp;gt;question/qengine.js&amp;lt;/tt&amp;gt; if you want to find out what it does and why it is important.&lt;br /&gt;
&lt;br /&gt;
You should output a hidden form field &amp;lt;tt&amp;gt;slots&amp;lt;/tt&amp;gt; that contains a comma-separated list of the slot numbers that appear on this page. That is not absolutely necessary, but it will make processing the form submission much more efficient.&lt;br /&gt;
&lt;br /&gt;
Another nicety is the &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field. Some question behaviours, for example the interactive behaviour, have submit buttons that do something to the question. When the user clicks this button, it is nice if when the page re-displays, it is scrolled to exactly the same place where it was. The question engine has JavaScript which, if it finds a &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field, will automatically save the scroll position to it when a button is clicked, and cause the page to scroll to that position when it reloads.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Outputting the questions===&lt;br /&gt;
&lt;br /&gt;
Finally, you can actually print the questions. Well, there is one more thing to take care of first. To control how the question appears, you must prepare a &amp;lt;tt&amp;gt;question_display_options&amp;lt;/tt&amp;gt; object that describes what should be visible. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = new question_display_options();&lt;br /&gt;
$options-&amp;gt;marks = question_display_options::MAX_ONLY;&lt;br /&gt;
$options-&amp;gt;markdp = 2; // Display marks to 2 decimal places.&lt;br /&gt;
$options-&amp;gt;feedback = question_display_options::VISIBLE;&lt;br /&gt;
$options-&amp;gt;generalfeedback = question_display_options::HIDDEN;&lt;br /&gt;
// etc.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(In the quiz code, the display options actually come from the quiz settings.) Then you really are ready to output the questions&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
foreach ($slotsonpage as $displaynumber =&amp;gt; $slot) {&lt;br /&gt;
    echo $quba-&amp;gt;render_question($slot, $options, $displaynumber);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;tt&amp;gt;$displaynumber&amp;lt;/tt&amp;gt; is the &#039;question number&#039; you want printed next to each question. This is not necessarily the same as the slot number. For example, in the quiz, Description &#039;questions&#039; are not numbered, although they take up a slot. It does not have to be a single integer (once MDL-62358 is fixed) if you have some other scheme for identifiying quesitions in your activity. For example you could pass &#039;4.3.1&#039; or &#039;7 of 10&#039; if that is what your activity needs. If you don&#039;t pass in a number to display, that is, if you pass null, then the question is printed without a Question X heading.&lt;br /&gt;
&lt;br /&gt;
==Processing responses==&lt;br /&gt;
&lt;br /&gt;
Once again, the example here are inspired by real code from the quiz module, in this case &amp;lt;tt&amp;gt;mod/quiz/processattempt.php&amp;lt;/tt&amp;gt;, but simplified to remove mention of the &amp;lt;tt&amp;gt;quiz_attempt&amp;lt;/tt&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The simple case===&lt;br /&gt;
&lt;br /&gt;
Normally, you just need to do something like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$timenow = time();&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($usageid);&lt;br /&gt;
$quba-&amp;gt;process_all_actions($timenow);&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Behind the scenes there is, of course, a lot going on, including the use of the &amp;lt;tt&amp;gt;slots&amp;lt;/tt&amp;gt; parameter to control which questions are processed.&lt;br /&gt;
&lt;br /&gt;
There may also be additional work you need to do. For example, in the quiz (before the &amp;lt;tt&amp;gt;commit_sql()&amp;lt;/tt&amp;gt; line) there is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if ($attempt-&amp;gt;timefinish) {&lt;br /&gt;
    $attempt-&amp;gt;sumgrades = $quba-&amp;gt;get_total_mark();&lt;br /&gt;
}&lt;br /&gt;
$attempt-&amp;gt;timemodified = $timenow;&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;quiz_attempts&#039;, $attempt);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===More selective processing===&lt;br /&gt;
&lt;br /&gt;
If you want something other than the default processing, you can use code like &amp;lt;tt&amp;gt;$submitteddata = $quba-&amp;gt;extract_responses($slot); $quba-&amp;gt;process_action($slot, $submitteddata);&amp;lt;/tt&amp;gt; or something similar.&lt;br /&gt;
&lt;br /&gt;
===Handling scrollpos===&lt;br /&gt;
&lt;br /&gt;
You will remember that when we printed the questions, we created a &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field. Presumably, after you have processed the submission, you will redirect the user back to a page to display the questions again. In that case, you need to get the &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; parameter, and add it on to the URL you redirect to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// With the other required/optional_param calls at the start of processattempt.php.&lt;br /&gt;
$scrollpos = optional_param(&#039;scrollpos&#039;, &#039;&#039;, PARAM_RAW);&lt;br /&gt;
&lt;br /&gt;
// ... a bit later in the file&lt;br /&gt;
$nexturl = new moodle_url(/* something */);&lt;br /&gt;
if ($scrollpos !== &#039;&#039;) {&lt;br /&gt;
    $nexturl-&amp;gt;param(&#039;scrollpos&#039;, (int) $scrollpos);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ... after all the processing is done.&lt;br /&gt;
redirect($nexturl);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reports==&lt;br /&gt;
&lt;br /&gt;
Places like the quiz reports, we need to get data about a lot of usages at the same time. There are methods on the &amp;lt;tt&amp;gt;question_engine_data_mapper&amp;lt;/tt&amp;gt; to do this. You should never access the data in the question engine tables directly.&lt;br /&gt;
&lt;br /&gt;
For example from the quiz grades report. (Again the example code has been simplified.)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// $qubaids is an array of integer ids.&lt;br /&gt;
$qubaidscondition = new qubaid_list($qubaids);&lt;br /&gt;
&lt;br /&gt;
$dm = new question_engine_data_mapper();&lt;br /&gt;
$latesstepdata = $dm-&amp;gt;load_questions_usages_latest_steps(&lt;br /&gt;
        $qubaidscondition, $slots);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;qubaid_list&amp;lt;/tt&amp;gt; is a subclass of the &amp;lt;tt&amp;gt;qubaid_condition&amp;lt;/tt&amp;gt; class. This is an efficient way to represent a set of usage ids in a way that can be used in database queries. The other main subclass is &amp;lt;tt&amp;gt;qubaid_join&amp;lt;/tt&amp;gt;. That could be used like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$qubaidscondition = new qubaid_join(&#039;{quiz_attempts} quiza&#039;, &#039;quiza.uniqueid&#039;,&lt;br /&gt;
        &#039;quiza.quiz = :quizaquiz&#039;, array(&#039;quizaquiz&#039; =&amp;gt; $quizid))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another example, from the quiz manual grading report is&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$dm = new question_engine_data_mapper();&lt;br /&gt;
$statesummary = $dm-&amp;gt;load_questions_usages_question_state_summary(&lt;br /&gt;
        $qubaidscondition, $slots);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Perhaps the use of the class &amp;lt;tt&amp;gt;question_engine_data_mapper&amp;lt;/tt&amp;gt; should be hidden inside a helper class &amp;lt;tt&amp;gt;question_engine_reporter&amp;lt;/tt&amp;gt;?)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Other methods==&lt;br /&gt;
&lt;br /&gt;
===Methods to help with settings UI===&lt;br /&gt;
&lt;br /&gt;
When you want to present users with a choice of question behaviour (for example, the quiz How questions behave option) use&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = question_engine::get_behaviour_options();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Question marks are stored in the database to a fixed number of decimal places. To get a list of possible decimal place display options, use&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = question_engine::get_dp_options();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Clean-up methods===&lt;br /&gt;
&lt;br /&gt;
To delete usages you no longer need:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// A single usage ...&lt;br /&gt;
question_engine::delete_questions_usage_by_activity($qubaid);&lt;br /&gt;
&lt;br /&gt;
// ... or many.&lt;br /&gt;
question_engine::delete_questions_usage_by_activities(&lt;br /&gt;
        new qubaid_join(&#039;{quiz_attempts} quiza&#039;, &#039;quiza.uniqueid&#039;,&lt;br /&gt;
        &#039;quiza.quiz = :quizaquiz&#039;, array(&#039;quizaquiz&#039; =&amp;gt; $quizid)));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Changing the score of a question in all attempts===&lt;br /&gt;
&lt;br /&gt;
Suppose you change the number of marks awarded to question 2 in the quiz, you need to change that information in every attempt at that quiz, you can do that with a call like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
question_engine::set_max_mark_in_attempts($qubaids, $slot, $newmaxmark);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Re-grading a question===&lt;br /&gt;
&lt;br /&gt;
You only need to re-grade a question when the question definition is edited, for example to change the scoring rules. If you are just changing the maximum possible score for a question, see the previous sub-section.&lt;br /&gt;
&lt;br /&gt;
This code example is adapted from &amp;lt;tt&amp;gt;mod/quiz/report/overview/report.php&amp;lt;/tt&amp;gt;. It re-grades selected slots within a quiz attempt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($attempt-&amp;gt;uniqueid);&lt;br /&gt;
&lt;br /&gt;
foreach ($slots as $slot) {&lt;br /&gt;
    $oldfraction[$slot] = $quba-&amp;gt;get_question_fraction($slot);&lt;br /&gt;
    $quba-&amp;gt;regrade_question($slot);&lt;br /&gt;
    $newfraction[$slot] = $quba-&amp;gt;get_question_fraction($slot);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
$attempt-&amp;gt;sumgrades = $quba-&amp;gt;get_total_mark();&lt;br /&gt;
update_record(&#039;quiz_attempts&#039;, $attempt);&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
In the next section, [[Question Engine 2:Implementation plan|Implementation plan]] outlines how I will implement this proposal.&lt;br /&gt;
&lt;br /&gt;
* https://github.com/moodleou/moodle-filter_embedquestion/blob/master/showquestion.php is probably the simplest example code that displays a question and lets a user interact with it.&lt;br /&gt;
&lt;br /&gt;
* The PHP documenter comments that explain the purposes of every method in the question engine code.&lt;br /&gt;
* Back to [[Question_Engine_2|Question Engine 2]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Using_the_question_engine_from_module&amp;diff=63836</id>
		<title>Using the question engine from module</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Using_the_question_engine_from_module&amp;diff=63836"/>
		<updated>2023-03-19T09:44:25Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Creating the usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:Question_engine_2}}&lt;br /&gt;
This page explains how to use the new Moodle [[Question Engine 2|question engine]] in an activity module you are developing.&lt;br /&gt;
&lt;br /&gt;
Previous section: [[Developing_a_Question_Type|Developing a Question Type]]&lt;br /&gt;
&lt;br /&gt;
The first example of a module that uses the question engine is the quiz module. Looking at how the quiz code works will let you see a real working example of what is explained on this page. Another, much simpler example to look at is &amp;lt;tt&amp;gt;question/preview.php&amp;lt;/tt&amp;gt;, and https://github.com/moodleou/moodle-filter_embedquestion/blob/master/showquestion.php is simpler still.&lt;br /&gt;
&lt;br /&gt;
Note that all the question engine code has extensive PHP documentor comments that should explain the purpose of every class and method. This document is supposed to provide an overview of the key points to get you started. It does not attempt to duplicate all the details in the PHPdocs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
The key class you will be working with is &amp;lt;tt&amp;gt;question_usage_by_activity&amp;lt;/tt&amp;gt;. This tracks an attempt at some questions, for example a quiz attempt. The usage should provide all the interface methods you need to do things with the question engine. You should rarely need to dive deeper into the inner workings of the question engine than this.&lt;br /&gt;
&lt;br /&gt;
A usage is a collection of &amp;lt;tt&amp;gt;question_attempt&amp;lt;/tt&amp;gt; objects. A question attempt represents the state of the user&#039;s attempt at one question within the usage. When you add a question to the usage, you get back a &#039;&#039;&#039;slot&#039;&#039;&#039; number. This serves to index that question within the attempt. Using slot numbers like this means that the same question can be added more than once to the same usage. A lot of the usage API calls take this slot number to indicate which question attempt to operate on. Other API methods let you perform batch actions on all the question attempts within the usage.&lt;br /&gt;
&lt;br /&gt;
==Starting an attempt at some questions==&lt;br /&gt;
&lt;br /&gt;
The example code in this section all came from &amp;lt;tt&amp;gt;mod/quiz/startattempt.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Creating the usage===&lt;br /&gt;
&lt;br /&gt;
To create a new usage, ask the question engine:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba = question_engine::make_questions_usage_by_activity(&#039;mod_quiz&#039;, $quizobj-&amp;gt;get_context());&lt;br /&gt;
$quba-&amp;gt;set_preferred_behaviour($quizobj-&amp;gt;get_quiz()-&amp;gt;preferredbehaviour);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will see that the constructor takes the plugin name (using the Moodle 2.0 &#039;frankenstyle&#039; naming convention) and the context that owns the usage. Usages should be cleaned up automatically when a context is deleted or a plugin un-installed. You also have to tell the usage which behaviour should be used when creating the attempt at each question.&lt;br /&gt;
&lt;br /&gt;
===Adding questions===&lt;br /&gt;
&lt;br /&gt;
Having got a usage, you will probably then want to add some questions to it. The question data you loaded from the database (probably using the &amp;lt;tt&amp;gt;get_question_options&amp;lt;/tt&amp;gt; function) come in a form suitable for data handling like import/export, backup/restore, and so on. We need to convert that to an &amp;lt;tt&amp;gt;question_definition&amp;lt;/tt&amp;gt; object. That can be done using the &amp;lt;tt&amp;gt;question_bank::make_question&amp;lt;/tt&amp;gt; method. Alternatively, you could just use the &amp;lt;tt&amp;gt;question_bank::load_question&amp;lt;/tt&amp;gt; method, but that can only load one question at a time.&lt;br /&gt;
&lt;br /&gt;
Once you have a &amp;lt;tt&amp;gt;question_definition&amp;lt;/tt&amp;gt; object, you add it to the usage by calling the &amp;lt;tt&amp;gt;add_question&amp;lt;/tt&amp;gt; method passing the question definition, and also the score you want this question marked out of. You get back the slot number that has been assigned to this question. The slot numbers are allocated in order, starting from 1. You can rely on that numbering convention. For example, the quiz module uses the slot numbers to make sure the grade for each question lines up properly in the reports.&lt;br /&gt;
&lt;br /&gt;
Here is the applicable code from the quiz module&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
foreach ($quizobj-&amp;gt;get_questions() as $i =&amp;gt; $questiondata) {&lt;br /&gt;
    $question = question_bank::make_question($questiondata);&lt;br /&gt;
    $idstoslots[$i] = $quba-&amp;gt;add_question($question, $questiondata-&amp;gt;maxmark);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Starting the question attempts===&lt;br /&gt;
&lt;br /&gt;
The usage does not do much when the question is added. Before the user can start interacting with the question, you have to start it. You can either do that in bulk:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba-&amp;gt;start_all_questions();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or you can start just one particular question using the &amp;lt;tt&amp;gt;start_question($slot)&amp;lt;/tt&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
===Saving the usage===&lt;br /&gt;
&lt;br /&gt;
So far, all these method calls have just built up a data structure in memory. If you want to keep it, you have to save it in the database. Fortunately, that is easy:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The usage is stored as a row in the &amp;lt;tt&amp;gt;question_usages&amp;lt;/tt&amp;gt; table (plus rows in other tables). To get the id of the usage, call &amp;lt;tt&amp;gt;$quba-&amp;gt;get_id()&amp;lt;/tt&amp;gt; after you have saved it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Displaying questions==&lt;br /&gt;
&lt;br /&gt;
Suppose that you wish to display a page that contains several questions from the usage. The questions to display will be the ones whose slot numbers are in an array called &amp;lt;tt&amp;gt;$slotsonpage&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The example code in this section is derived from code used by &amp;lt;tt&amp;gt;mod/quiz/attempt.php&amp;lt;/tt&amp;gt;. However, the quiz code is split between &amp;lt;tt&amp;gt;mod/quiz/attempt.php&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;quiz_attempt&amp;lt;/tt&amp;gt; class in &amp;lt;tt&amp;gt;mod/quiz/attemptlib.php&amp;lt;/tt&amp;gt;. That separation means that if I used the real quiz code in this tutorial, it would be unnecessarily hard to understand. Instead, I have simplified the examples below. If you are interested, you should be able to match up what you see below with the real quiz code.&lt;br /&gt;
&lt;br /&gt;
===Loading the usage===&lt;br /&gt;
&lt;br /&gt;
At the end of the last section, you had just saved the usage to the database. To display the questions as part of a different script, they must be loaded from the database again. Once again you ask the question engine to do this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($usageid);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The id that you pass to this method is the id you got from &amp;lt;tt&amp;gt;$quba-&amp;gt;get_id()&amp;lt;/tt&amp;gt; after saving the usage.&lt;br /&gt;
&lt;br /&gt;
===The question form===&lt;br /&gt;
&lt;br /&gt;
Within the page, all the questions have to be wrapped in a HTML &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;form&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; tag. This form needs to POST to a scripts that processes the submitted data ([[#Processing_responses|see below]]).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;&amp;lt;form id=&amp;quot;responseform&amp;quot; method=&amp;quot;post&amp;quot; action=&amp;quot;&#039; . $processurl .&lt;br /&gt;
        &#039;&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot; accept-charset=&amp;quot;utf-8&amp;quot;&amp;gt;&#039;, &amp;quot;\n&amp;lt;div&amp;gt;\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$PAGE-&amp;gt;requires-&amp;gt;js_init_call(&#039;M.core_question_engine.init_form&#039;,&lt;br /&gt;
        array(&#039;#responseform&#039;), false, &#039;core_question_engine&#039;);&lt;br /&gt;
&lt;br /&gt;
echo &#039;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;slots&amp;quot; value=&amp;quot;&#039; . implode(&#039;,&#039;, $slotsonpage) . &amp;quot;\&amp;quot; /&amp;gt;\n&amp;quot;;&lt;br /&gt;
echo &#039;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;scrollpos&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;enctype&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;accept-charset&amp;lt;/tt&amp;gt; parameters are important. Please copy them. The form must have an id, and you must then write some JavaScript that passes that id to to the &amp;lt;tt&amp;gt;question_init_form&amp;lt;/tt&amp;gt; function. That function is defined in &amp;lt;tt&amp;gt;question/qengine.js&amp;lt;/tt&amp;gt; if you want to find out what it does and why it is important.&lt;br /&gt;
&lt;br /&gt;
You should output a hidden form field &amp;lt;tt&amp;gt;slots&amp;lt;/tt&amp;gt; that contains a comma-separated list of the slot numbers that appear on this page. That is not absolutely necessary, but it will make processing the form submission much more efficient.&lt;br /&gt;
&lt;br /&gt;
Another nicety is the &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field. Some question behaviours, for example the interactive behaviour, have submit buttons that do something to the question. When the user clicks this button, it is nice if when the page re-displays, it is scrolled to exactly the same place where it was. The question engine has JavaScript which, if it finds a &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field, will automatically save the scroll position to it when a button is clicked, and cause the page to scroll to that position when it reloads.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Outputting the questions===&lt;br /&gt;
&lt;br /&gt;
Finally, you can actually print the questions. Well, there is one more thing to take care of first. To control how the question appears, you must prepare a &amp;lt;tt&amp;gt;question_display_options&amp;lt;/tt&amp;gt; object that describes what should be visible. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = new question_display_options();&lt;br /&gt;
$options-&amp;gt;marks = question_display_options::MAX_ONLY;&lt;br /&gt;
$options-&amp;gt;markdp = 2; // Display marks to 2 decimal places.&lt;br /&gt;
$options-&amp;gt;feedback = question_display_options::VISIBLE;&lt;br /&gt;
$options-&amp;gt;generalfeedback = question_display_options::HIDDEN;&lt;br /&gt;
// etc.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(In the quiz code, the display options actually come from the quiz settings.) Then you really are ready to output the questions&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
foreach ($slotsonpage as $displaynumber =&amp;gt; $slot) {&lt;br /&gt;
    echo $quba-&amp;gt;render_question($slot, $options, $displaynumber);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here &amp;lt;tt&amp;gt;$displaynumber&amp;lt;/tt&amp;gt; is the &#039;question number&#039; you want printed next to each question. This is not necessarily the same as the slot number. For example, in the quiz, Description &#039;questions&#039; are not numbered, although they take up a slot. It does not have to be a single integer (once MDL-62358 is fixed) if you have some other scheme for identifiying quesitions in your activity. For example you could pass &#039;4.3.1&#039; or &#039;7 of 10&#039; if that is what your activity needs. If you don&#039;t pass in a number to display, that is, if you pass null, then the question is printed without a Question X heading.&lt;br /&gt;
&lt;br /&gt;
==Processing responses==&lt;br /&gt;
&lt;br /&gt;
Once again, the example here are inspired by real code from the quiz module, in this case &amp;lt;tt&amp;gt;mod/quiz/processattempt.php&amp;lt;/tt&amp;gt;, but simplified to remove mention of the &amp;lt;tt&amp;gt;quiz_attempt&amp;lt;/tt&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The simple case===&lt;br /&gt;
&lt;br /&gt;
Normally, you just need to do something like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$timenow = time();&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($usageid);&lt;br /&gt;
$quba-&amp;gt;process_all_actions($timenow);&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Behind the scenes there is, of course, a lot going on, including the use of the &amp;lt;tt&amp;gt;slots&amp;lt;/tt&amp;gt; parameter to control which questions are processed.&lt;br /&gt;
&lt;br /&gt;
There may also be additional work you need to do. For example, in the quiz (before the &amp;lt;tt&amp;gt;commit_sql()&amp;lt;/tt&amp;gt; line) there is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if ($attempt-&amp;gt;timefinish) {&lt;br /&gt;
    $attempt-&amp;gt;sumgrades = $quba-&amp;gt;get_total_mark();&lt;br /&gt;
}&lt;br /&gt;
$attempt-&amp;gt;timemodified = $timenow;&lt;br /&gt;
$DB-&amp;gt;update_record(&#039;quiz_attempts&#039;, $attempt);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===More selective processing===&lt;br /&gt;
&lt;br /&gt;
If you want something other than the default processing, you can use code like &amp;lt;tt&amp;gt;$submitteddata = $quba-&amp;gt;extract_responses($slot); $quba-&amp;gt;process_action($slot, $submitteddata);&amp;lt;/tt&amp;gt; or something similar.&lt;br /&gt;
&lt;br /&gt;
===Handling scrollpos===&lt;br /&gt;
&lt;br /&gt;
You will remember that when we printed the questions, we created a &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; hidden field. Presumably, after you have processed the submission, you will redirect the user back to a page to display the questions again. In that case, you need to get the &amp;lt;tt&amp;gt;scrollpos&amp;lt;/tt&amp;gt; parameter, and add it on to the URL you redirect to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// With the other required/optional_param calls at the start of processattempt.php.&lt;br /&gt;
$scrollpos = optional_param(&#039;scrollpos&#039;, &#039;&#039;, PARAM_RAW);&lt;br /&gt;
&lt;br /&gt;
// ... a bit later in the file&lt;br /&gt;
$nexturl = new moodle_url(/* something */);&lt;br /&gt;
if ($scrollpos !== &#039;&#039;) {&lt;br /&gt;
    $nexturl-&amp;gt;param(&#039;scrollpos&#039;, (int) $scrollpos);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ... after all the processing is done.&lt;br /&gt;
redirect($nexturl);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reports==&lt;br /&gt;
&lt;br /&gt;
Places like the quiz reports, we need to get data about a lot of usages at the same time. There are methods on the &amp;lt;tt&amp;gt;question_engine_data_mapper&amp;lt;/tt&amp;gt; to do this. You should never access the data in the question engine tables directly.&lt;br /&gt;
&lt;br /&gt;
For example from the quiz grades report. (Again the example code has been simplified.)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// $qubaids is an array of integer ids.&lt;br /&gt;
$qubaidscondition = new qubaid_list($qubaids);&lt;br /&gt;
&lt;br /&gt;
$dm = new question_engine_data_mapper();&lt;br /&gt;
$latesstepdata = $dm-&amp;gt;load_questions_usages_latest_steps(&lt;br /&gt;
        $qubaidscondition, $slots);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;qubaid_list&amp;lt;/tt&amp;gt; is a subclass of the &amp;lt;tt&amp;gt;qubaid_condition&amp;lt;/tt&amp;gt; class. This is an efficient way to represent a set of usage ids in a way that can be used in database queries. The other main subclass is &amp;lt;tt&amp;gt;qubaid_join&amp;lt;/tt&amp;gt;. That could be used like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$qubaidscondition = new qubaid_join(&#039;{quiz_attempts} quiza&#039;, &#039;quiza.uniqueid&#039;,&lt;br /&gt;
        &#039;quiza.quiz = :quizaquiz&#039;, array(&#039;quizaquiz&#039; =&amp;gt; $quizid))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another example, from the quiz manual grading report is&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$dm = new question_engine_data_mapper();&lt;br /&gt;
$statesummary = $dm-&amp;gt;load_questions_usages_question_state_summary(&lt;br /&gt;
        $qubaidscondition, $slots);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Perhaps the use of the class &amp;lt;tt&amp;gt;question_engine_data_mapper&amp;lt;/tt&amp;gt; should be hidden inside a helper class &amp;lt;tt&amp;gt;question_engine_reporter&amp;lt;/tt&amp;gt;?)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Other methods==&lt;br /&gt;
&lt;br /&gt;
===Methods to help with settings UI===&lt;br /&gt;
&lt;br /&gt;
When you want to present users with a choice of question behaviour (for example, the quiz How questions behave option) use&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = question_engine::get_behaviour_options();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Question marks are stored in the database to a fixed number of decimal places. To get a list of possible decimal place display options, use&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$options = question_engine::get_dp_options();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Clean-up methods===&lt;br /&gt;
&lt;br /&gt;
To delete usages you no longer need:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// A single usage ...&lt;br /&gt;
question_engine::delete_questions_usage_by_activity($qubaid);&lt;br /&gt;
&lt;br /&gt;
// ... or many.&lt;br /&gt;
question_engine::delete_questions_usage_by_activities(&lt;br /&gt;
        new qubaid_join(&#039;{quiz_attempts} quiza&#039;, &#039;quiza.uniqueid&#039;,&lt;br /&gt;
        &#039;quiza.quiz = :quizaquiz&#039;, array(&#039;quizaquiz&#039; =&amp;gt; $quizid)));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Changing the score of a question in all attempts===&lt;br /&gt;
&lt;br /&gt;
Suppose you change the number of marks awarded to question 2 in the quiz, you need to change that information in every attempt at that quiz, you can do that with a call like&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
question_engine::set_max_mark_in_attempts($qubaids, $slot, $newmaxmark);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Re-grading a question===&lt;br /&gt;
&lt;br /&gt;
You only need to re-grade a question when the question definition is edited, for example to change the scoring rules. If you are just changing the maximum possible score for a question, see the previous sub-section.&lt;br /&gt;
&lt;br /&gt;
This code example is adapted from &amp;lt;tt&amp;gt;mod/quiz/report/overview/report.php&amp;lt;/tt&amp;gt;. It re-grades selected slots within a quiz attempt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
$quba = question_engine::load_questions_usage_by_activity($attempt-&amp;gt;uniqueid);&lt;br /&gt;
&lt;br /&gt;
foreach ($slots as $slot) {&lt;br /&gt;
    $oldfraction[$slot] = $quba-&amp;gt;get_question_fraction($slot);&lt;br /&gt;
    $quba-&amp;gt;regrade_question($slot);&lt;br /&gt;
    $newfraction[$slot] = $quba-&amp;gt;get_question_fraction($slot);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
question_engine::save_questions_usage_by_activity($quba);&lt;br /&gt;
$attempt-&amp;gt;sumgrades = $quba-&amp;gt;get_total_mark();&lt;br /&gt;
update_record(&#039;quiz_attempts&#039;, $attempt);&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
In the next section, [[Question Engine 2:Implementation plan|Implementation plan]] outlines how I will implement this proposal.&lt;br /&gt;
&lt;br /&gt;
* https://github.com/moodleou/moodle-filter_embedquestion/blob/master/showquestion.php is probably the simplest example code that displays a question and lets a user interact with it.&lt;br /&gt;
&lt;br /&gt;
* The PHP documenter comments that explain the purposes of every method in the question engine code.&lt;br /&gt;
* Back to [[Question_Engine_2|Question Engine 2]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=MoodleNet&amp;diff=63682</id>
		<title>MoodleNet</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=MoodleNet&amp;diff=63682"/>
		<updated>2022-11-14T05:37:41Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Moodlenet-logo.png|400px]]&lt;br /&gt;
== What is MoodleNet? ==&lt;br /&gt;
[https://moodle.net/ MoodleNet] is a federated and flexible Open Education Technology platform for curating collections of the best known Open Educational (and other) Resources. You&#039;ll find more general information in the [https://docs.moodle.org/moodlenet/Main_Page MoodleNet user documentation].&lt;br /&gt;
== Current status ==&lt;br /&gt;
Take a look at MoodleNet [https://tracker.moodle.org/projects/MDLNET?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&amp;amp;status=unreleased releases in our Tracker] and get involved by creating issues or reporting bugs, discussing and voting for features and connect with the MoodleNet team directly. &lt;br /&gt;
== Roadmap ==&lt;br /&gt;
* The MoodleNet release is available on the [https://tracker.moodle.org/projects/MDLNET?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&amp;amp;status=unreleased MoodleNet Roadmap].&lt;br /&gt;
== Important links ==&lt;br /&gt;
* [https://www.npmjs.com/package/@moodlenet/ce-platform Code repository]&lt;br /&gt;
* [https://docs.moodle.org/moodlenet/Main_Page MoodleNet user documentation]&lt;br /&gt;
* [https://moodle.org/mod/forum/view.php?id=8726 MoodleNet news and discussion]&lt;br /&gt;
* [https://tracker.moodle.org/secure/RapidBoard.jspa?rapidView=167&amp;amp;view=detail MoodleNet Issue Tracker]&lt;br /&gt;
[[es:MoodleNet]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Quiz_report_statistics&amp;diff=63680</id>
		<title>Quiz report statistics</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Quiz_report_statistics&amp;diff=63680"/>
		<updated>2022-11-06T23:12:44Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;These [http://www.education.com/reference/article/item-analysis/ statistics] are designed for use with [https://en.wikipedia.org/wiki/Summative_assessment summative tests] where students have just one attempt and complete that attempt.&#039;&#039;&#039;&lt;br /&gt;
== Test statistics ==&lt;br /&gt;
&#039;&#039;Average grade&#039;&#039;: For discriminating, deferred feedback, tests aim for between 50% and 75%. Values outside these limits need thinking about. Interactive tests with multiple tries invariably lead to higher averages.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Median grade&#039;&#039;: Half the students score less than this figure.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Standard deviation&#039;&#039;: A measure of the spread of scores about the mean. Aim for values between 12% and 18%. A smaller value suggests that scores are too bunched up.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Skewness&#039;&#039;: A measure of the asymmetry of the distribution of scores. Zero implies a perfectly symmetrical distribution, positive values a ‘tail’ to the right and negative values a ‘tail’ to the left.&lt;br /&gt;
&lt;br /&gt;
[[Image:Skewness.jpg]]&lt;br /&gt;
&lt;br /&gt;
Aim for a value of -1.0. If it is too negative, it may indicate lack of discrimination between students who do better than average. Similarly, a large positive value (greater than 1.0) may indicate a lack of discrimination near the pass fail border.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Kurtosis&#039;&#039;: Kurtosis is a measure of the flatness of the distribution.&lt;br /&gt;
&lt;br /&gt;
A normal, bell shaped, distribution has a kurtosis of zero. The greater the kurtosis, the more peaked is the distribution, without much of a tail on either side.&lt;br /&gt;
&lt;br /&gt;
Aim for a value in the range 0-1. A value greater than 1 may indicate that the test is not discriminating very well between very good or very bad students and those who are average.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Coefficient of internal consistency (CIC)&#039;&#039;: It is impossible to get internal consistency much above 90%. Anything above 75% is satisfactory. If the value is below 64%, the test as a whole is unsatisfactory and remedial measures should be considered.&lt;br /&gt;
&lt;br /&gt;
A low value indicates either that some of the questions are not very good at discriminating between students of different ability and hence that the differences between total scores owe a good deal to chance or that some of the questions are testing a different quality from the rest and that these two qualities do not correlate well – i.e. the test as a whole is inhomogeneous.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Error ratio (ER)&#039;&#039;: This is related to CIC according to the following table: it estimates the percentage of the standard deviation which is due to chance effects rather than to genuine differences of ability between students. Values of ER in excess of 50% cannot be regarded as satisfactory: they imply that less than half the standard deviation is due to differences in ability and the rest to chance effects.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! CIC&lt;br /&gt;
! ER&lt;br /&gt;
|-&lt;br /&gt;
| 100&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| 99&lt;br /&gt;
| 10&lt;br /&gt;
|-&lt;br /&gt;
| 96&lt;br /&gt;
| 20&lt;br /&gt;
|-&lt;br /&gt;
| 91&lt;br /&gt;
| 30&lt;br /&gt;
|-&lt;br /&gt;
| 84&lt;br /&gt;
| 40&lt;br /&gt;
|-&lt;br /&gt;
| 75&lt;br /&gt;
| 50&lt;br /&gt;
|-&lt;br /&gt;
| 64&lt;br /&gt;
| 60&lt;br /&gt;
|-&lt;br /&gt;
| 51&lt;br /&gt;
| 70&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;Standard error (SE)&#039;&#039;: This is SD x ER/100. It estimates how much of the SD is due to chance effects and is a measure of the uncertainty in any given student’s score. If the same student took an equivalent test, his or her score could be expected to lie within ±SE of the previous score. The smaller the value of SE the better the test, but it is difficult to get it below 5% or 6%. A value of 8% corresponds to half a grade difference on a typical scale – if the SE exceeds this, it is likely that a substantial proportion of the students will be wrongly graded in the sense that the grades awarded do not accurately indicate their true abilities.&lt;br /&gt;
== Question statistics ==&lt;br /&gt;
&#039;&#039;Facility index (F)&#039;&#039;: The mean score of students on the item.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! F&lt;br /&gt;
! Interpretation&lt;br /&gt;
|-&lt;br /&gt;
| 5 or less&lt;br /&gt;
| Extremely difficult or something wrong with the question.&lt;br /&gt;
|-&lt;br /&gt;
| 6-10&lt;br /&gt;
| Very difficult.&lt;br /&gt;
|-&lt;br /&gt;
| 11-20&lt;br /&gt;
| Difficult.&lt;br /&gt;
|-&lt;br /&gt;
| 21-34&lt;br /&gt;
| Moderately difficult.&lt;br /&gt;
|-&lt;br /&gt;
| 35-65&lt;br /&gt;
| About right for the average student.&lt;br /&gt;
|-&lt;br /&gt;
| 66-80&lt;br /&gt;
| Fairly easy.&lt;br /&gt;
|-&lt;br /&gt;
| 81-89&lt;br /&gt;
| Easy.&lt;br /&gt;
|-&lt;br /&gt;
| 90-94&lt;br /&gt;
| Very easy.&lt;br /&gt;
|-&lt;br /&gt;
| 95-100&lt;br /&gt;
| Extremely easy.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;Standard deviation (SD)&#039;&#039;: A measure of the spread of scores about the mean and hence the extent to which the question might discriminate. If F is very high or very low it is impossible for the spread to be large. Note however that a good SD does not automatically ensure good discrimination. A value of SD less than about a third of the question maximum (i.e. 33%) in the table is not generally satisfactory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Random guess score (RGS)&#039;&#039;: This is the mean score students would be expected to get for a random guess at the question. Random guess scores are only available for questions that use some form of multiple choice. All random guess scores are for deferred feedback only and assume the simplest situation e.g. for multiple response questions students will be told how many answers are correct.&lt;br /&gt;
&lt;br /&gt;
Values above 40% are unsatisfactory – and show that True/False questions must be used sparsely in summative tests.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Intended weight&#039;&#039;: The question weight expressed as a percentage of the overall test score.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Effective weight&#039;&#039;: An estimate of the weight the question actually has in contributing to the overall spread of scores. The effective weights should add to 100% - but read on.&lt;br /&gt;
&lt;br /&gt;
The intended weight and effective weight are intended to be compared. If the effective weight is greater than the intended weight it shows the question has a greater share in the spread of scores than may have been intended. If it is less than the intended weight it shows that it is not having as much effect in spreading out the scores as was intended.&lt;br /&gt;
&lt;br /&gt;
The calculation of the effective weight relies on taking the square root of the covariance of the question scores with overall performance. If a question’s scores vary in the opposite way to the overall score, this would indicate that this is a very odd question which is testing something different from the rest. And the computer cannot calculate the effective weights of such questions resulting in warning message boxes being displayed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Discrimination index&#039;&#039;: This is the correlation between the weighted scores on the question and those on the rest of the test. It indicates how effective the question is at sorting out able students from those who are less able. The results should be interpreted as follows&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Index&lt;br /&gt;
! Interpretation&lt;br /&gt;
|-&lt;br /&gt;
| 50 and above&lt;br /&gt;
| Very good discrimination&lt;br /&gt;
|-&lt;br /&gt;
| 30 – 50&lt;br /&gt;
| Adequate discrimination&lt;br /&gt;
|-&lt;br /&gt;
| 20 - 29&lt;br /&gt;
| Weak discrimination&lt;br /&gt;
|-&lt;br /&gt;
| 0 - 19&lt;br /&gt;
| Very weak discrimination&lt;br /&gt;
|-&lt;br /&gt;
| -ve&lt;br /&gt;
| Question probably invalid&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;Discrimination efficiency&#039;&#039;: This statistic attempts to estimate how good the discrimination index is relative to the difficulty of the question.&lt;br /&gt;
&lt;br /&gt;
An item which is very easy or very difficult cannot discriminate between students of different ability, because most of them get the same score on that question. Maximum discrimination requires a facility index in the range 30% - 70% (although such a value is no guarantee of a high discrimination index).&lt;br /&gt;
&lt;br /&gt;
The discrimination efficiency will very rarely approach 100%, but values in excess of 50% should be achievable. Lower values indicate that the question is not nearly as effective at discriminating between students of different ability as it might be and therefore is not a particularly good question.&lt;br /&gt;
&lt;br /&gt;
Note: The discrimation index is used in Moodle ≥ 4.0 to make a column &#039;Need for revision&#039; for questions in the question bank. Questions will probably need revision if the Discrimination index is on average very low.&lt;br /&gt;
&lt;br /&gt;
[[es:Estadísticas del reporte del examen]]&lt;br /&gt;
[[de:Test-Statistik]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63602</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63602"/>
		<updated>2022-09-02T05:06:36Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Contributors (financially) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=434031 this forum thread].&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* SWITCH eduhub Community, Switzerland&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* University of Applied Sciences and Arts Western Switzerland, Switzerland&lt;br /&gt;
* University College London, United Kingdom&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the Question bank improvements for Moodle 4.0 project ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63601</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63601"/>
		<updated>2022-09-02T05:05:47Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=434031 this forum thread].&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* SWITCH eduhub Community, Switzerland&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland&lt;br /&gt;
* University of Applied Sciences and Arts Western Switzerland, Switzerland&lt;br /&gt;
* University College London, United Kingdom&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the Question bank improvements for Moodle 4.0 project ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63592</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63592"/>
		<updated>2022-08-16T08:47:25Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Contributors (financially) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=434031 this forum thread].&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* SWITCH eduhub Community, Switzerland&lt;br /&gt;
* University of Applied Sciences and Arts Western Switzerland, Switzerland&lt;br /&gt;
* University College London, United Kingdom&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the Question bank improvements for Moodle 4.0 project ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63591</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63591"/>
		<updated>2022-08-16T08:45:59Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=434031 this forum thread].&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* SWITCH eduhub Community, Switzerland&lt;br /&gt;
* University College London, United Kingdom&lt;br /&gt;
* University of Applied Sciences and Arts Western Switzerland, Switzerland&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the Question bank improvements for Moodle 4.0 project ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63500</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63500"/>
		<updated>2022-06-29T09:47:48Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=434031 this forum thread].&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* SWITCH eduhub Community, Switzerland&lt;br /&gt;
* University of Applied Sciences and Arts Western Switzerland, Switzerland&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the Question bank improvements for Moodle 4.0 project ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63333</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63333"/>
		<updated>2022-06-16T18:10:23Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Contributors (financially) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=434031 this forum thread].&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* SWITCH eduhub Community, Switzerland&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the Question bank improvements for Moodle 4.0 project ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63332</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=63332"/>
		<updated>2022-06-16T18:09:58Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=434031 this forum thread].&lt;br /&gt;
&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* SWITCH eduhub Community&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the Question bank improvements for Moodle 4.0 project ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62131</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62131"/>
		<updated>2022-04-28T14:56:27Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Technical overview of the plans */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=434031 this forum thread].&lt;br /&gt;
&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the Question bank improvements for Moodle 4.0 project ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=62089</id>
		<title>Question bank improvements for Moodle 4.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=62089"/>
		<updated>2022-04-27T10:22:47Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.0&lt;br /&gt;
|state = Done&lt;br /&gt;
|tracker = MDL-70329&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=417599&lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]], Antonia Bonaccorso. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle_4.0}}&lt;br /&gt;
&lt;br /&gt;
This is a project to largely re-develop the question bank for Moodle 4.0 (if possible). The aim is to&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
This project has a follow-up project [[Question_bank_improvements_for_Moodle_4.1|Question bank improvements for Moodle 4.1]] which continues with the issues not making it into Moodle 4.0, and new additional requirements.&lt;br /&gt;
&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread]. That thread is quite long, with discussion of the plan, but the key posts which describe the plan are:&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1682674 Setting the scope]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683127 Question bank will be made up of plugins]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1687624 List of the plugins that will be created initially]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683186 Question bank will store the version history of each question]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1688163 How the question bank will track the places (quizzes) where questions are used]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1685143 Some initial UI wireframes]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1705076 Question (and following discussion) about how complicated the filtering/searching system needs to be at first]&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project ===&lt;br /&gt;
These institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=62088</id>
		<title>Question bank improvements for Moodle 4.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=62088"/>
		<updated>2022-04-27T10:20:22Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.0&lt;br /&gt;
|state = Done&lt;br /&gt;
|tracker = MDL-70329&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=417599&lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]], Antonia Bonaccorso. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle_4.0}}&lt;br /&gt;
&lt;br /&gt;
This is a project to largely re-develop the question bank for Moodle 4.0 (if possible). The aim is to&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread]. That thread is quite long, with discussion of the plan, but the key posts which describe the plan are:&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1682674 Setting the scope]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683127 Question bank will be made up of plugins]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1687624 List of the plugins that will be created initially]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683186 Question bank will store the version history of each question]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1688163 How the question bank will track the places (quizzes) where questions are used]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1685143 Some initial UI wireframes]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1705076 Question (and following discussion) about how complicated the filtering/searching system needs to be at first]&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project ===&lt;br /&gt;
These institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62077</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62077"/>
		<updated>2022-04-26T08:38:43Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is not yet outlined in a forum thread.&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the Question bank improvements for Moodle 4.0 project ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62076</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62076"/>
		<updated>2022-04-26T07:52:02Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Work-in-progress */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is not yet outlined in a forum thread.&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will add more information here, for example links to a prototype site.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project and Question bank improvements for Moodle 4.0 ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 and/or the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62075</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62075"/>
		<updated>2022-04-26T07:51:34Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Overflowing funds from the SEB deeper integration project and Question bank improvements for Moodle 4.0 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is not yet outlined in a forum thread.&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project and Question bank improvements for Moodle 4.0 ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.0 and/or the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62074</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62074"/>
		<updated>2022-04-26T07:50:32Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is not yet outlined in a forum thread.&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project and Question bank improvements for Moodle 4.0 ===&lt;br /&gt;
These institutions are credited here since they participated in the Question bank improvements for Moodle 4.1 and/or the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62070</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62070"/>
		<updated>2022-04-25T13:15:21Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is not yet outlined in a forum thread.&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.1#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project and Question bank improvements for Moodle 4.0 ===&lt;br /&gt;
These institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62069</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62069"/>
		<updated>2022-04-25T13:11:59Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0|Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is not yet outlined in a forum thread.&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project and Question bank improvements for Moodle 4.0 ===&lt;br /&gt;
These institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62068</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62068"/>
		<updated>2022-04-25T13:11:18Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0#Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* replace the question bank with a mod_qbank activity.&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is not yet outlined in a forum thread.&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project and Question bank improvements for Moodle 4.0 ===&lt;br /&gt;
These institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62067</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62067"/>
		<updated>2022-04-25T12:25:59Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0#Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread]. That thread is quite long, with discussion of the plan, but the key posts which describe the plan are:&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1682674 Setting the scope]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683127 Question bank will be made up of plugins]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1687624 List of the plugins that will be created initially]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683186 Question bank will store the version history of each question]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1688163 How the question bank will track the places (quizzes) where questions are used]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1685143 Some initial UI wireframes]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1705076 Question (and following discussion) about how complicated the filtering/searching system needs to be at first]&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project and Question bank improvements for Moodle 4.0 ===&lt;br /&gt;
These institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62066</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62066"/>
		<updated>2022-04-25T12:15:48Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [[Question_bank_improvements_for_Moodle_4.0#Question bank improvements for Moodle 4.0]] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread]. That thread is quite long, with discussion of the plan, but the key posts which describe the plan are:&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1682674 Setting the scope]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683127 Question bank will be made up of plugins]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1687624 List of the plugins that will be created initially]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683186 Question bank will store the version history of each question]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1688163 How the question bank will track the places (quizzes) where questions are used]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1685143 Some initial UI wireframes]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1705076 Question (and following discussion) about how complicated the filtering/searching system needs to be at first]&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project ===&lt;br /&gt;
These institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62065</id>
		<title>Question bank improvements for Moodle 4.1</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.1&amp;diff=62065"/>
		<updated>2022-04-25T12:14:12Z</updated>

		<summary type="html">&lt;p&gt;Finns: Created page with &amp;quot;{{Infobox Project |name = Question bank improvements for Moodle 4.1 |state = Development in progress |tracker = MDL-72752 |discussion =  |assignee = Project instigated by Us...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.1&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-72752&lt;br /&gt;
|discussion = &lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]]. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle_4.1}}&lt;br /&gt;
&lt;br /&gt;
This is a project to continue the issues initially planned with the [Question bank improvements for Moodle 4.0] project, and new additional requirements.&lt;br /&gt;
The aim is to&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread]. That thread is quite long, with discussion of the plan, but the key posts which describe the plan are:&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1682674 Setting the scope]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683127 Question bank will be made up of plugins]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1687624 List of the plugins that will be created initially]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683186 Question bank will store the version history of each question]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1688163 How the question bank will track the places (quizzes) where questions are used]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1685143 Some initial UI wireframes]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1705076 Question (and following discussion) about how complicated the filtering/searching system needs to be at first]&lt;br /&gt;
== Project support ==&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
== Contributors ==&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project ===&lt;br /&gt;
These institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_4.0_developer_update&amp;diff=61801</id>
		<title>Moodle 4.0 developer update</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_4.0_developer_update&amp;diff=61801"/>
		<updated>2022-03-13T22:07:03Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 4.0}}This page highlights the important changes that are coming in Moodle 4.0 for developers. Including how the UX improvements impact custom themes, relevant API changes, and what you can do as developer to prepare for the 4.0 release.&lt;br /&gt;
== Navigation changes ==&lt;br /&gt;
The core Navigation API has been left mostly untouched. The callbacks to all navigation callbacks remains unchanged and will be called as part of the regular &#039;navigation&#039; and &#039;settingsnav&#039; initialisation. Some new core classes have been created and exist within a new namespace &#039;core/navigation&#039; and serves as conduit to rearrange, cherry-pick existing navigation nodes from the navigation/settingsnav trees and display within the respective navigation type. As such, it is highly recommended to provide unique keys for custom navigation nodes as this helps in the cherry-picking / rearranging process within the new classes.&lt;br /&gt;
=== Primary navigation ===&lt;br /&gt;
The primary navigation(the navbar) apart from the existing content will now display links to the Dashboard, My Courses, Site Admin and Course search, by default. You can still add items to the navbar via the &#039;custom menu&#039; option. This will be displayed within the &#039;More&#039; menu. We have transitioned the menus to be rendered via templates - refer user_menu.mustache. The lang menu has been moved to reside within the user menu.&lt;br /&gt;
==== Customising the primary navigation ====&lt;br /&gt;
Not yet implemented but we are looking at allowing the full addition and removal of any of the primary navigation tabs in the boost theme config file.&lt;br /&gt;
=== Secondary navigation ===&lt;br /&gt;
The main content area shows tabs for secondary navigation with a maximum of 5 items being rendered in this ‘more’ menu. A new UI component has been created to render menus like this. Files:&lt;br /&gt;
 /lib/templates/moremenu.mustache&lt;br /&gt;
==== Changing the order of tabs ====&lt;br /&gt;
Apart from the previously mentioned functions, you can also create a custom secondary class as mentioned earlier. This will automatically be picked by getter and used to render the secondary nav within the activity. E.g. mod_assign/local/views/secondary. Note: This is currently only possible on an activity and block level. &lt;br /&gt;
=== Tertiary navigation ===&lt;br /&gt;
=== New API functions ===&lt;br /&gt;
==== Page API ====&lt;br /&gt;
* Magic getters to fetch the primary and secondary navs and the primary output.&lt;br /&gt;
* The secondarynav magic getter also checks whether a custom secondary class has been defined within the module&#039;s local\views directory. Use this if you want to deviate from the standard secondary nav structure/order.&lt;br /&gt;
&lt;br /&gt;
* set_secondary_nav - Force override the secondary navigation class&lt;br /&gt;
&lt;br /&gt;
* has_secondary_navigation_setter - Sets the ‘_hassecondarynavigation’ to indicate whether a page should render the secondary navigation&lt;br /&gt;
==== Navigationlib ====&lt;br /&gt;
* set_show_in_secondary_navigation - whether or not a node should be displayed in the secondary nav. Accepts a single boolean argument&lt;br /&gt;
* set_force_into_more_menu- whether or not to force a node into the &#039;More&#039; menu. Accepts a single boolean argument&lt;br /&gt;
==== The activity header class ====&lt;br /&gt;
There is a new activity header class that handles the display of information common to activities. 3rd party activities are not required to explicitly output this information as part of rendering individual pages.&lt;br /&gt;
&lt;br /&gt;
The common information that are currently handled by the class are:&lt;br /&gt;
* title&lt;br /&gt;
* description&lt;br /&gt;
* completion information&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As part of the update it was required that the initial information to be displayed by the class be toggable at a theme and layout level. Taking this into account the following theme level configurable exists:&lt;br /&gt;
* activityheaderconfig =&amp;gt; An array that currently only enforces &#039;notitle&#039; but can be expanded in the future NOTE: Boost has this set as true by default &#039;options&#039;&lt;br /&gt;
The following layout level options that can be defined:&lt;br /&gt;
* noactivityheader - to remove the header in this specific layout.&lt;br /&gt;
* activityheader - An array that enforces the following options:&lt;br /&gt;
** notitle&lt;br /&gt;
** nocompletion&lt;br /&gt;
** nodescription&lt;br /&gt;
The class has a page level getter which you can use to fetch the current version of the class. The base state is initialised within the constructor with the completion information only fetched when data is exported for the template.&lt;br /&gt;
&lt;br /&gt;
The class has setters for the following variables which can be leveraged to modify the header for a particular page in the format set_{variable_name}:&lt;br /&gt;
* hidecompletion&lt;br /&gt;
* description&lt;br /&gt;
* title&lt;br /&gt;
Alternately, bulk operations can also be done by passing the above variables in an array to &#039;set_attrs&#039; which in turn calls the setters.&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Note: Any updates to the activityheader needs to be performed before the call to $OUTPUT-&amp;gt;header&#039;&#039;&#039;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
===== Theme updates: =====&lt;br /&gt;
In order for 3rd party themes to use the class they need to export the activity_header and include the following into their base template :&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
{{#headercontent}}&lt;br /&gt;
   {{&amp;gt; core/activity_header}}&lt;br /&gt;
{{#headercontent}}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;** headercontent being the array element that contains the exported activity_header data &lt;br /&gt;
===== Accessibility notes: =====&lt;br /&gt;
The jump to ‘maincontent’ div is now rendered within the activity header when within an activity context&lt;br /&gt;
== Component library ==&lt;br /&gt;
Each Moodle installation now ships with a Moodle User Interface (UI) Component library, a documentation system used to describe all the Bootstrap components and the custom Moodle components. The component Library is a helper tool for developers when creating user interfaces, a testing tool for theme developers and a documentation tool for core developers. The ultimate goal of having a component library is to encourage developers to create consistent user interfaces to improve Moodle’s overall user experience.&lt;br /&gt;
&lt;br /&gt;
The library contains pages with documentation about User Interface components. It contains details on how to use the component, what variations are available and the JavaScript events / options are associated with the component.&lt;br /&gt;
&lt;br /&gt;
When writing on these pages it is possible to render core mustache templates using some custom syntax like this:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{&amp;lt; mustache template=&amp;quot;core/notification_error&amp;quot; &amp;gt;}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{&amp;lt; /mustache &amp;gt;}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
You can also call core JavaScript or use HTML examples where the html code and the rendered result are visible in the Component Library. For more info visit the [http://componentlibrary.moodle.com/admin/tool/componentlibrary/docspage.php/library/moodle-templates/ Moodle templates] page or the [http://componentlibrary.moodle.com/admin/tool/componentlibrary/docspage.php/library/moodle-javascript/ Moodle JavaScript] page.&lt;br /&gt;
&lt;br /&gt;
Each page in the library uses the current css from the default theme in your Moodle installation, if you have multiple themes installed and enabled the setting &amp;quot;Allow theme changes on url&amp;quot;, the component library will have a theme selector option.&lt;br /&gt;
&lt;br /&gt;
A hosted version of the Component Library can be found here. http://componentlibrary.moodle.com&lt;br /&gt;
=== Enabling the Component Library ===&lt;br /&gt;
Component library pages are written in the markdown language. These pages need to be compiled to HTML pages before the Component Library is visible. To compile the pages the server running Moodle needs to have the [[Javascript Modules#Install%20NVM%20and%20Node|JavaScript developer tools installed]] (nodeJs and Grunt)&lt;br /&gt;
&lt;br /&gt;
If your server meets all requirements you can enable the library running&lt;br /&gt;
 $ npm install&lt;br /&gt;
 $ grunt componentlibrary&lt;br /&gt;
Further installation instructions can be found in the Component Library itself.&lt;br /&gt;
=== Documenting new UI Components ===&lt;br /&gt;
There are no set rules for adding new pages in the component library yet. These rules will need to be written and adopted in the integration process for Moodle code.&lt;br /&gt;
&lt;br /&gt;
As a guideline for making this rules consideration are:&lt;br /&gt;
&lt;br /&gt;
The component library is not about single use components, for example the Moodle grade book (a huge component with many custom features). Or about very common components like buttons, these are already covered by the Bootstrap section of the component library.&lt;br /&gt;
&lt;br /&gt;
New features should be build keeping in mind the UI part needs to be customisable and if possible (and making sense) reusable. And example would be the new page drawers that we are introducing for the Navigation project. Or the custom primary navigation menus where overflowing items are pushed into a More section.&lt;br /&gt;
== Theme changes ==&lt;br /&gt;
=== Edit switch ===&lt;br /&gt;
On theme boost the “Turn editing on” and “Customise this page” buttons have been replaced by an edit switch in the top navbar. Theme Classic will keep using the old buttons. Child themes can choose to use the edit switch if the theme config.php is using this variable&lt;br /&gt;
 $THEME-&amp;gt;haseditswitch = true;&lt;br /&gt;
The languague menu, which used to be rendered in place of the custom menu has moved to the user dropdown when the user is logged in. If not logged in it will be placed next to the search / notification / messaging icon in the top navbar.&lt;br /&gt;
=== Login page ===&lt;br /&gt;
The login page has been redesigned and allows the admin to configure a background image for the login page only in the theme settings page. This change is available in both Boost and Classic. The login page still has all the features with an improved layout. &lt;br /&gt;
=== The page footer ===&lt;br /&gt;
In large screens, the page footer button is only visible when clicking a help button at the bottom right of the screen.&lt;br /&gt;
=== User initials as profile picture placeholder ===&lt;br /&gt;
If users do not upload a profile picture the user initials are displayed on a rounded gray background as a placeholder picture in the top navbar or any other page using a placeholder image. This change will be available in both Boost and Classic. &lt;br /&gt;
&lt;br /&gt;
With the introduction of this placeholder image the full username will no longer be displayed in the top navbar.&lt;br /&gt;
=== Removal of back to top link ===&lt;br /&gt;
The &amp;quot;back to top&amp;quot; link will be removed for theme boost since the new course index reduced the dependence on page scrolling. Also, the new footer is positioned where this component used to be.&lt;br /&gt;
=== Styling changes ===&lt;br /&gt;
By default rounded edges will be used for UI components, for the page header and main content area the borders will be removed. &lt;br /&gt;
=== New layout page ===&lt;br /&gt;
Theme boost now uses the drawers.php layout for the course index and blocks.&lt;br /&gt;
== Question bank changes ==&lt;br /&gt;
There was a big project to deliver [[Question bank improvements for Moodle 4.0]] which added a new plugin type for adding features to the question banks, tracking the version history for each question as it is edited (question table has been split into &amp;lt;code&amp;gt;question&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;question_versions&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;question_bank_entries&amp;lt;/code&amp;gt;), and tracking where each question is going to be used, with new tables &amp;lt;code&amp;gt;question_references&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;question_set_references&amp;lt;/code&amp;gt;. This work was done in Epic MDL-70329 if you want to track down the details of any of the core changes.&lt;br /&gt;
=== Question type plugins ===&lt;br /&gt;
Amazingly, we (Safat and colleagues at Catalyst AU) managed to implement this without breaking most question type plugins.&lt;br /&gt;
&lt;br /&gt;
However, the changes to the question bank, and the other Moodle 4.0 changes, probably broke the Behat tests for your plugin. To help with fixing that, MDL-74130 adds navigation to key question type pages (Preview and Edit for a question, and standard question bank pages like the bank itself, import and export) which should let you fix your test efficiently, and in a way that will work in all Moodle versions since 3.9.&lt;br /&gt;
&lt;br /&gt;
The &#039;most&#039; in the first paragraph here is becuase more advance question types may require more effort to fix. (For example qtype_combined which creates multi-part qusetions like the core qtype_multianswer; or qtype_pmatch or qtype_stack, which store additional data - questions tests - alongside the question itseld. How should that work with versionning?) But, if you have not done weird things like that, you are probably safe. If you find anything else that causes problems, please list it here.&lt;br /&gt;
&lt;br /&gt;
The same thing should apply to question behaviour and question import/export format plugings: no significant changes required (probably just fixing the Behat tests because of the navigation changes).&lt;br /&gt;
=== New plugin type: qbank plugins ===&lt;br /&gt;
This is not something that will cause problems for people upgrading from 3.x. Rather, it is an exciting possibility you can explore once you have survived process of upgrading to 4.0. There is a whole new plugin type which you can create to add new features to the question bank. For example extra columns, new actions and bulk actions, and so on. See [[Question_bank_plugins]].&lt;br /&gt;
=== Activities that use questions ===&lt;br /&gt;
The probable bad news is if you have an activity module which uses questions. So far, the only activity which has been fixed is mod_quiz in Moodle core, so we don&#039;t yet have a good picture of what fixes will be necessary in other activities. Work is about to start fixing [https://github.com/studentquiz/moodle-mod_studentquiz mod_studentquiz], so watching that should give more clues. As we do that, we will try to update this section of this page. Other help writing the information required here would also be greatly appreciated.&lt;br /&gt;
== The course format system ==&lt;br /&gt;
Most of the logic for rendering and editing a course has been moved to a new subsystem called courseformat. The subsystem is located in &amp;quot;course/format&amp;quot; folder so it includes all the format plugins inside. The methods and modules which are distributed between the course and the course/format folders are now rearranged or refactored to be aligned with the current Moodle coding style.&lt;br /&gt;
=== Mandatory renderer in course formats ===&lt;br /&gt;
Now format plugins renderer is not optional anymore. Legacy formats without a renderer will get a deprecation message but it will continue working however, they should create a new renderer as soon as possible. The section-based format can do it by extending the provided core_courseformat\output\section_renderer class which includes all the necessary methods.&lt;br /&gt;
=== New format base class ===&lt;br /&gt;
The old base_format class (which all plugins extend) is now renamed as core_courseformat\base. The new class provides all the functionally of the previous base_format but it has been refactored to be used as a centralized source of truth for the course rendering. Legacy formats should extend the new class to avoid the deprecation message.&lt;br /&gt;
&lt;br /&gt;
Now, the plugin format class provides information such as:&lt;br /&gt;
* If the page is displaying a single or multiple section&lt;br /&gt;
* Give access to other related format objects like the modinfo, the course record, maximum number of sections...&lt;br /&gt;
* If the format is compatible with features like course index, reactive components, ajax...&lt;br /&gt;
* Other format specifics like the page title, the default section name, default blocks...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The format instance is now the main object output components will use to render a course (see next section for more information).&lt;br /&gt;
=== New course output classes and mustache files ===&lt;br /&gt;
Traditionally, section-based course formats uses print_single_section_page and print_multiple_section_page to render the course content. In Moodle 4.0 most of the course rendering methods are migrated to output components and mustache templates. The old methods will get deprecation messages if they use the old renderer methods.&lt;br /&gt;
&lt;br /&gt;
This is an example of a format rendering a course:&amp;lt;syntaxhighlight lang=&amp;quot;php-brief&amp;quot;&amp;gt;&lt;br /&gt;
// Get the course format instance.&lt;br /&gt;
$format = course_get_format($course);&lt;br /&gt;
&lt;br /&gt;
// Get the specific format renderer.&lt;br /&gt;
$renderer = $format-&amp;gt;get_renderer($PAGE);&lt;br /&gt;
&lt;br /&gt;
if (!empty($displaysection)) {&lt;br /&gt;
    // Setup the format instance to display a single section.&lt;br /&gt;
    $format-&amp;gt;set_section_number($displaysection);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Create the ouptut instance and render it.&lt;br /&gt;
$outputclass = $format-&amp;gt;get_output_classname(&#039;content&#039;);&lt;br /&gt;
$widget = new $outputclass($format);&lt;br /&gt;
&lt;br /&gt;
echo $renderer-&amp;gt;render($widget);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Format plugins are free to use its own output classes to render a course, or they could override the existing output classes by providing their own implementation. For example, the default output for &amp;quot;content&amp;quot; (as in the previous example) is &amp;quot;core_courseformat\output\local\|content&amp;quot;, however, if the plugin has a &amp;quot;format_XXX\output\courseformat\content&amp;quot; class, the $format-&amp;gt;class the get_output_class will return the overridden one.&lt;br /&gt;
Another important update on course rendering is that now all course structure is rendered using mustache templates instead of the original html_writer methods. Now themes are able to override the course format by providing alternative versions of the mustache files. All core course templates are located in &amp;quot;course/format/templates&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
All the new output classes and a guide on how to migrate the current third-party plugins will be available soon.&lt;br /&gt;
=== Course editor javascript modules and frontend components ===&lt;br /&gt;
The majority of the javascript logic related to the course editing is replaced by AMD modules. Because this is a major change in the way courses are edited and rendered, by default format plugins will continue using the previous YUI modules for now. However, formats can start using the new libraries overriding the &amp;quot;$format-&amp;gt;supports_components()&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Some Moodle 4.0 new features are only available for courses using the new editor library:&lt;br /&gt;
* Edit the course via the course index&lt;br /&gt;
* Creating sections without reloading the course page&lt;br /&gt;
* The new move section/activity modal&lt;br /&gt;
* Native browser drag&amp;amp;drop implementation&lt;br /&gt;
The new course editor uses a component-based reactive pattern to keep track of the course changes. The pattern highlights are:&lt;br /&gt;
* The main AMD module &amp;quot;core_crouseformat\courseeditor&amp;quot; maintains a data structure called state.&lt;br /&gt;
* Each UI element is implemented as a Component that observes the course state data and reacts to any data change&lt;br /&gt;
* When any reactive component needs to modify the course, it asks the course editor to execute a mutation. Mutations encapsulate all web services calls and alter the course state data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The reactive library documentation, as well as the format plugin migration guide, will be available soon.&lt;br /&gt;
=== Other course related 4.0 changes ===&lt;br /&gt;
Two new web services have been added:&lt;br /&gt;
* core_courseformat_get_state: user by the new javascript course editor to get the current course state data (containing the list of sections, activities, and other course-related data)&lt;br /&gt;
* core_courseformat_update_course: to alter the current course content. Each call returns the parts of the course state altered by the action&lt;br /&gt;
== Behat changes ==&lt;br /&gt;
&lt;br /&gt;
=== New steps ===&lt;br /&gt;
Moodle 4.0 introduces some new behat steps.&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to create a bulk number of activities. In that case you can use:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
:count :entitytype exist with the following data:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
Given 100 &amp;quot;mod_lti &amp;gt; tool types&amp;quot; exist with the following data:&lt;br /&gt;
  |name        |Test tool [count]                  |&lt;br /&gt;
  |description |Example description [count]        |&lt;br /&gt;
  |baseurl     |https://www.example.com/tool[count]|&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dynamic (AJAX) tabs is a new feature contributed to Moodle 4.0 by the Workplace team (MDL-71943). You can use the following step to navigate between the tabs.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I click on the &amp;quot;tab title&amp;quot; dynamic tab&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To make sure that edit mode is (or is not) available on the current page, the following steps can be used.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And edit mode should be available on the current page&lt;br /&gt;
And edit mode should not be available on the current page&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are new aliases for the existing steps &amp;lt;code&amp;gt;I turn editing mode on&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;I turn editing mode off&amp;lt;/code&amp;gt;.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I switch editing mode on&lt;br /&gt;
And I switch editing mode off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to the existing step to go to a course with editing mode on, we now have the following step to do the same but with editing mode being off.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I am on &amp;quot;course full name&amp;quot; course homepage with editing mode off&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following step is similar to the old &amp;lt;code&amp;gt;following &amp;quot;link string&amp;quot; should download between &amp;quot;min bytes&amp;quot; and &amp;quot;max bytes&amp;quot; bytes&amp;lt;/code&amp;gt; step, with more flexibility.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And following &amp;quot;element string&amp;quot; &amp;quot;element type&amp;quot; in the &amp;quot;container string&amp;quot; &amp;quot;container type&amp;quot; should download between &amp;quot;min bytes&amp;quot; and &amp;quot;max bytes&amp;quot; bytes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And following &amp;quot;Download&amp;quot; &amp;quot;link&amp;quot; in the &amp;quot;Starter&amp;quot; &amp;quot;table_row&amp;quot; should download between &amp;quot;0&amp;quot; and &amp;quot;5000&amp;quot; bytes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following step can be used to hover the mouse over the trigger area.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I hover over the &amp;quot;element string&amp;quot; &amp;quot;element type&amp;quot; in the &amp;quot;container string&amp;quot; &amp;quot;container type&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following step enables an installed plugin.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I enable &amp;quot;plugin name&amp;quot; &amp;quot;plugin type&amp;quot; plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I enable &amp;quot;course_summary&amp;quot; &amp;quot;block&amp;quot; plugin&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following is a special variation of &#039;I click on &amp;quot;&amp;lt;page name&amp;gt;&amp;quot; &amp;quot;link&amp;quot; in the &amp;quot;page&amp;quot; &amp;quot;region&amp;quot;&#039;. It first checks to see if we are on the given page via the breadcrumb. If not we then attempt to follow the link name given.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I follow the breadcrumb &amp;quot;page name&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can use the following step to ensure a node is active in the navbar.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I should see &amp;quot;Node&amp;quot; is active in navigation&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I should see &amp;quot;My courses&amp;quot; is active in navigation&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following step can be used to navigate to a given node in the primary navigation.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I select &amp;quot;Node&amp;quot; from primary navigation&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following steps are to check whether an item exists in the user menu or not.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And &amp;quot;item text&amp;quot; &amp;quot;selector type&amp;quot; should exist in the user menu&lt;br /&gt;
And &amp;quot;item text&amp;quot; &amp;quot;selector type&amp;quot; should not exist in the user menu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And &amp;quot;Language&amp;quot; &amp;quot;link&amp;quot; should exist in the user menu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following steps are to check if a submenu of the user menu is shown, and if an item exists or does not exist in a given user submenu.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I should see &amp;quot;submenu name&amp;quot; user submenu&lt;br /&gt;
And &amp;quot;item text&amp;quot; &amp;quot;selector type&amp;quot; should exist in the &amp;quot;submenu name&amp;quot; user submenu&lt;br /&gt;
And &amp;quot;item text&amp;quot; &amp;quot;selector type&amp;quot; should not exist in the &amp;quot;submenu name&amp;quot; user submenu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
When I follow &amp;quot;Language&amp;quot; in the user menu&lt;br /&gt;
Then I should see &amp;quot;Language selector&amp;quot; user submenu&lt;br /&gt;
And &amp;quot;English &amp;amp;lrm;(en)&amp;amp;lrm;&amp;quot; &amp;quot;link&amp;quot; should exist in the &amp;quot;Language selector&amp;quot; user submenu&lt;br /&gt;
And &amp;quot;English (pirate) &amp;amp;lrm;(en_ar)&amp;amp;lrm;&amp;quot; &amp;quot;link&amp;quot; should not exist in the &amp;quot;Language selector&amp;quot; user submenu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To add enrolment methods to courses you can use the following new step. The data that you provide in the next lines are used to fill the enrolment method form.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I add &amp;quot;enrolment method&amp;quot; in &amp;quot;course identifier&amp;quot; with:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
When I add &amp;quot;Self enrolment&amp;quot; enrolment method in &amp;quot;Course 1&amp;quot; with:&lt;br /&gt;
  | Custom instance name     | Test student enrolment |&lt;br /&gt;
  | Enrolment key            | moodle_rules           |&lt;br /&gt;
  | Use group enrolment keys | Yes                    |&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are 3 new steps specific to the calendar component. These steps can be used to hover over a day in the mini-calendar or the full calendar.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I hover over day &amp;quot;day of month&amp;quot; of this month in the full calendar page&lt;br /&gt;
And I hover over day &amp;quot;day of month&amp;quot; of this month in the mini-calendar block&lt;br /&gt;
And I hover over today in the mini-calendar block&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some new steps are added to question bank to be able to add comment to questions, verify the existence of a comment, and deleting comments form questions. Please note that the steps for adding comments only write the comment text in the comment field. You still need to click on the &amp;quot;Add comment&amp;quot; button to save the comment.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I add &amp;quot;comment text&amp;quot; comment to question&lt;br /&gt;
And I add &amp;quot;comment text&amp;quot; comment to question preview&lt;br /&gt;
And I delete &amp;quot;comment text&amp;quot; comment from question&lt;br /&gt;
And I delete &amp;quot;comment text&amp;quot; comment from question preview&lt;br /&gt;
And I should see &amp;quot;number of comments&amp;quot; on the comments column&lt;br /&gt;
And I click &amp;quot;number of comments&amp;quot; on the row on the comments column&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I navigate to &amp;quot;Question bank&amp;quot; in current page administration&lt;br /&gt;
And I should see &amp;quot;0&amp;quot; on the comments column&lt;br /&gt;
And I click &amp;quot;0&amp;quot; on the row on the comments column&lt;br /&gt;
And I add &amp;quot;test comment 01&amp;quot; comment to question&lt;br /&gt;
And I click on &amp;quot;Add comment&amp;quot; &amp;quot;button&amp;quot; in the &amp;quot;.modal-dialog&amp;quot; &amp;quot;css_element&amp;quot;&lt;br /&gt;
And I click on &amp;quot;Close&amp;quot; &amp;quot;button&amp;quot; in the &amp;quot;.modal-dialog&amp;quot; &amp;quot;css_element&amp;quot;&lt;br /&gt;
And I should see &amp;quot;1&amp;quot; on the comments column&lt;br /&gt;
And I click &amp;quot;1&amp;quot; on the row on the comments column&lt;br /&gt;
And I delete &amp;quot;test comment 01&amp;quot; comment from question&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similar to the steps for comments, the following steps are to verify the number of a question&#039;s usage and to click on it in order to open the question usage modal.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I should see &amp;quot;usage count&amp;quot; on the usage column&lt;br /&gt;
And I click &amp;quot;usage count&amp;quot; on the usage column&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following new steps are related to bulk actions in the question bank UI.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I click on question bulk action &amp;quot;action&amp;quot;&lt;br /&gt;
And I should see question bulk action &amp;quot;action&amp;quot;&lt;br /&gt;
And I should not see question bulk action &amp;quot;action&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I click on &amp;quot;First question&amp;quot; &amp;quot;checkbox&amp;quot;&lt;br /&gt;
And I click on &amp;quot;Second question&amp;quot; &amp;quot;checkbox&amp;quot;&lt;br /&gt;
And I click on &amp;quot;With selected&amp;quot; &amp;quot;button&amp;quot;&lt;br /&gt;
And I should see question bulk action &amp;quot;deleteselected&amp;quot;&lt;br /&gt;
And I click on question bulk action &amp;quot;deleteselected&amp;quot;&lt;br /&gt;
And I click on &amp;quot;Delete&amp;quot; &amp;quot;button&amp;quot; in the &amp;quot;Confirm&amp;quot; &amp;quot;dialogue&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://docs.moodle.org/en/Report_builder Report builder] is a new feature contributed to Moodle 4.0 by the Workplace team. The following new step is added to Moodle 4.0 to select an action from the action menu in the list of custom reports table.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I press &amp;quot;action&amp;quot; action in the &amp;quot;report name&amp;quot; report row&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There&#039;s another step related to the report builder to set a column&#039;s aggregation in the report editor.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I set the &amp;quot;column title&amp;quot; column aggregation to &amp;quot;aggregation method&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I set the &amp;quot;First name&amp;quot; column aggregation to &amp;quot;Comma separated values&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following step needs to be used in scenarios that involve testing BigBlueButton. For this to work, you need to have a [https://github.com/moodlehq/bigbluebutton_mock BigBlueButton Mock API Server] and set &amp;lt;code&amp;gt;TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER&amp;lt;/code&amp;gt; to point to that in config.php.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And a BigBlueButton mock server is configured&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following step replicates receiving a callback from the BigBlueButton server indicating the recordings for meetings are ready for viewing.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And the BigBlueButtonBN server has sent recording ready notifications&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following steps are specific to the lesson activity. Note that in 4.0, some links (such as the &amp;quot;edit&amp;quot; and the &amp;quot;grade essays&amp;quot; links) are replaced by buttons, so you need to update your old steps with the new ones.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I edit the lesson&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;A new step is added to be used in lesson activities to edit them. This step navigates the user to the lesson edit page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I grade lesson essays&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;It&#039;s a new step to go to the &amp;quot;Grade essays&amp;quot; page of the lesson we are currently in.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I select edit type &amp;quot;edit type&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Select the lesson edit type when we are in the the lesson&#039;s edit page. &amp;quot;edit type&amp;quot; can either be &amp;quot;Collapsed&amp;quot; or &amp;quot;Expanded&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following new step can be used to navigate to the exports page in the course gradebook and select the specified export type from the grade exports navigation selector.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I navigate to &amp;quot;export option&amp;quot; export page in the course gradebook&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I navigate to &amp;quot;XML file&amp;quot; export page in the course gradebook&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Similarly, there&#039;s a new step to navigate to the imports page in the course gradebook and select the specified import type from the grade imports navigation selector.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I navigate to &amp;quot;import option&amp;quot; import page in the course gradebook&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Boost steps ===&lt;br /&gt;
In addition to the steps listed in the previous section, there are also some Boost specific steps coming with Moodle 4.0. These steps only work in Boost or Boost child themes, so you need to make sure they are not used in scenarios that may be run by non-Boost themes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following step checks whether a node is active in the secondary navigation.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I should see :name is active in secondary navigation&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Boost theme shows the language selector menu in the primary navigation when not logged in, and within the user menu when logged in. The following steps are to check if the primary navigation includes the language selector menu.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And language selector menu should exist in the navbar&lt;br /&gt;
And language selector menu should not exist in the navbar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And the following steps can be used to check whether an item exists in the language selector menu in the Boost theme.&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And &amp;quot;item text&amp;quot; &amp;quot;selector type&amp;quot; should exist in the language selector menu&lt;br /&gt;
And &amp;quot;item text&amp;quot; &amp;quot;selector type&amp;quot; should not exist in the language selector menu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;For example:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And &amp;quot;English &amp;amp;lrm;(en)&amp;amp;lrm;&amp;quot; &amp;quot;link&amp;quot; should exist in the language selector menu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Modified steps ===&lt;br /&gt;
The step &amp;lt;code&amp;gt;I change the (window|viewport) size to &amp;quot;size&amp;quot;&amp;lt;/code&amp;gt; now supports 2 new values for the size argument. The size argument now accepts &amp;lt;code&amp;gt;mobile&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;tablet&amp;lt;/code&amp;gt; values in addition to &amp;lt;code&amp;gt;small&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;medium&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;large&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Removed steps ===&lt;br /&gt;
Some behat steps are removed or replaced with new steps.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As a result of some design changes, hidden or restricted activities are no longer dimmed. Therefore the step&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And &amp;quot;Activity or resource name&amp;quot; activity should be dimmed&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;is now removed.&lt;br /&gt;
&lt;br /&gt;
Depending on what you were using that step for, you may be able to use these steps:&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And &amp;quot;Label name&amp;quot; label should be hidden&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And &amp;quot;Activity or resource name&amp;quot; activity should be hidden&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;gherkin&amp;quot;&amp;gt;&lt;br /&gt;
And I should see &amp;quot;Activity or resource name&amp;quot;&lt;br /&gt;
And &amp;quot;Activity or resource name&amp;quot; &amp;quot;link&amp;quot; should not exist in the &amp;quot;region-main&amp;quot; &amp;quot;region&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Other things to consider ===&lt;br /&gt;
To make behat tests more readable and easy to maintain, it is recommended to use the most direct steps to get what the test needs. It is highly recommended to use&lt;br /&gt;
 I am on the &amp;quot;Activity name&amp;quot; &amp;quot;[modname] activity&amp;quot; page &lt;br /&gt;
or&lt;br /&gt;
 I am on the &amp;quot;Activity name&amp;quot; &amp;quot;[modname] activity&amp;quot; page logged in as &amp;quot;user&amp;quot;&lt;br /&gt;
instead of navigating to the activity via&lt;br /&gt;
 I am on &amp;quot;Course&amp;quot; course homepage&lt;br /&gt;
 I follow &amp;quot;Activity name&amp;quot;&lt;br /&gt;
Now that [https://docs.moodle.org/dev/Prototypes#Course_creation_improvements Course index] is integrated these behat steps&lt;br /&gt;
 I am on &amp;quot;Course&amp;quot; course homepage&lt;br /&gt;
 I follow &amp;quot;Activity name&amp;quot;&lt;br /&gt;
will fail using Boost theme.&lt;br /&gt;
&lt;br /&gt;
The reason for it is that the drawer used in Boost is hiding the course index. So when the test is trying to follow an &amp;quot;Activity name&amp;quot; link, it finds two different links:&lt;br /&gt;
* one in the course index&lt;br /&gt;
* another one in the course main content.&lt;br /&gt;
But the first one, the one in the course index, is hidden by the drawer, and the test fails.&lt;br /&gt;
&lt;br /&gt;
However the recommended behat steps&lt;br /&gt;
 I am on the &amp;quot;Activity name&amp;quot; &amp;quot;[modname] activity&amp;quot; page &lt;br /&gt;
or&lt;br /&gt;
 I am on the &amp;quot;Activity name&amp;quot; &amp;quot;[modname] activity&amp;quot; page logged in as &amp;quot;user&amp;quot;&lt;br /&gt;
Old behat steps that may now fail can be updated to the new steps.&lt;br /&gt;
For example:&lt;br /&gt;
 And I am on the &amp;quot;Test assignment name&amp;quot; &amp;quot;assign activity&amp;quot; page logged in as teacher1&lt;br /&gt;
instead of:&lt;br /&gt;
 When I log in as &amp;quot;teacher1&amp;quot;&lt;br /&gt;
 And I am on &amp;quot;Course&amp;quot; course homepage&lt;br /&gt;
 And I follow &amp;quot;Test assignment name&amp;quot;&lt;br /&gt;
There are also similar stream-lined navigation steps for accessing question bank pages. See MDL-74130.&lt;br /&gt;
== Other ==&lt;br /&gt;
=== Core plugins review ===&lt;br /&gt;
A few plugins from core Moodle LMS which are no longer or hardly used have been removed and, if appropriate, added to the Moodle plugins directory.&lt;br /&gt;
&lt;br /&gt;
More information about this project, the list of plugins to be removed and the process to follow for keeping them before upgrading to 4.0 can be found in the [[Core plugins review]] page.&lt;br /&gt;
=== Site admin presets plugin ===&lt;br /&gt;
The third-party plugin [https://moodle.org/plugins/block_admin_presets Admin presets], created by David Monllaó and maintained by developers from [https://pimenko.com/ Pimenko] has been adapted and integrated into Moodle 4.0. It stores settings and plugins status (enabled/disabled) in what&#039;s called &amp;quot;presets&amp;quot; to let admins quickly switch between different configurations.&lt;br /&gt;
&lt;br /&gt;
More information about this project can be found in the [[Site admin presets|Site admin presets plugin]] page.&lt;br /&gt;
=== JavaScript browser support changes ===&lt;br /&gt;
From Moodle 4.0, Internet Explorer is no longer supported. See MDL-73915 and MDLSITE-6109 for further information on this change.&lt;br /&gt;
&lt;br /&gt;
This change means that changes built on 4.0 onwards (including the master branch) will be different to older versions of Moodle.&lt;br /&gt;
&lt;br /&gt;
For plugin developers supporting multiple versions of Moodle using a single plugin version, the compiled javascript files are backwards compatible and will _work_ on all supported versions, however if you run the `grunt` command on multiple versions you will see unbuilt changes. Running grunt on all versions of Moodle is not necessary and this check can be safely disabled for Moodle versions 3.9 - 4.0, as long as only at least you run `grunt` against at least one version of Moodle.&lt;br /&gt;
&lt;br /&gt;
If you need to support Internet Explorer and do not wish to fork your plugin for Moodle 4.0 onwards, then it is recommended that you run `grunt` on an older version of Moodle.&lt;br /&gt;
=== The course index element ===&lt;br /&gt;
The new course index feature can be themed using a set of scss variables. Use them to change the look and feel instead of adding custom css&lt;br /&gt;
 /theme/boost/scss/moodle/courseindex.scss&lt;br /&gt;
With the introduction of the course index component, the previous and next links shown underneath each activity are no longer needed and they will be removed.&lt;br /&gt;
=== Activity icons ===&lt;br /&gt;
The icons used for activities have been redesigned and updated for all core moodle activities.&lt;br /&gt;
&lt;br /&gt;
When viewing the new icons in a file manager, for example for the quiz activity, you will see a simple black monochrome icon with a transparent background.&lt;br /&gt;
&lt;br /&gt;
On the course page, or in the activity chooser, the icon will display as a white icon on a coloured background. Styling of the icons on the coursepage is controlled by the css in theme/boost/scss/moodle/icons.scss.&lt;br /&gt;
&lt;br /&gt;
The background colour for activity icons is set using a new variable in function [modname]_supports(). The quiz activity is of type assessment, so in function quiz_supports() there is a new line defining the purpose:&lt;br /&gt;
 case FEATURE_MOD_PURPOSE: return MOD_PURPOSE_ASSESSMENT;&lt;br /&gt;
Available purposes are:&lt;br /&gt;
* MOD_PURPOSE_COMMUNICATION&lt;br /&gt;
* MOD_PURPOSE_ASSESSMENT&lt;br /&gt;
* MOD_PURPOSE_COLLABORATION&lt;br /&gt;
* MOD_PURPOSE_CONTENT&lt;br /&gt;
* MOD_PURPOSE_ADMINISTRATION&lt;br /&gt;
* MOD_PURPOSE_INTERFACE&lt;br /&gt;
The background colours linked to these purposes are set in theme/boost/scss/moodle/variables.scss&lt;br /&gt;
 $activity-icon-colors: map-merge(&lt;br /&gt;
     (&lt;br /&gt;
         &amp;quot;administration&amp;quot;: #5d63f6,&lt;br /&gt;
         &amp;quot;assessment&amp;quot;: #eb66a2,&lt;br /&gt;
         &amp;quot;collaboration&amp;quot;: #f7634d,&lt;br /&gt;
         &amp;quot;communication&amp;quot;: #11a676,&lt;br /&gt;
         &amp;quot;content&amp;quot;: #399be2,&lt;br /&gt;
         &amp;quot;interface&amp;quot;: #a378ff&lt;br /&gt;
     ),&lt;br /&gt;
     $activity-icon-colors&lt;br /&gt;
 );&lt;br /&gt;
If activity plugins do not define FEATURE_MOD_PURPOSE the activity icon will be rendered against a light grey background. There is no requirement to define the purpose of activity plugins, it will only affect the icon styling.&lt;br /&gt;
&lt;br /&gt;
Plugins implementing the variable FEATURE_MOD_PURPOSE are only supported on Moodle 4.0 and newer.&lt;br /&gt;
&lt;br /&gt;
Customising the activity icon can be done in an alternative way. For example using the styles.css in mod/[pluginname/styles.css&lt;br /&gt;
&lt;br /&gt;
In the example below the activity plugin developer chooses to keep the coloured icon for the activity and render it as large as the coloured background on the core activities&lt;br /&gt;
 .modicon_subcourse.activityiconcontainer {&lt;br /&gt;
     background-color: transparent;&lt;br /&gt;
     padding: 0;&lt;br /&gt;
 }&lt;br /&gt;
  &lt;br /&gt;
 .modicon_subcourse.activityiconcontainer img {&lt;br /&gt;
     width: 50px;&lt;br /&gt;
     height: 50px;&lt;br /&gt;
 }&lt;br /&gt;
To customize all icon colours use this scss array and add it to the ‘Raw initial SCSS’ in the theme Boost advanced settings page. The complete array of icon background colours can be overridden using the ‘Raw initial SCSS’ in the theme settings page. The example below changes the colours of each activity type.&lt;br /&gt;
 $activity-icon-colors: (&lt;br /&gt;
     &amp;quot;administration&amp;quot;: #5D63F6,&lt;br /&gt;
     &amp;quot;assessment&amp;quot;: #11A676,&lt;br /&gt;
     &amp;quot;collaboration&amp;quot;: #EB66A2,&lt;br /&gt;
     &amp;quot;communication&amp;quot;: #F7634D,&lt;br /&gt;
     &amp;quot;content&amp;quot;: #399BE2,&lt;br /&gt;
     &amp;quot;interface&amp;quot;: #A378FF&lt;br /&gt;
 )&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60510</id>
		<title>Question bank</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60510"/>
		<updated>2021-07-27T09:19:02Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|Let&#039;s use this page as an intermediary one for the documentation of the Moodle 4.0 question bank features.}}&lt;br /&gt;
This feature allows a teacher to create, preview, and edit questions in a database of question categories. The categories can be limited to being used on the site, course or quiz level. The questions in a category can be added to a [[Quiz module|Quiz]] or to a [[Lesson module|lesson activity]] via an export process. The teacher enters the question bank by creating or editing a quiz activity or via &#039;&#039;Course administration &amp;gt; Question bank&#039;&#039;&lt;br /&gt;
==Select a category==&lt;br /&gt;
Questions are organised into categories. Initially each course has only one category called &amp;quot;Default&amp;quot;. It is good practice to create more categories to organize your questions. This not only makes it easier to find questions, but makes the use of random questions and matching question easier. You can create a hierarchy of categories because you can create subcategories inside parent categories. To add or edit categories click on the &amp;quot;[[Question categories|Categories]]&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
The question editing screen shows the questions from the currently selected category. You choose this category from the &#039;&#039;&#039;Category:&#039;&#039;&#039; drop-down menu. Using the tick box below that menu you determine whether to also show the questions from all subcategories.&lt;br /&gt;
&lt;br /&gt;
If a question is deleted when it is still being used by a quiz, then it is not removed from the database, because that would cause all sorts of problems. Instead it is just set to hidden. &#039;Also show old questions&#039; is for showing these hidden questions.&lt;br /&gt;
===Categories are shared in contexts===&lt;br /&gt;
There are separate question category trees in each different &#039;context&#039; in which questions are shared. The contexts available to you depend on whether you access the question bank from an activity or from a course and depend on the permissions assigned you for access to questions. See [[Question contexts]] for more information on these contexts.&lt;br /&gt;
==Add a new question==&lt;br /&gt;
# Click the &#039;&#039;Questions&#039;&#039; tab to access the Question Bank page, if not there already.&lt;br /&gt;
# From the &#039;&#039;&#039;Category&#039;&#039;&#039; drop-down menu, select a category you want to add a question to.&lt;br /&gt;
# The page will change to show the questions already in that category&lt;br /&gt;
# Select the question type you want to create from the &#039;&#039;&#039;Create new question&#039;&#039;&#039; drop-down menu.&lt;br /&gt;
# Fill in the form for the question type you are creating. Each [[Question types|question type]] has its own form and has its own options.&lt;br /&gt;
# Click &#039;&#039;Save Changes&#039;&#039; at the bottom of the form.&lt;br /&gt;
==Edit, duplicate, preview, delete, move and tag==&lt;br /&gt;
[[File:NewQuestionEditIcons1.png|link=Special:FilePath/NewQuestionEditIcons1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each question in the question bank has four icons which allow you to tag, edit, quickly duplicate, preview and delete the question. (The question may not be deleted if it is already in use elsewhere.) To duplicate a question, click the duplicate icon (second from the left) and a copy of the question editing screen will appear. You can either edit this new copy or simply scroll down and click &amp;quot;Save changes.&amp;quot;To move a question into a different category or subcategory, click into the box on its left; scroll down to &amp;quot;With Selected...&amp;quot; and choose &amp;quot;Move to..&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A new tag icon allows you to tag questions directly from the question bank. You can then search and filter by tagged questions.&lt;br /&gt;
&lt;br /&gt;
[[File:FilterByTag.png|link=Special:FilePath/FilterByTag.png]]&lt;br /&gt;
&lt;br /&gt;
==Question tags==&lt;br /&gt;
&lt;br /&gt;
==Question versions==&lt;br /&gt;
&lt;br /&gt;
==Question comments==&lt;br /&gt;
&lt;br /&gt;
==Question statistics==&lt;br /&gt;
&lt;br /&gt;
==Sharing and Managing Question banks==&lt;br /&gt;
&lt;br /&gt;
==Tips and tricks==&lt;br /&gt;
&lt;br /&gt;
*Put the answer into the question name so you can quickly see the answers when students are asking for answers. This is especially useful if you&#039;re dealing with large sets of questions! (No option yet for viewing category or answer of question in the list of questions.)&lt;br /&gt;
*Export questions in GIFT or Moodle XML formats, then import them into a Lesson. (Future versions of Moodle will make Question bank available to both Lesson and Quiz activities.)&lt;br /&gt;
*Remember that while some of the same question types can be found in both the Quiz and Lesson modules, they can be very different. Scoring and grading each student&#039;s choice is more robust in a Quiz. On the other hand, each Lesson question answer also has a [[Jumps|jump]] associated it.&lt;br /&gt;
*Use GIFT or other export modes to print questions and answers in a category. Hint, clever use of word processor macros, using search and replace, can tidy up a GIFT file for printing.&lt;br /&gt;
*The question title is useful in sorting and making notes. For example, &amp;quot;ZZ remove 2010-3 Why did the Moodler cross&amp;quot;, will put this question at the bottom of the list. Or where you want a &#039;the&#039; questions in a category to appear in a specific order, use letters or numbers, knowing that AA will come first, AB will be second in the list.&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60509</id>
		<title>Question bank</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60509"/>
		<updated>2021-07-27T09:18:25Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|Let&#039;s use this page as an intermediary one for the documentation of the Moodle 4.0 question bank features.}}&lt;br /&gt;
This feature allows a teacher to create, preview, and edit questions in a database of question categories. The categories can be limited to being used on the site, course or quiz level. The questions in a category can be added to a [[Quiz module|Quiz]] or to a [[Lesson module|lesson activity]] via an export process. The teacher enters the question bank by creating or editing a quiz activity or via &#039;&#039;Course administration &amp;gt; Question bank&#039;&#039;&lt;br /&gt;
==Select a category==&lt;br /&gt;
Questions are organised into categories. Initially each course has only one category called &amp;quot;Default&amp;quot;. It is good practice to create more categories to organize your questions. This not only makes it easier to find questions, but makes the use of random questions and matching question easier. You can create a hierarchy of categories because you can create subcategories inside parent categories. To add or edit categories click on the &amp;quot;[[Question categories|Categories]]&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
The question editing screen shows the questions from the currently selected category. You choose this category from the &#039;&#039;&#039;Category:&#039;&#039;&#039; drop-down menu. Using the tick box below that menu you determine whether to also show the questions from all subcategories.&lt;br /&gt;
&lt;br /&gt;
If a question is deleted when it is still being used by a quiz, then it is not removed from the database, because that would cause all sorts of problems. Instead it is just set to hidden. &#039;Also show old questions&#039; is for showing these hidden questions.&lt;br /&gt;
===Categories are shared in contexts===&lt;br /&gt;
There are separate question category trees in each different &#039;context&#039; in which questions are shared. The contexts available to you depend on whether you access the question bank from an activity or from a course and depend on the permissions assigned you for access to questions. See [[Question contexts]] for more information on these contexts.&lt;br /&gt;
==Add a new question==&lt;br /&gt;
# Click the &#039;&#039;Questions&#039;&#039; tab to access the Question Bank page, if not there already.&lt;br /&gt;
# From the &#039;&#039;&#039;Category&#039;&#039;&#039; drop-down menu, select a category you want to add a question to.&lt;br /&gt;
# The page will change to show the questions already in that category&lt;br /&gt;
# Select the question type you want to create from the &#039;&#039;&#039;Create new question&#039;&#039;&#039; drop-down menu.&lt;br /&gt;
# Fill in the form for the question type you are creating. Each [[Question types|question type]] has its own form and has its own options.&lt;br /&gt;
# Click &#039;&#039;Save Changes&#039;&#039; at the bottom of the form.&lt;br /&gt;
==Edit, duplicate, preview, delete, move and tag==&lt;br /&gt;
[[File:NewQuestionEditIcons1.png|link=Special:FilePath/NewQuestionEditIcons1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each question in the question bank has four icons which allow you to tag, edit, quickly duplicate, preview and delete the question. (The question may not be deleted if it is already in use elsewhere.) To duplicate a question, click the duplicate icon (second from the left) and a copy of the question editing screen will appear. You can either edit this new copy or simply scroll down and click &amp;quot;Save changes.&amp;quot;To move a question into a different category or subcategory, click into the box on its left; scroll down to &amp;quot;With Selected...&amp;quot; and choose &amp;quot;Move to..&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A new tag icon allows you to tag questions directly from the question bank. You can then search and filter by tagged questions.&lt;br /&gt;
&lt;br /&gt;
[[File:FilterByTag.png|link=Special:FilePath/FilterByTag.png]]&lt;br /&gt;
&lt;br /&gt;
==Question tags==&lt;br /&gt;
&lt;br /&gt;
==Question versions==&lt;br /&gt;
&lt;br /&gt;
==Question comments==&lt;br /&gt;
&lt;br /&gt;
==Question statistics==&lt;br /&gt;
&lt;br /&gt;
==Tips and tricks==&lt;br /&gt;
&lt;br /&gt;
==Sharing and Managing Question banks==&lt;br /&gt;
&lt;br /&gt;
*Put the answer into the question name so you can quickly see the answers when students are asking for answers. This is especially useful if you&#039;re dealing with large sets of questions! (No option yet for viewing category or answer of question in the list of questions.)&lt;br /&gt;
*Export questions in GIFT or Moodle XML formats, then import them into a Lesson. (Future versions of Moodle will make Question bank available to both Lesson and Quiz activities.)&lt;br /&gt;
*Remember that while some of the same question types can be found in both the Quiz and Lesson modules, they can be very different. Scoring and grading each student&#039;s choice is more robust in a Quiz. On the other hand, each Lesson question answer also has a [[Jumps|jump]] associated it.&lt;br /&gt;
*Use GIFT or other export modes to print questions and answers in a category. Hint, clever use of word processor macros, using search and replace, can tidy up a GIFT file for printing.&lt;br /&gt;
*The question title is useful in sorting and making notes. For example, &amp;quot;ZZ remove 2010-3 Why did the Moodler cross&amp;quot;, will put this question at the bottom of the list. Or where you want a &#039;the&#039; questions in a category to appear in a specific order, use letters or numbers, knowing that AA will come first, AB will be second in the list.&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60508</id>
		<title>Question bank</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60508"/>
		<updated>2021-07-27T09:17:40Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Sharing and Managing Question banks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|Let&#039;s use this page as an intermediary one for the documentation of the Moodle 4.0 question bank features.}}&lt;br /&gt;
This feature allows a teacher to create, preview, and edit questions in a database of question categories. The categories can be limited to being used on the site, course or quiz level. The questions in a category can be added to a [[Quiz module|Quiz]] or to a [[Lesson module|lesson activity]] via an export process. The teacher enters the question bank by creating or editing a quiz activity or via &#039;&#039;Course administration &amp;gt; Question bank&#039;&#039;&lt;br /&gt;
==Select a category==&lt;br /&gt;
Questions are organised into categories. Initially each course has only one category called &amp;quot;Default&amp;quot;. It is good practice to create more categories to organize your questions. This not only makes it easier to find questions, but makes the use of random questions and matching question easier. You can create a hierarchy of categories because you can create subcategories inside parent categories. To add or edit categories click on the &amp;quot;[[Question categories|Categories]]&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
The question editing screen shows the questions from the currently selected category. You choose this category from the &#039;&#039;&#039;Category:&#039;&#039;&#039; drop-down menu. Using the tick box below that menu you determine whether to also show the questions from all subcategories.&lt;br /&gt;
&lt;br /&gt;
If a question is deleted when it is still being used by a quiz, then it is not removed from the database, because that would cause all sorts of problems. Instead it is just set to hidden. &#039;Also show old questions&#039; is for showing these hidden questions.&lt;br /&gt;
===Categories are shared in contexts===&lt;br /&gt;
There are separate question category trees in each different &#039;context&#039; in which questions are shared. The contexts available to you depend on whether you access the question bank from an activity or from a course and depend on the permissions assigned you for access to questions. See [[Question contexts]] for more information on these contexts.&lt;br /&gt;
==Add a new question==&lt;br /&gt;
# Click the &#039;&#039;Questions&#039;&#039; tab to access the Question Bank page, if not there already.&lt;br /&gt;
# From the &#039;&#039;&#039;Category&#039;&#039;&#039; drop-down menu, select a category you want to add a question to.&lt;br /&gt;
# The page will change to show the questions already in that category&lt;br /&gt;
# Select the question type you want to create from the &#039;&#039;&#039;Create new question&#039;&#039;&#039; drop-down menu.&lt;br /&gt;
# Fill in the form for the question type you are creating. Each [[Question types|question type]] has its own form and has its own options.&lt;br /&gt;
# Click &#039;&#039;Save Changes&#039;&#039; at the bottom of the form.&lt;br /&gt;
==Edit, duplicate, preview, delete, move and tag==&lt;br /&gt;
[[File:NewQuestionEditIcons1.png|link=Special:FilePath/NewQuestionEditIcons1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each question in the question bank has four icons which allow you to tag, edit, quickly duplicate, preview and delete the question. (The question may not be deleted if it is already in use elsewhere.) To duplicate a question, click the duplicate icon (second from the left) and a copy of the question editing screen will appear. You can either edit this new copy or simply scroll down and click &amp;quot;Save changes.&amp;quot;To move a question into a different category or subcategory, click into the box on its left; scroll down to &amp;quot;With Selected...&amp;quot; and choose &amp;quot;Move to..&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A new tag icon allows you to tag questions directly from the question bank. You can then search and filter by tagged questions.&lt;br /&gt;
&lt;br /&gt;
[[File:FilterByTag.png|link=Special:FilePath/FilterByTag.png]]&lt;br /&gt;
==Question versions==&lt;br /&gt;
==Question comments==&lt;br /&gt;
==Tips and tricks==&lt;br /&gt;
*Put the answer into the question name so you can quickly see the answers when students are asking for answers. This is especially useful if you&#039;re dealing with large sets of questions! (No option yet for viewing category or answer of question in the list of questions.)&lt;br /&gt;
*Export questions in GIFT or Moodle XML formats, then import them into a Lesson. (Future versions of Moodle will make Question bank available to both Lesson and Quiz activities.)&lt;br /&gt;
*Remember that while some of the same question types can be found in both the Quiz and Lesson modules, they can be very different. Scoring and grading each student&#039;s choice is more robust in a Quiz. On the other hand, each Lesson question answer also has a [[Jumps|jump]] associated it.&lt;br /&gt;
*Use GIFT or other export modes to print questions and answers in a category. Hint, clever use of word processor macros, using search and replace, can tidy up a GIFT file for printing.&lt;br /&gt;
*The question title is useful in sorting and making notes. For example, &amp;quot;ZZ remove 2010-3 Why did the Moodler cross&amp;quot;, will put this question at the bottom of the list. Or where you want a &#039;the&#039; questions in a category to appear in a specific order, use letters or numbers, knowing that AA will come first, AB will be second in the list.&lt;br /&gt;
==Sharing and Managing Question banks==&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60507</id>
		<title>Question bank</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60507"/>
		<updated>2021-07-27T09:17:02Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Tips and tricks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|Let&#039;s use this page as an intermediary one for the documentation of the Moodle 4.0 question bank features.}}&lt;br /&gt;
This feature allows a teacher to create, preview, and edit questions in a database of question categories. The categories can be limited to being used on the site, course or quiz level. The questions in a category can be added to a [[Quiz module|Quiz]] or to a [[Lesson module|lesson activity]] via an export process. The teacher enters the question bank by creating or editing a quiz activity or via &#039;&#039;Course administration &amp;gt; Question bank&#039;&#039;&lt;br /&gt;
==Select a category==&lt;br /&gt;
Questions are organised into categories. Initially each course has only one category called &amp;quot;Default&amp;quot;. It is good practice to create more categories to organize your questions. This not only makes it easier to find questions, but makes the use of random questions and matching question easier. You can create a hierarchy of categories because you can create subcategories inside parent categories. To add or edit categories click on the &amp;quot;[[Question categories|Categories]]&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
The question editing screen shows the questions from the currently selected category. You choose this category from the &#039;&#039;&#039;Category:&#039;&#039;&#039; drop-down menu. Using the tick box below that menu you determine whether to also show the questions from all subcategories.&lt;br /&gt;
&lt;br /&gt;
If a question is deleted when it is still being used by a quiz, then it is not removed from the database, because that would cause all sorts of problems. Instead it is just set to hidden. &#039;Also show old questions&#039; is for showing these hidden questions.&lt;br /&gt;
===Categories are shared in contexts===&lt;br /&gt;
There are separate question category trees in each different &#039;context&#039; in which questions are shared. The contexts available to you depend on whether you access the question bank from an activity or from a course and depend on the permissions assigned you for access to questions. See [[Question contexts]] for more information on these contexts.&lt;br /&gt;
==Add a new question==&lt;br /&gt;
# Click the &#039;&#039;Questions&#039;&#039; tab to access the Question Bank page, if not there already.&lt;br /&gt;
# From the &#039;&#039;&#039;Category&#039;&#039;&#039; drop-down menu, select a category you want to add a question to.&lt;br /&gt;
# The page will change to show the questions already in that category&lt;br /&gt;
# Select the question type you want to create from the &#039;&#039;&#039;Create new question&#039;&#039;&#039; drop-down menu.&lt;br /&gt;
# Fill in the form for the question type you are creating. Each [[Question types|question type]] has its own form and has its own options.&lt;br /&gt;
# Click &#039;&#039;Save Changes&#039;&#039; at the bottom of the form.&lt;br /&gt;
==Edit, duplicate, preview, delete, move and tag==&lt;br /&gt;
[[File:NewQuestionEditIcons1.png|link=Special:FilePath/NewQuestionEditIcons1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each question in the question bank has four icons which allow you to tag, edit, quickly duplicate, preview and delete the question. (The question may not be deleted if it is already in use elsewhere.) To duplicate a question, click the duplicate icon (second from the left) and a copy of the question editing screen will appear. You can either edit this new copy or simply scroll down and click &amp;quot;Save changes.&amp;quot;To move a question into a different category or subcategory, click into the box on its left; scroll down to &amp;quot;With Selected...&amp;quot; and choose &amp;quot;Move to..&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A new tag icon allows you to tag questions directly from the question bank. You can then search and filter by tagged questions.&lt;br /&gt;
&lt;br /&gt;
[[File:FilterByTag.png|link=Special:FilePath/FilterByTag.png]]&lt;br /&gt;
==Question versions==&lt;br /&gt;
==Question comments==&lt;br /&gt;
==Tips and tricks==&lt;br /&gt;
*Put the answer into the question name so you can quickly see the answers when students are asking for answers. This is especially useful if you&#039;re dealing with large sets of questions! (No option yet for viewing category or answer of question in the list of questions.)&lt;br /&gt;
*Export questions in GIFT or Moodle XML formats, then import them into a Lesson. (Future versions of Moodle will make Question bank available to both Lesson and Quiz activities.)&lt;br /&gt;
*Remember that while some of the same question types can be found in both the Quiz and Lesson modules, they can be very different. Scoring and grading each student&#039;s choice is more robust in a Quiz. On the other hand, each Lesson question answer also has a [[Jumps|jump]] associated it.&lt;br /&gt;
*Use GIFT or other export modes to print questions and answers in a category. Hint, clever use of word processor macros, using search and replace, can tidy up a GIFT file for printing.&lt;br /&gt;
*The question title is useful in sorting and making notes. For example, &amp;quot;ZZ remove 2010-3 Why did the Moodler cross&amp;quot;, will put this question at the bottom of the list. Or where you want a &#039;the&#039; questions in a category to appear in a specific order, use letters or numbers, knowing that AA will come first, AB will be second in the list.&lt;br /&gt;
==Sharing and Managing Question banks==&lt;br /&gt;
Be default, teachers can manage only the questions in the context of the courses they are in. You can set up a role to allow teachers to share and manager questions on a larger scale. &lt;br /&gt;
&lt;br /&gt;
You can also use this role to create a special system-wide &amp;quot;Question bank Manager&amp;quot; instead of giving admin level or site-wide Manager access to a person managing the Questions.&lt;br /&gt;
&lt;br /&gt;
See:&lt;br /&gt;
*[[How to let teachers share questions between courses]]&lt;br /&gt;
*[[How to minimize the question bank when doing backup/restore]] &lt;br /&gt;
*Quiz Question Bank: Quiz level vs Course level - Forum Discussion: https://moodle.org/mod/forum/discuss.php?d=405646&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60506</id>
		<title>Question bank</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60506"/>
		<updated>2021-07-27T09:16:07Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|Let&#039;s use this page as an intermediary one for the documentation of the Moodle 4.0 question bank features.}}&lt;br /&gt;
&lt;br /&gt;
This feature allows a teacher to create, preview, and edit questions in a database of question categories. The categories can be limited to being used on the site, course or quiz level.  The questions in a category can be added to a [[Quiz module|Quiz]] or to a [[Lesson module|lesson activity]] via an export process. The teacher enters the question bank by creating or editing a quiz activity or via &#039;&#039;Course administration &amp;gt; Question bank&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Select a category==&lt;br /&gt;
Questions are organised into categories. Initially each course has only one category called &amp;quot;Default&amp;quot;. It is good practice to create more categories to organize your questions. This not only makes it easier to find questions, but makes the use of random questions and matching question easier. You can create a hierarchy of categories because you can create subcategories inside parent categories. To add or edit categories click on the &amp;quot;[[Question categories|Categories]]&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
The question editing screen shows the questions from the currently selected category. You choose this category from the &#039;&#039;&#039;Category:&#039;&#039;&#039; drop-down menu. Using the tick box below that menu you determine whether to also show the questions from all subcategories.&lt;br /&gt;
&lt;br /&gt;
If a question is deleted when it is still being used by a quiz, then it is not removed from the database, because that would cause all sorts of problems. Instead it is just set to hidden. &#039;Also show old questions&#039; is for showing these hidden questions.&lt;br /&gt;
&lt;br /&gt;
===Categories are shared in contexts===&lt;br /&gt;
&lt;br /&gt;
There are separate question category trees in each different &#039;context&#039; in which questions are shared. The contexts available to you depend on whether you access the question bank from an activity or from a course and depend on the permissions assigned you for access to questions. See [[Question contexts]] for more information on these contexts.&lt;br /&gt;
&lt;br /&gt;
==Add a new question==&lt;br /&gt;
# Click the &#039;&#039;Questions&#039;&#039; tab to access the Question Bank page, if not there already.&lt;br /&gt;
# From the &#039;&#039;&#039;Category&#039;&#039;&#039; drop-down menu, select a category you want to add a question to.&lt;br /&gt;
# The page will change to show the questions already in that category&lt;br /&gt;
# Select the question type you want to create from the &#039;&#039;&#039;Create new question&#039;&#039;&#039; drop-down menu.&lt;br /&gt;
# Fill in the form for the question type you are creating. Each [[Question types|question type]] has its own form and has its own options.&lt;br /&gt;
# Click &#039;&#039;Save Changes&#039;&#039; at the bottom of the form.&lt;br /&gt;
&lt;br /&gt;
==Edit, duplicate, preview, delete, move and tag==&lt;br /&gt;
[[File:NewQuestionEditIcons1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each question in the question bank has four icons which allow you to tag, edit, quickly duplicate, preview and delete the question. (The question may not be deleted if it is already in use elsewhere.)  To duplicate a question, click the duplicate icon (second from the left) and a copy of the question editing screen will appear. You can either edit this new copy or simply scroll down and click &amp;quot;Save changes.&amp;quot;To move a question into a different category or subcategory, click into the box on its left; scroll down to &amp;quot;With Selected...&amp;quot; and choose &amp;quot;Move to..&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A new tag icon allows you to tag questions directly from the question bank. You can then search and filter by tagged questions.&lt;br /&gt;
&lt;br /&gt;
[[File:FilterByTag.png]]&lt;br /&gt;
&lt;br /&gt;
==Question versions==&lt;br /&gt;
&lt;br /&gt;
==Question comments==&lt;br /&gt;
&lt;br /&gt;
==Tips and tricks==&lt;br /&gt;
*Put the answer into the question name so you can quickly see the answers when students are asking for answers. This is especially useful if you&#039;re dealing with large sets of questions! (No option yet for viewing category or answer of question in the list of questions.)&lt;br /&gt;
*Export questions in GIFT or Moodle XML formats, then import them into a Lesson. (Future versions of Moodle will make Question bank available to both Lesson and Quiz activities.)&lt;br /&gt;
*Remember that while some of the same question types can be found in both the Quiz and Lesson modules, they can be very different.  Scoring and grading each student&#039;s choice is more robust in a Quiz.  On the other hand, each Lesson question answer also has a [[Jumps|jump]] associated it.&lt;br /&gt;
*Use GIFT or other export modes to print questions and answers in a category.  Hint, clever use of word processor macros, using search and replace, can tidy up a GIFT file for printing.&lt;br /&gt;
*The question title is useful in sorting and making notes. For example, &amp;quot;ZZ remove 2010-3 Why did the Moodler cross&amp;quot;, will put this question at the bottom of the list.  Or where you want a &#039;the&#039; questions in a category to appear in a specific order, use letters or numbers, knowing that AA will come first, AB will be second in the list.&lt;br /&gt;
*Do a copy and paste from a PDF file into the question content area.  Reduces &amp;quot;other&amp;quot; hidden code which Word, Open Office and other programs can insert.&lt;br /&gt;
&lt;br /&gt;
==Sharing and Managing Question banks==&lt;br /&gt;
&lt;br /&gt;
Be default, teachers can manage only the questions in the context of the courses they are in. You can set up a role to allow teachers to share and manager questions on a larger scale. &lt;br /&gt;
&lt;br /&gt;
You can also use this role to create a special system-wide &amp;quot;Question bank Manager&amp;quot; instead of giving admin level or site-wide Manager access to a person managing the Questions.&lt;br /&gt;
&lt;br /&gt;
See:&lt;br /&gt;
&lt;br /&gt;
*[[How to let teachers share questions between courses]]&lt;br /&gt;
*[[How to minimize the question bank when doing backup/restore]] &lt;br /&gt;
*Quiz Question Bank: Quiz level vs Course level - Forum Discussion: https://moodle.org/mod/forum/discuss.php?d=405646&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60460</id>
		<title>Question bank</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60460"/>
		<updated>2021-07-20T08:22:41Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|Let&#039;s use this page as an intermediary one for the documentation of the Moodle 4.0 question bank features.}}&lt;br /&gt;
&lt;br /&gt;
This feature allows a teacher to create, preview, and edit questions in a database of question categories. The categories can be limited to being used on the site, course or quiz level.  The questions in a category can be added to a [[Quiz module|Quiz]] or to a [[Lesson module|lesson activity]] via an export process. The teacher enters the question bank by creating or editing a quiz activity or via &#039;&#039;Course administration &amp;gt; Question bank&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Select a category==&lt;br /&gt;
Questions are organised into categories. Initially each course has only one category called &amp;quot;Default&amp;quot;. It is good practice to create more categories to organize your questions. This not only makes it easier to find questions, but makes the use of random questions and matching question easier. You can create a hierarchy of categories because you can create subcategories inside parent categories. To add or edit categories click on the &amp;quot;[[Question categories|Categories]]&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
The question editing screen shows the questions from the currently selected category. You choose this category from the &#039;&#039;&#039;Category:&#039;&#039;&#039; drop-down menu. Using the tick box below that menu you determine whether to also show the questions from all subcategories.&lt;br /&gt;
&lt;br /&gt;
If a question is deleted when it is still being used by a quiz, then it is not removed from the database, because that would cause all sorts of problems. Instead it is just set to hidden. &#039;Also show old questions&#039; is for showing these hidden questions.&lt;br /&gt;
&lt;br /&gt;
===Categories are shared in contexts===&lt;br /&gt;
&lt;br /&gt;
There are separate question category trees in each different &#039;context&#039; in which questions are shared. The contexts available to you depend on whether you access the question bank from an activity or from a course and depend on the permissions assigned you for access to questions. See [[Question contexts]] for more information on these contexts.&lt;br /&gt;
&lt;br /&gt;
==Add a new question==&lt;br /&gt;
# Click the &#039;&#039;Questions&#039;&#039; tab to access the Question Bank page, if not there already.&lt;br /&gt;
# From the &#039;&#039;&#039;Category&#039;&#039;&#039; drop-down menu, select a category you want to add a question to.&lt;br /&gt;
# The page will change to show the questions already in that category&lt;br /&gt;
# Select the question type you want to create from the &#039;&#039;&#039;Create new question&#039;&#039;&#039; drop-down menu.&lt;br /&gt;
# Fill in the form for the question type you are creating. Each [[Question types|question type]] has its own form and has its own options.&lt;br /&gt;
# Click &#039;&#039;Save Changes&#039;&#039; at the bottom of the form.&lt;br /&gt;
&lt;br /&gt;
==Edit, duplicate, preview, delete, move and tag==&lt;br /&gt;
[[File:NewQuestionEditIcons1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each question in the question bank has four icons which allow you to tag, edit, quickly duplicate, preview and delete the question. (The question may not be deleted if it is already in use elsewhere.)  To duplicate a question, click the duplicate icon (second from the left) and a copy of the question editing screen will appear. You can either edit this new copy or simply scroll down and click &amp;quot;Save changes.&amp;quot;To move a question into a different category or subcategory, click into the box on its left; scroll down to &amp;quot;With Selected...&amp;quot; and choose &amp;quot;Move to..&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A new tag icon allows you to tag questions directly from the question bank. You can then search and filter by tagged questions.&lt;br /&gt;
&lt;br /&gt;
[[File:FilterByTag.png]]&lt;br /&gt;
&lt;br /&gt;
==Tips and tricks==&lt;br /&gt;
*Put the answer into the question name so you can quickly see the answers when students are asking for answers. This is especially useful if you&#039;re dealing with large sets of questions! (No option yet for viewing category or answer of question in the list of questions.)&lt;br /&gt;
*Export questions in GIFT or Moodle XML formats, then import them into a Lesson. (Future versions of Moodle will make Question bank available to both Lesson and Quiz activities.)&lt;br /&gt;
*Remember that while some of the same question types can be found in both the Quiz and Lesson modules, they can be very different.  Scoring and grading each student&#039;s choice is more robust in a Quiz.  On the other hand, each Lesson question answer also has a [[Jumps|jump]] associated it.&lt;br /&gt;
*Use GIFT or other export modes to print questions and answers in a category.  Hint, clever use of word processor macros, using search and replace, can tidy up a GIFT file for printing.&lt;br /&gt;
*The question title is useful in sorting and making notes. For example, &amp;quot;ZZ remove 2010-3 Why did the Moodler cross&amp;quot;, will put this question at the bottom of the list.  Or where you want a &#039;the&#039; questions in a category to appear in a specific order, use letters or numbers, knowing that AA will come first, AB will be second in the list.&lt;br /&gt;
*Do a copy and paste from a PDF file into the question content area.  Reduces &amp;quot;other&amp;quot; hidden code which Word, Open Office and other programs can insert.&lt;br /&gt;
&lt;br /&gt;
==Sharing and Managing Question banks==&lt;br /&gt;
&lt;br /&gt;
Be default, teachers can manage only the questions in the context of the courses they are in. You can set up a role to allow teachers to share and manager questions on a larger scale. &lt;br /&gt;
&lt;br /&gt;
You can also use this role to create a special system-wide &amp;quot;Question bank Manager&amp;quot; instead of giving admin level or site-wide Manager access to a person managing the Questions.&lt;br /&gt;
&lt;br /&gt;
See:&lt;br /&gt;
&lt;br /&gt;
*[[How to let teachers share questions between courses]]&lt;br /&gt;
*[[How to minimize the question bank when doing backup/restore]] &lt;br /&gt;
*Quiz Question Bank: Quiz level vs Course level - Forum Discussion: https://moodle.org/mod/forum/discuss.php?d=405646&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60459</id>
		<title>Question bank</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank&amp;diff=60459"/>
		<updated>2021-07-20T08:19:01Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Note|Let&#039;s use this page as an intermediary one for the documentation of the Moodle 4.0 question bank features.}}&lt;br /&gt;
&lt;br /&gt;
{{Managing questions}}&lt;br /&gt;
This feature allows a teacher to create, preview, and edit questions in a database of question categories. The categories can be limited to being used on the site, course or quiz level.  The questions in a category can be added to a [[Quiz module|Quiz]] or to a [[Lesson module|lesson activity]] via an export process. The teacher enters the question bank by creating or editing a quiz activity or via &#039;&#039;Course administration &amp;gt; Question bank&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Select a category==&lt;br /&gt;
Questions are organised into categories. Initially each course has only one category called &amp;quot;Default&amp;quot;. It is good practice to create more categories to organize your questions. This not only makes it easier to find questions, but makes the use of random questions and matching question easier. You can create a hierarchy of categories because you can create subcategories inside parent categories. To add or edit categories click on the &amp;quot;[[Question categories|Categories]]&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
The question editing screen shows the questions from the currently selected category. You choose this category from the &#039;&#039;&#039;Category:&#039;&#039;&#039; drop-down menu. Using the tick box below that menu you determine whether to also show the questions from all subcategories.&lt;br /&gt;
&lt;br /&gt;
If a question is deleted when it is still being used by a quiz, then it is not removed from the database, because that would cause all sorts of problems. Instead it is just set to hidden. &#039;Also show old questions&#039; is for showing these hidden questions.&lt;br /&gt;
&lt;br /&gt;
===Categories are shared in contexts===&lt;br /&gt;
&lt;br /&gt;
There are separate question category trees in each different &#039;context&#039; in which questions are shared. The contexts available to you depend on whether you access the question bank from an activity or from a course and depend on the permissions assigned you for access to questions. See [[Question contexts]] for more information on these contexts.&lt;br /&gt;
&lt;br /&gt;
==Add a new question==&lt;br /&gt;
# Click the &#039;&#039;Questions&#039;&#039; tab to access the Question Bank page, if not there already.&lt;br /&gt;
# From the &#039;&#039;&#039;Category&#039;&#039;&#039; drop-down menu, select a category you want to add a question to.&lt;br /&gt;
# The page will change to show the questions already in that category&lt;br /&gt;
# Select the question type you want to create from the &#039;&#039;&#039;Create new question&#039;&#039;&#039; drop-down menu.&lt;br /&gt;
# Fill in the form for the question type you are creating. Each [[Question types|question type]] has its own form and has its own options.&lt;br /&gt;
# Click &#039;&#039;Save Changes&#039;&#039; at the bottom of the form.&lt;br /&gt;
&lt;br /&gt;
==Edit, duplicate, preview, delete, move and tag==&lt;br /&gt;
[[File:NewQuestionEditIcons1.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each question in the question bank has four icons which allow you to tag, edit, quickly duplicate, preview and delete the question. (The question may not be deleted if it is already in use elsewhere.)  To duplicate a question, click the duplicate icon (second from the left) and a copy of the question editing screen will appear. You can either edit this new copy or simply scroll down and click &amp;quot;Save changes.&amp;quot;To move a question into a different category or subcategory, click into the box on its left; scroll down to &amp;quot;With Selected...&amp;quot; and choose &amp;quot;Move to..&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A new tag icon allows you to tag questions directly from the question bank. You can then search and filter by tagged questions.&lt;br /&gt;
&lt;br /&gt;
[[File:FilterByTag.png]]&lt;br /&gt;
&lt;br /&gt;
==Tips and tricks==&lt;br /&gt;
*Put the answer into the question name so you can quickly see the answers when students are asking for answers. This is especially useful if you&#039;re dealing with large sets of questions! (No option yet for viewing category or answer of question in the list of questions.)&lt;br /&gt;
*Export questions in GIFT or Moodle XML formats, then import them into a Lesson. (Future versions of Moodle will make Question bank available to both Lesson and Quiz activities.)&lt;br /&gt;
*Remember that while some of the same question types can be found in both the Quiz and Lesson modules, they can be very different.  Scoring and grading each student&#039;s choice is more robust in a Quiz.  On the other hand, each Lesson question answer also has a [[Jumps|jump]] associated it.&lt;br /&gt;
*Use GIFT or other export modes to print questions and answers in a category.  Hint, clever use of word processor macros, using search and replace, can tidy up a GIFT file for printing.&lt;br /&gt;
*The question title is useful in sorting and making notes. For example, &amp;quot;ZZ remove 2010-3 Why did the Moodler cross&amp;quot;, will put this question at the bottom of the list.  Or where you want a &#039;the&#039; questions in a category to appear in a specific order, use letters or numbers, knowing that AA will come first, AB will be second in the list.&lt;br /&gt;
*Do a copy and paste from a PDF file into the question content area.  Reduces &amp;quot;other&amp;quot; hidden code which Word, Open Office and other programs can insert.&lt;br /&gt;
&lt;br /&gt;
==Sharing and Managing Question banks==&lt;br /&gt;
&lt;br /&gt;
Be default, teachers can manage only the questions in the context of the courses they are in. You can set up a role to allow teachers to share and manager questions on a larger scale. &lt;br /&gt;
&lt;br /&gt;
You can also use this role to create a special system-wide &amp;quot;Question bank Manager&amp;quot; instead of giving admin level or site-wide Manager access to a person managing the Questions.&lt;br /&gt;
&lt;br /&gt;
See:&lt;br /&gt;
&lt;br /&gt;
*[[How to let teachers share questions between courses]]&lt;br /&gt;
*[[How to minimize the question bank when doing backup/restore]] &lt;br /&gt;
*Quiz Question Bank: Quiz level vs Course level - Forum Discussion: https://moodle.org/mod/forum/discuss.php?d=405646&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Moodle_App_Remote_Themes_Upgrade_Guide&amp;diff=59022</id>
		<title>Talk:Moodle App Remote Themes Upgrade Guide</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Moodle_App_Remote_Themes_Upgrade_Guide&amp;diff=59022"/>
		<updated>2021-06-29T12:04:05Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Thanks for that great guide.&lt;br /&gt;
&lt;br /&gt;
Finally, I do struggle on how to implement at the end. Because to use it with Chromium something like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* 3.9.5 ionic styles */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
  --core-header-toolbar-background: #64788b;&lt;br /&gt;
  --core-header-toolbar-border-color: #64788b;&lt;br /&gt;
  --core-header-toolbar-color: #fff;&lt;br /&gt;
  --core-bottom-tabs-background: #64788b;&lt;br /&gt;
  --core-bottom-tabs-color: #eff1f3;&lt;br /&gt;
  --core-bottom-tabs-color-selected: #fac301;&lt;br /&gt;
  --drop-shadow: 0, 0, 0, 0.00;&lt;br /&gt;
  --brand-color: #fac301;&lt;br /&gt;
  --color: #fac301;&lt;br /&gt;
  --loading-text-color: #fac301;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
works perfectly well.&lt;br /&gt;
&lt;br /&gt;
But is that the form it can be shipped in a custom css file?&lt;br /&gt;
A minimal simple enough sample css file would be much appreciated.&lt;br /&gt;
Thanks!&lt;br /&gt;
&lt;br /&gt;
[[User:Luca Bösch|Luca Bösch]] ([[User talk:Luca Bösch|talk]]) 10:55, 29 June 2021 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I added a Full example at the end of the page, :root is ok but if you feel more comfortable, you can use body.ionic5 instead.&lt;br /&gt;
&lt;br /&gt;
Thanks heaps, Pau!&lt;br /&gt;
In our site it is productive but for some reason it does not propagate to the beta Moodle 3.9.5 (3.9.5.0) iOS version, but that might just be temporary.&lt;br /&gt;
We have the Premium subscription plan, the &amp;quot;Basic branding&amp;quot; colors are coming through, but the rest of the style is not. I did incrase a #2 at the end of the css URL in order to &#039;count up&#039;.&lt;br /&gt;
&lt;br /&gt;
[[User:Luca Bösch|Luca Bösch]] ([[User talk:Luca Bösch|talk]]) 12:04, 29 June 2021 (UTC)&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Moodle_App_Remote_Themes_Upgrade_Guide&amp;diff=59016</id>
		<title>Talk:Moodle App Remote Themes Upgrade Guide</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Moodle_App_Remote_Themes_Upgrade_Guide&amp;diff=59016"/>
		<updated>2021-06-29T10:55:23Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Thanks for that great guide.&lt;br /&gt;
&lt;br /&gt;
Finally, I do struggle on how to implement at the end. Because to use it with Chromium something like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
/* 3.9.5 ionic styles */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
  --core-header-toolbar-background: #64788b;&lt;br /&gt;
  --core-header-toolbar-border-color: #64788b;&lt;br /&gt;
  --core-header-toolbar-color: #fff;&lt;br /&gt;
  --core-bottom-tabs-background: #64788b;&lt;br /&gt;
  --core-bottom-tabs-color: #eff1f3;&lt;br /&gt;
  --core-bottom-tabs-color-selected: #fac301;&lt;br /&gt;
  --drop-shadow: 0, 0, 0, 0.00;&lt;br /&gt;
  --brand-color: #fac301;&lt;br /&gt;
  --color: #fac301;&lt;br /&gt;
  --loading-text-color: #fac301;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
works perfectly well.&lt;br /&gt;
&lt;br /&gt;
But is that the form it can be shipped in a custom css file?&lt;br /&gt;
A minimal simple enough sample css file would be much appreciated.&lt;br /&gt;
Thanks!&lt;br /&gt;
&lt;br /&gt;
[[User:Luca Bösch|Luca Bösch]] ([[User talk:Luca Bösch|talk]]) 10:55, 29 June 2021 (UTC)&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Moodle_App_Remote_Themes_Upgrade_Guide&amp;diff=59015</id>
		<title>Talk:Moodle App Remote Themes Upgrade Guide</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Moodle_App_Remote_Themes_Upgrade_Guide&amp;diff=59015"/>
		<updated>2021-06-29T10:55:08Z</updated>

		<summary type="html">&lt;p&gt;Finns: Created page with &amp;quot;Thanks for that great guide.  Finally, I do struggle on how to implement at the end. Because to use it with Chromium something like  /* 3.9.5 ionic styles */  &amp;lt;code css&amp;gt; :root...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Thanks for that great guide.&lt;br /&gt;
&lt;br /&gt;
Finally, I do struggle on how to implement at the end. Because to use it with Chromium something like&lt;br /&gt;
&lt;br /&gt;
/* 3.9.5 ionic styles */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code css&amp;gt;&lt;br /&gt;
:root {&lt;br /&gt;
  --core-header-toolbar-background: #64788b;&lt;br /&gt;
  --core-header-toolbar-border-color: #64788b;&lt;br /&gt;
  --core-header-toolbar-color: #fff;&lt;br /&gt;
  --core-bottom-tabs-background: #64788b;&lt;br /&gt;
  --core-bottom-tabs-color: #eff1f3;&lt;br /&gt;
  --core-bottom-tabs-color-selected: #fac301;&lt;br /&gt;
  --drop-shadow: 0, 0, 0, 0.00;&lt;br /&gt;
  --brand-color: #fac301;&lt;br /&gt;
  --color: #fac301;&lt;br /&gt;
  --loading-text-color: #fac301;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
works perfectly well.&lt;br /&gt;
&lt;br /&gt;
But is that the form it can be shipped in a custom css file?&lt;br /&gt;
A minimal simple enough sample css file would be much appreciated.&lt;br /&gt;
Thanks!&lt;br /&gt;
&lt;br /&gt;
[[User:Luca Bösch|Luca Bösch]] ([[User talk:Luca Bösch|talk]]) 10:55, 29 June 2021 (UTC)&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=59000</id>
		<title>Question bank improvements for Moodle 4.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=59000"/>
		<updated>2021-06-25T10:28:02Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Contributors (financially) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.0&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-70329&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=417599&lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]], Antonia Bonaccorso. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle_4.0}}&lt;br /&gt;
&lt;br /&gt;
This is a project to largely re-develop the question bank for Moodle 4.0 (if possible). The aim is to&lt;br /&gt;
&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
&lt;br /&gt;
== Technical overview of the plans ==&lt;br /&gt;
&lt;br /&gt;
What we are planning to do is outlined in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread]. That thread is quite long, with discussion of the plan, but the key posts which describe the plan are:&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1682674 Setting the scope]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683127 Question bank will be made up of plugins]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1687624 List of the plugins that will be created initially]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1683186 Question bank will store the version history of each question]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1688163 How the question bank will track the places (quizzes) where questions are used]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1685143 Some initial UI wireframes]&lt;br /&gt;
* [https://moodle.org/mod/forum/discuss.php?d=417599#p1705076 Question (and following discussion) about how complicated the filtering/searching system needs to be at first]&lt;br /&gt;
&lt;br /&gt;
== Project support ==&lt;br /&gt;
&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* RWTH Aachen University, Germany&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project ===&lt;br /&gt;
These institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=58946</id>
		<title>Question bank improvements for Moodle 4.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=58946"/>
		<updated>2021-06-04T15:09:07Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Contributors (financially) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.0&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-70329&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=417599&lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]], Antonia Bonaccorso. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle_4.0}}&lt;br /&gt;
&lt;br /&gt;
This is a project to largely re-develop the question bank for Moodle 4.0 (if possible). The aim is to&lt;br /&gt;
&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
&lt;br /&gt;
The project has been explained in detail in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread], so for more details, please read that.&lt;br /&gt;
&lt;br /&gt;
== Project support ==&lt;br /&gt;
&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Office for Middle and vocational schools, Switzerland&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project ===&lt;br /&gt;
This institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=58828</id>
		<title>Question bank improvements for Moodle 4.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=58828"/>
		<updated>2021-05-18T13:35:41Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.0&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-70329&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=417599&lt;br /&gt;
|assignee = Project instigated by [[User:Thomas_Korner|Thomas Korner]], [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]], Antonia Bonaccorso. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle_4.0}}&lt;br /&gt;
&lt;br /&gt;
This is a project to largely re-develop the question bank for Moodle 4.0 (if possible). The aim is to&lt;br /&gt;
&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
&lt;br /&gt;
The project has been explained in detail in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread], so for more details, please read that.&lt;br /&gt;
&lt;br /&gt;
== Project support ==&lt;br /&gt;
&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Canton of Zurich Middle Schools and Vocational Training Office, Switzerland&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* ETH (Swiss Federal Institute of Technology) Zurich, Department of Medicine, Switzerland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project ===&lt;br /&gt;
This institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Process&amp;diff=58627</id>
		<title>Process</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Process&amp;diff=58627"/>
		<updated>2021-04-05T21:46:47Z</updated>

		<summary type="html">&lt;p&gt;Finns: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This document summarises the various development processes used in developing Moodle.  There are four main processes that overlap.&lt;br /&gt;
&lt;br /&gt;
==Integration workflow in the tracker==&lt;br /&gt;
&lt;br /&gt;
The Moodle tracker keeps track of the status of all bug fixes and new features. &lt;br /&gt;
&lt;br /&gt;
We use a workflow that ensures that new code receives multiple reviews by different people before it is included into the core Moodle code.&lt;br /&gt;
&lt;br /&gt;
[[Image:Workflow.jpg]]&lt;br /&gt;
&lt;br /&gt;
A number of roles make this work:&lt;br /&gt;
&lt;br /&gt;
===Users===&lt;br /&gt;
&lt;br /&gt;
Users report bugs and make feature requests directly in the tracker, by creating new issues with a summary and a description.&lt;br /&gt;
&lt;br /&gt;
===Developers===&lt;br /&gt;
&lt;br /&gt;
Developers work on the issues in the tracker to specify solutions and write code that implements these solutions.  They will often ask other developers to &amp;quot;peer review&amp;quot; their code in the early stages to avoid problems later on.&lt;br /&gt;
&lt;br /&gt;
While many of the developers work for Moodle.com, a large number are part of the global development community around Moodle. If you&#039;re interested in becoming a recognised developer, see [[Tracker_guide#Tracker_groups_and_permissions|Tracker groups and permissions]].&lt;br /&gt;
&lt;br /&gt;
===CiBoT===&lt;br /&gt;
&lt;br /&gt;
CiBoT is not a person but a bot who monitors the tracker and performs the [[Automated code review]] when issue is submitted for Peer review or when developer added &#039;&#039;cime&#039;&#039; label.&lt;br /&gt;
&lt;br /&gt;
===Component leads===&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/projects/MDL?selectedItem=com.atlassian.jira.jira-projects-plugin:components-page Component leads] are developers with some responsibility for particular components (plugins or modules) in Moodle.  They have authority to decide that a particular fix is suitable and complete enough to be considered for integration in Moodle core and should be called upon to complete peer reviews for code in their components. Note that, apart from that, every component also has some [[Component Leads|HQ Component leads]] that will specifically work on associated issues, triaging, monitoring, reviewing, fixing them.&lt;br /&gt;
&lt;br /&gt;
===Integrators===&lt;br /&gt;
&lt;br /&gt;
On Monday and Tuesday of each week, the integration team (a small team of senior developers employed by Moodle HQ) conducts a code-level review of all issues in the integration queue.  This is often called the &amp;quot;pull&amp;quot; process.  If the fix is judged appropriate they will integrate the code into our git integration repository for further testing and it gets added to the testing queue.&lt;br /&gt;
&lt;br /&gt;
If they find problems they reject the issue and send it back to the developer for further work.&lt;br /&gt;
&lt;br /&gt;
===Testers===&lt;br /&gt;
&lt;br /&gt;
On Wednesday each week, testers look at all the issues in the testing queue, trying each fix and feature to make sure that it does actually fix the problem it was supposed to, and that there are no regressions in the web version and the Moodle mobile app.&lt;br /&gt;
&lt;br /&gt;
If they find problems they reject the issue and integrators may remove it from the integration repository and push it back to the developer for further work.&lt;br /&gt;
&lt;br /&gt;
See [[Testing of integrated issues]] for more details.&lt;br /&gt;
&lt;br /&gt;
===Production maintainers===&lt;br /&gt;
&lt;br /&gt;
On Thursday each week, production maintainers merge all the issues that passed testing into the git production repository, and it becomes available for use on production systems via git and download packages.&lt;br /&gt;
&lt;br /&gt;
==Stable maintenance cycles==&lt;br /&gt;
&lt;br /&gt;
Moodle releases regular updates of the stable version of the software to fix bugs and other issues.  Releases like 2.2.1, 2.2.2, 2.2.3 etc only include fixes based on the latest major release (2.2) and never any significant new features or database changes.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ there are teams of developers using the [http://www.scrum.org/ Scrum framework] to work on these issues (as well as new features for [[#Major_release_cycles|major releases]]). &lt;br /&gt;
&lt;br /&gt;
===Minor release (point release) timing===&lt;br /&gt;
&lt;br /&gt;
After [[#Major_release_cycles|major releases]] there will be minor releases.&lt;br /&gt;
* x.x.1 will occur approximately two months after each major release (eg. 2.x).&lt;br /&gt;
* There will then be another point release every two months after that.&lt;br /&gt;
&lt;br /&gt;
See the [[Releases#General_release_calendar|General release calendar]] for details.&lt;br /&gt;
&lt;br /&gt;
===Issue triage===&lt;br /&gt;
&lt;br /&gt;
[[Bug_triage|Issue triage]] involves evaluating new issues, making sure that they are recorded correctly.  One of the most important jobs triagers do is to identify issues that should be fixed in the stable branch. These are set with a priority ranging from &amp;quot;Trivial&amp;quot; up to &amp;quot;Blocker&amp;quot; and other features are checked.&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ there are currently teams working on stable issues (mostly bugs reported by users) and improvements and new features (Partners, Moodle Association, user suggestions and Martin Dougiamas).&lt;br /&gt;
&lt;br /&gt;
===Scrum===&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ, every three weeks, the stable team takes a number of the most urgent issues from the backlog to work on during a period known as a &#039;&#039;sprint&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
At the start of a sprint there is a period of planning and estimation. All issues on the backlog are given a relative rank that is based on issue features including priority, security, Partner interest, patches and votes. Issues are given a relative size in Story Points and these points are summed to allow the teams to determine how many issues they can work on in the sprint.&lt;br /&gt;
&lt;br /&gt;
During the sprint, the team meets daily to discuss solutions and progress, as well as to organise testing and peer reviews of code.  The team has a &#039;&#039;Scrum master&#039;&#039; to help everyone stay organised, to &amp;quot;unblock&amp;quot; any barriers to progress and to protect the team from distracting influences (mostly people attempting to add to the developers&#039; workloads) during the sprint.  The teams&#039; work is documented publicly in the tracker.&lt;br /&gt;
&lt;br /&gt;
Whenever a solution for an issue is finished, it is submitted to the standard integration workflow process described above.&lt;br /&gt;
&lt;br /&gt;
==Major release cycles==&lt;br /&gt;
&lt;br /&gt;
Since Moodle 2.0, we have a policy of release major versions (eg 2.1, 2.2) every six months in May and November. See the [[Releases#General_release_calendar|General release calendar]] for more details.&lt;br /&gt;
&lt;br /&gt;
Each release can be different, but generally the cycles work as follows.&lt;br /&gt;
&lt;br /&gt;
===Define roadmap===&lt;br /&gt;
&lt;br /&gt;
The product owner (Martin Dougiamas) defines the likely roadmap based on community wishes, third-party developments and important issues within the existing code. &lt;br /&gt;
&lt;br /&gt;
Sometimes new features might be based on earlier features, sometimes they may be something developed by a third party that needs to be evaluated and sometimes it might be something completely new.&lt;br /&gt;
&lt;br /&gt;
===Planning and development===&lt;br /&gt;
&lt;br /&gt;
The UX team, employed at Moodle HQ, work on specifications of major new features throughout the cycle, specifying project ahead of development time.&lt;br /&gt;
&lt;br /&gt;
New features are worked on by the &amp;quot;Dev&amp;quot; team. The process of [[#New_feature_development|new feature development]] is described below. When specifications are in place, new code is developed during sprints and goes through the standard weekly integration workflow described above.&lt;br /&gt;
&lt;br /&gt;
===Testing===&lt;br /&gt;
&lt;br /&gt;
During development, as new code is integrated, automated testing conducted at the [[PHPUnit|code]] and [[Acceptance_testing|interface]] levels, to make sure there are no regressions caused by new features.&lt;br /&gt;
&lt;br /&gt;
In the last month before the release, a feature freeze is called (no new features can be added) and volunteer testers from the Moodle community perform manual QA testing of Moodle features. The current set of functional tests is listed in MDLQA-1. The list of tests is extended as new features are added, though we&#039;re also trying to reduce the number as more automated [[Acceptance_testing|acceptance tests]] are developed.&lt;br /&gt;
&lt;br /&gt;
There is also a set of tests for manually testing any major theme changes - MDLQA-11592.&lt;br /&gt;
&lt;br /&gt;
For more details, see [[Testing]].&lt;br /&gt;
&lt;br /&gt;
===Sprints===&lt;br /&gt;
&lt;br /&gt;
At Moodle HQ, development takes place in sprints. The sprints are three-week periods during which developers to focus on a fixed list of issues. Sprints are arranged within each release cycle as shown in the diagram below.&lt;br /&gt;
&lt;br /&gt;
===Events during cycle===&lt;br /&gt;
&lt;br /&gt;
During each cycle there are a periods and events that occur between and around sprints.&lt;br /&gt;
&lt;br /&gt;
[[Image:Dev sprint calendar.png|800px]]&lt;br /&gt;
&lt;br /&gt;
; &#039;&#039;&#039;Planning and bug fixing&#039;&#039;&#039;&lt;br /&gt;
: A period during which the Roadmap is explored, specs are written and prototypes are created. Regressions in the recent release are fixed as they arise.&lt;br /&gt;
; &#039;&#039;&#039;End sync period&#039;&#039;&#039;&lt;br /&gt;
: During the [[Integration Review#On-sync period|on-sync period]], the recent release and master versions are kept synchronised. No new code is added during this period, which ensures regressions are fixed rapidly. This also allows for planning and provides relief for developers after a release.&lt;br /&gt;
; &#039;&#039;&#039;Personal projects&#039;&#039;&#039;&lt;br /&gt;
: Affecting full-time HQ developers only, this period allows for individual creations to be explored and provides a break from sprints.&lt;br /&gt;
; &#039;&#039;&#039;Code freeze&#039;&#039;&#039;&lt;br /&gt;
: A point after which no new code (only fixes to existing code) is accepted until beyond the release. This stabilisation allows for QA testing.&lt;br /&gt;
; &#039;&#039;&#039;QA, bug fixing, continuous integration&#039;&#039;&#039;&lt;br /&gt;
: A period after the code freeze where quality assurance testing takes place. No new code is added, which means developers are able to respond rapidly to bugs found. Integration becomes [[Integration Review#During continuous integration/Freeze/QA period|continuous]], meaning that failed QA tests can be re-run within days rather than having to wait for the weekly release.&lt;br /&gt;
; &#039;&#039;&#039;Release candidate&#039;&#039;&#039;&lt;br /&gt;
: A point prior to the full release where a candidate is made public for wider testing.&lt;br /&gt;
&lt;br /&gt;
==New feature development==&lt;br /&gt;
&lt;br /&gt;
Major new features in Moodle usually should go through the following process.&lt;br /&gt;
&lt;br /&gt;
===Specification===&lt;br /&gt;
&lt;br /&gt;
The User Experience (UX) team should create detailed wireframes and features and goals for the new feature. It should be agreed upon and as final as possible before development starts.&lt;br /&gt;
&lt;br /&gt;
Developers should create a detailed spec (here in the developer docs) outlining their goals for the development and their design for meeting those goals.  The more detail the better.&lt;br /&gt;
&lt;br /&gt;
Developers should also create an issue in the tracker (linking to your docs) to keep track of the project status.&lt;br /&gt;
&lt;br /&gt;
===Community consultation===&lt;br /&gt;
&lt;br /&gt;
Get the community involved in looking at the spec to see if it meets their needs and to get further feedback.  Please post in the [http://moodle.org/mod/forum/view.php?id=8052 Future major features forum] on moodle.org. You could also blog/tweet about it etc.&lt;br /&gt;
&lt;br /&gt;
Community developers proposing a new feature will want to talk with HQ core developers to make sure the ideas make sense, and possibly get some review on database design, architecture and so on.&lt;br /&gt;
&lt;br /&gt;
===Develop the code using Git===&lt;br /&gt;
&lt;br /&gt;
Develop your code on an open Git repository, like github.com.  That enables people to see your code and to help you as it develops.  Testers and early adopters also have the opportunity to try it early in the process and give you more valuable feedback.&lt;br /&gt;
&lt;br /&gt;
Coverage with automated tests ([[PHPUnit]] or [[Behat|Behat_integration]]) is mandatory for new features.&lt;br /&gt;
&lt;br /&gt;
It is essential that your code follows the [[Coding|Moodle Coding Guide]].&lt;br /&gt;
&lt;br /&gt;
===Submit your code for peer review===&lt;br /&gt;
&lt;br /&gt;
Click on &amp;quot;Request peer review&amp;quot; button in the tracker.&lt;br /&gt;
&lt;br /&gt;
You need to fill in the information about your public git repository and which branches the fixes are on. Make sure you are listed as Assignee.&lt;br /&gt;
&lt;br /&gt;
This would be a good time to fill in the testing instructions (read the [[Testing instructions guide|instructions guide]]) for how to verify your fix is correct. You may also wish to add a comment in the bug.&lt;br /&gt;
&lt;br /&gt;
Component leads should put issues, which affect code in their components, up for peer review to allow interested parties to provide feedback. However, if it is not reviewed in a week, a component lead may send the issue to integration. If integrators consider that the issue has not been given proper chance for peer review (e.g. is extremely large or complex...) it can be decided to move the issue back in the process.&lt;br /&gt;
&lt;br /&gt;
All other developers, including people who are component leads but working outside their component, should have their issues peer reviewed before they are sent to integration.&lt;br /&gt;
&lt;br /&gt;
===Peer review===&lt;br /&gt;
&lt;br /&gt;
The [http://tracker.moodle.org/browse/MDL#selectedTab=com.atlassian.jira.plugin.system.project%3Acomponents-panel component lead] should peer-review the change. If there is no component lead for an affected component, any other recognised developer may complete the peer review. The peer reviewer will either give you comments on the code and if it needs more work.&lt;br /&gt;
&lt;br /&gt;
Process and the list of things to check are described in [[Peer reviewing]].&lt;br /&gt;
&lt;br /&gt;
===Submit the code for integration===&lt;br /&gt;
&lt;br /&gt;
The developer is responsible for acting on the feedback from the peer reviewer. If changes have been made and the developer is satisfied that this has accommodated the feedback from the peer reviewer, then the developer can submit the issue for integration. If there have been significant changes after the peer review, or if the peer reviewer has raised concerns about the approach taken, then the developer should offer the issue up for peer review again, most often to the same peer reviewer, but not necessarily.&lt;br /&gt;
&lt;br /&gt;
Submitting an issue to integration is much the same as for any Moodle code.  See [[Integration Review]] and the information about the integration workflow above.&lt;br /&gt;
&lt;br /&gt;
==Fixing a bug==&lt;br /&gt;
&lt;br /&gt;
Bug fixes, and minor features or enhancements should go through the following process. (The only exception is English language string typo fixes or suggested improvements, which may be contributed to the en_fix language pack on the [http://lang.moodle.org/ Moodle translation site].)&lt;br /&gt;
&lt;br /&gt;
===Make sure there is a tracker issue===&lt;br /&gt;
&lt;br /&gt;
Every change must have an issue in the tracker. If you are fixing a bug, there is probably one there already, but if not, create one. [[Tracker tips|Tips for searching tracker]].&lt;br /&gt;
&lt;br /&gt;
===Decide which branches the fix is required on===&lt;br /&gt;
&lt;br /&gt;
Bugs should normally be fixed on all the supported stable branches that are affected. New features should just go into master, but sometimes minor enhancements are made on the most recent stable branch.&lt;br /&gt;
&lt;br /&gt;
===Develop your change using git===&lt;br /&gt;
&lt;br /&gt;
Develop your fix and push the change to an open git repository, for example on github.com. See also [[Git for developers]]&lt;br /&gt;
&lt;br /&gt;
It is essential that your code follows the [[Coding|Moodle Coding Guide]].&lt;br /&gt;
&lt;br /&gt;
You will need to push one commit for each branch the fix needs to be applied to. Often people use branch names like MDL-12345-31_brief_name so it is clear what each branch is. [http://kernel.org/pub/software/scm/git/docs/git-cherry-pick.html git cherry-pick] can help with replicating the fix onto different branches.&lt;br /&gt;
&lt;br /&gt;
Consider setting up [[Travis integration]] with your repository so tests will be automatically run for you whenever you push work on your fix.&lt;br /&gt;
&lt;br /&gt;
===Submit your code for peer review===&lt;br /&gt;
&lt;br /&gt;
Once your fix is done, it should be submitted for a peer review.&lt;br /&gt;
&lt;br /&gt;
The following information is necessary for this:&lt;br /&gt;
* Information about your public git repository&lt;br /&gt;
** repository URL&lt;br /&gt;
** branch name(s)&lt;br /&gt;
** diff URL&lt;br /&gt;
* [[Testing instructions guide|Testing instructions]] for how to verify your fix is correct.&lt;br /&gt;
&lt;br /&gt;
If you have never contributed to Moodle and don&#039;t see a button &amp;quot;Request peer review&amp;quot;, just comment on the issue with the above information. The component lead or another user with sufficient privileges will then send the issue up for peer review for you.&lt;br /&gt;
&lt;br /&gt;
After your first fix is integrated you will be added to developers group and will be able to send issues for peer review yourself. In this case make sure you are listed as Assignee and click on &amp;quot;Request peer review&amp;quot; button in the tracker.&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve set up [[Travis integration]], the issue will automatically show the Travis build status for the branch(es) you&#039;ve submitted for peer review.&lt;br /&gt;
&lt;br /&gt;
===Peer review===&lt;br /&gt;
&lt;br /&gt;
The [https://tracker.moodle.org/projects/MDL?selectedItem=com.atlassian.jira.jira-projects-plugin:components-page component lead] should peer-review the change. If there is no component lead for an affected component, any other recognised developer may complete the peer review. The peer reviewer will either give you comments on the code and if it needs more work.&lt;br /&gt;
&lt;br /&gt;
Process and the list of things to check are described in [[Peer reviewing]].&lt;br /&gt;
&lt;br /&gt;
===Submit your code for integration===&lt;br /&gt;
&lt;br /&gt;
It will then be reviewed the following week by one of the integration team and either integrated or rejected. Once integrated, the fix will be tested, and then included in the next weekly release. For details see [[Integration Review]].&lt;br /&gt;
&lt;br /&gt;
==Security issues==&lt;br /&gt;
&lt;br /&gt;
Issues identified as [[Security|security issues]] are resolved in a slightly different way, in order to achieve responsible disclosure as described in [[Moodle security procedures]].&lt;br /&gt;
&lt;br /&gt;
* Security issues should be labelled as &amp;quot;Minor&amp;quot; or &amp;quot;Serious&amp;quot; in order control visibility of the issue.&lt;br /&gt;
** An issue reported with a security level of &amp;quot;Could be a security issue&amp;quot; should be evaluated as soon as possible and either set as &amp;quot;Minor&amp;quot; or &amp;quot;Serious&amp;quot; or the security level should be set to &amp;quot;None&amp;quot;.&lt;br /&gt;
* Solutions to security issues should not:&lt;br /&gt;
** be made available in public repositories.&lt;br /&gt;
*** If a developer has shared a solution as Git branches via Github, they should be asked to provide the solutions as [[How_to_create_a_patch|stand-alone patches]] attached to the issue and to [[#How to remove a branch from Github|remove the solution from Github]].&lt;br /&gt;
** contain details about the security problem in the commit message.&lt;br /&gt;
*** Instead use generic terms like, &amp;quot;improve&amp;quot;, &amp;quot;better handling of&amp;quot; ..&lt;br /&gt;
* The solution will not be integrated until the week before a [[Process#Stable_maintenance_cycles|minor release]] following the normal [[Release process|Release process]]. In short, the issue will be incorporated into the integration version, rebased, tested and made ready for release as a normal issue would, but not until as late as possible.&lt;br /&gt;
* Details of security issues will be shared with registered admins with the minor release.&lt;br /&gt;
* Details of security issues will not be publicly announced until one week after a minor release to allow admins to update.&lt;br /&gt;
&lt;br /&gt;
Note that not all the labelled (minor) security issues are always handled following the procedure above. It&#039;s possible that, after discussion, it&#039;s decided a given issue is not a real Moodle security problem (say external disclosures/potential attacks using Moodle as vector, not as target, discussions revealing some private details...). Those issues will be processed as normal issues, generating the needed user documentation if necessary and will be part of the habitual weekly releases.&lt;br /&gt;
&lt;br /&gt;
====How to remove a branch from Github====&lt;br /&gt;
&lt;br /&gt;
To remove a branch from Github, you can use the following command.&lt;br /&gt;
&lt;br /&gt;
 git push github :remote_branch&lt;br /&gt;
&lt;br /&gt;
Where &#039;&#039;remote_branch&#039;&#039; is the name of your remote branch, for example &#039;wip-mdl-1234&#039;. This effectively replaces the remote branch with nothing, removing the remote branch, but leaving the branch intact in your local Git repository. Please note that its likely that your commit will still exist on github due to the nature of git, so its best to avoid doing this in the first place.&lt;br /&gt;
&lt;br /&gt;
==Policy issues==&lt;br /&gt;
&lt;br /&gt;
Occasionally within Moodle we run into policy issues where a high-level decision needs to be made about how things are to be done.&lt;br /&gt;
&lt;br /&gt;
In these cases the process is as follows:&lt;br /&gt;
* Create an issue in the tracker with a [https://tracker.moodle.org/browse/MDL/component/12733 Policy component] and put &amp;quot;POLICY:&amp;quot; as a prefix on the summary.&lt;br /&gt;
* In the description describe the problem clearly as well as all the options.  If it&#039;s long then make a page here in Moodle Dev Docs and link to it.&lt;br /&gt;
* Do not use this issue for code.  If there are issues that depend on this policy decision, then add tracker links to them as dependencies.&lt;br /&gt;
* Feel free to encourage people to come and talk about the policy to support various points of view.  The more evidence we have (from everyone in the community) the better.&lt;br /&gt;
&lt;br /&gt;
Some time has been scheduled in the weekly Moodle HQ meeting to look at Policy issues and try to make decisions on them.  We discuss all the evidence and try to achieve a high amount of consensus.  Deadlocked issues can be resolved by a decision from Martin Dougiamas (this is rarely needed).&lt;br /&gt;
&lt;br /&gt;
Decisions will be posted on the issue and that issue will be closed, allowing any dependent issues to continue to integration (or not).   Decisions are final and bribes hardly ever work.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Release process]]&lt;br /&gt;
* [[Deprecation]]&lt;br /&gt;
* [http://tracker.moodle.org/secure/Dashboard.jspa?selectPageId=11350 Integration dashboard]&lt;br /&gt;
&lt;br /&gt;
Walks-though of the process for contributors:&lt;br /&gt;
* By Dan Poltawski, Integrator: http://www.slideshare.net/poltawski/how-to-guarantee-your-change-is-integrated-to-moodle-core, https://www.youtube.com/watch?v=836WtnM2YpM&lt;br /&gt;
* By Tim Hunt, contributor: http://tjhunt.blogspot.co.uk/2012/03/fixing-bug-in-moodle-core-mechanics.html and https://www.youtube.com/watch?v=gPPA3h7OGQU and https://youtu.be/Hu8ne0NCRAg?t=11659&lt;br /&gt;
&lt;br /&gt;
[[Category:Processes]]&lt;br /&gt;
[[Category:Quality Assurance]]&lt;br /&gt;
[[Category:Git]]&lt;br /&gt;
[[Category:Core development]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Tracker_tips&amp;diff=58626</id>
		<title>Tracker tips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Tracker_tips&amp;diff=58626"/>
		<updated>2021-04-05T21:34:24Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Useful queries */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Searching=&lt;br /&gt;
&lt;br /&gt;
==Quick search==&lt;br /&gt;
&lt;br /&gt;
On every tracker page you can find search box. Quick search is much more powerful than you might think.&lt;br /&gt;
&lt;br /&gt;
Examples of the quick searches:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Quick search&lt;br /&gt;
! Advanced search equivalent&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Find all unresolved Bugs in Moodle project that contain words abra cadabra&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;MDL Unresolved Bug abra cadabra&#039;&#039;&#039;&lt;br /&gt;
[[{{ns:file}}:trackerquicksearch.png]]&lt;br /&gt;
| project = MDL AND issuetype = Bug AND resolution = Unresolved AND text ~ &amp;quot;abra cadabra&amp;quot;&lt;br /&gt;
[[{{ns:file}}:advancedsearch.png]]&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Find all ongoing issues assigned to me:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;my Unresolved&#039;&#039;&#039;&lt;br /&gt;
| resolution = Unresolved AND assignee = currentUser()&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Quick search can pick up many other keywords, see more information on page [https://confluence.atlassian.com/display/JIRA062/Using+Quick+Search Using quick search]&lt;br /&gt;
&lt;br /&gt;
==Advanced search==&lt;br /&gt;
&lt;br /&gt;
To get here either enter something in quick search or go to the link [https://tracker.moodle.org/issues/?jql= Tracker search page] and switch it to “Advanced” mode.&lt;br /&gt;
Now you can enter queries in the Jira Query Language (JQL). Use as many AND, OR and parenthesis as you want. Some examples and interesting subqueries:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! JQL&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| project = MDL&lt;br /&gt;
| only issues inside project Moodle&lt;br /&gt;
|-&lt;br /&gt;
| resolution = Unresolved&lt;br /&gt;
| Best way to search for open issues&lt;br /&gt;
|-&lt;br /&gt;
| type in (Improvement, &amp;quot;New Feature&amp;quot;)&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| votes &amp;gt; 50&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| component in (Assignment, Gradebook)&lt;br /&gt;
| where component is either Assignment or Gradebook&lt;br /&gt;
|-&lt;br /&gt;
| component = Assignment AND component = Gradebook&lt;br /&gt;
| where both Assignement and Gradebook are listed as components&lt;br /&gt;
|-&lt;br /&gt;
| labels = patch&lt;br /&gt;
| issues containing particular label&lt;br /&gt;
|-&lt;br /&gt;
| labels is empty OR labels not in (triaged, triaging_in_progress)&lt;br /&gt;
| issues NOT containing particular label(s)&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=updatedDate%20%3E%20-7d updatedDate &amp;gt; -7d]&lt;br /&gt;
| updated in the last week&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=assignee%20%3D%20currentUser%28%29%20AND%20resolution%20%3D%20Unresolved assignee = currentUser() AND resolution = Unresolved]&lt;br /&gt;
| open issues where you are an assignee&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=reporter%20%3D%20currentUser%28%29 reporter = currentUser()]&lt;br /&gt;
| issues reported by you&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=Participants%20%20%3D%20currentUser() Participants  = currentUser()]&lt;br /&gt;
| issues where you commented, edited or otherwise participated&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=%22Component%20watchers%22%20%3D%20currentUser()%20and%20resolution%20%3D%20Unresolved &amp;quot;Component watchers&amp;quot; = currentUser() and resolution = Unresolved]&lt;br /&gt;
| open issues in the components where you are an automatic watcher (only tracker admins can assign automatic watchers)&lt;br /&gt;
|-&lt;br /&gt;
| assignee in membersOf(&amp;quot;hq-developers&amp;quot;)&lt;br /&gt;
| issues assigned to members of hq-developers group&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=status%20changed%20to%20%22Waiting%20for%20peer%20review%22%20before%20startofday%28-7%29%20and%20status%20%3D%20%22Waiting%20for%20peer%20review%22 status changed to &amp;quot;Waiting for peer review&amp;quot; before startofday(-7) and status = &amp;quot;Waiting for peer review&amp;quot;]&lt;br /&gt;
| issues waiting for peer review for over a week&lt;br /&gt;
|-&lt;br /&gt;
| status WAS NOT &amp;quot;Development in progress&amp;quot;  BEFORE &amp;quot;2011/02/02&amp;quot;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;issue in linkedIssues(&amp;quot;MDL-12345&amp;quot;)&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
| issues linked to particular issue&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;issue in linkedIssues(&amp;quot;MDL-12345&amp;quot;,&amp;quot;duplicated by&amp;quot;)&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
| &amp;lt;nowiki&amp;gt;Returns all the issues directly and indirectly duplicated by &#039;MDL-12345&#039;. i.e. if there is &#039;MDL-12222&#039;  duplicated by &#039;MDL-12345&#039;   and &#039;MDL-11111&#039;  duplicated by &#039;MDL-12222&#039;, both &#039;MDL-11111&#039; and &#039;MDL-12222&#039; will be returned as search results.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=issue%20in%20favouriteIssues%28%29 issue in favouriteIssues()]&lt;br /&gt;
| issues that you marked as favourite&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More documentation on [https://confluence.atlassian.com/jirasoftwareserver071/advanced-searching-800707146.html Advanced searching]&lt;br /&gt;
&lt;br /&gt;
=Using filters=&lt;br /&gt;
&lt;br /&gt;
To create a filter click on &amp;quot;Save as&amp;quot; button above the search:&lt;br /&gt;
&lt;br /&gt;
[[{{ns:file}}:savefilter1.png]]&lt;br /&gt;
&lt;br /&gt;
Now you can quickly access your filters but also you can subscribe to it, Click on &amp;quot;Details&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[{{ns:file}}:savefilter3.jpg]]&lt;br /&gt;
&lt;br /&gt;
and then on &amp;quot;New subscription&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[{{ns:file}}:savefilter4.png]]&lt;br /&gt;
&lt;br /&gt;
Now you will be notified daily about new issues in Assignment component. You can manage your filters and subscriptions on [https://tracker.moodle.org/secure/ManageFilters.jspa Manage filters] page.&lt;br /&gt;
Watchers automatically receive notifications about the updates of the issues they are watching. Using filter subscription you can either monitor issues that you are not watching or monitor issues that are in particular state and were not updated.&lt;br /&gt;
&lt;br /&gt;
==Useful queries==&lt;br /&gt;
# [https://tracker.moodle.org/issues/?jql=project%20%3D%20mdl%20and%20resolution%20%3D%20unresolved%20and%20type%20in%20%28bug%29%20and%20%22Affected%20Branches%22%20!~%20MOODLE_310_STABLE%20and%20%22Affected%20Branches%22%20!~%20MOODLE_311_STABLE%20and%20reporter%20%3D%20currentUser%28%29 Issues reported by me not against current versions] - make sure that you keep track of your own issues!&lt;br /&gt;
# [https://tracker.moodle.org/issues/?jql=component%20in%20%28componentsLeadByUser%28%29%29%20AND%20resolution%20%3D%20Unresolved%20AND%20updatedDate%20%3E%20-14d%20AND%20project%20%3D%20MDL%20AND%20%28%20labels%20is%20EMPTY%20OR%20labels%20not%20in%20%28triaged%2C%20triaging_in_progress%29%29%20ORDER%20BY%20updatedDate%20ASC Untriaged issues in my components] (works only for component leads)&lt;br /&gt;
# [https://tracker.moodle.org/issues/?jql=status%20changed%20to%20%22Waiting%20for%20peer%20review%22%20before%20startofday(-21)%20and%20status%20%3D%20%22Waiting%20for%20peer%20review%22 Waiting for peer review for 21 days]&lt;br /&gt;
# [https://tracker.moodle.org/issues/?filter=19324 Integrated this week] - subscribe to this filter on Fridays and keep yourself up-to-date with what is happening in Moodle&lt;br /&gt;
&lt;br /&gt;
[[Category:Tracker]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Tracker_tips&amp;diff=58625</id>
		<title>Tracker tips</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Tracker_tips&amp;diff=58625"/>
		<updated>2021-04-05T21:32:37Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Advanced search */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Searching=&lt;br /&gt;
&lt;br /&gt;
==Quick search==&lt;br /&gt;
&lt;br /&gt;
On every tracker page you can find search box. Quick search is much more powerful than you might think.&lt;br /&gt;
&lt;br /&gt;
Examples of the quick searches:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Quick search&lt;br /&gt;
! Advanced search equivalent&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Find all unresolved Bugs in Moodle project that contain words abra cadabra&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;MDL Unresolved Bug abra cadabra&#039;&#039;&#039;&lt;br /&gt;
[[{{ns:file}}:trackerquicksearch.png]]&lt;br /&gt;
| project = MDL AND issuetype = Bug AND resolution = Unresolved AND text ~ &amp;quot;abra cadabra&amp;quot;&lt;br /&gt;
[[{{ns:file}}:advancedsearch.png]]&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Find all ongoing issues assigned to me:&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;my Unresolved&#039;&#039;&#039;&lt;br /&gt;
| resolution = Unresolved AND assignee = currentUser()&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Quick search can pick up many other keywords, see more information on page [https://confluence.atlassian.com/display/JIRA062/Using+Quick+Search Using quick search]&lt;br /&gt;
&lt;br /&gt;
==Advanced search==&lt;br /&gt;
&lt;br /&gt;
To get here either enter something in quick search or go to the link [https://tracker.moodle.org/issues/?jql= Tracker search page] and switch it to “Advanced” mode.&lt;br /&gt;
Now you can enter queries in the Jira Query Language (JQL). Use as many AND, OR and parenthesis as you want. Some examples and interesting subqueries:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! JQL&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| project = MDL&lt;br /&gt;
| only issues inside project Moodle&lt;br /&gt;
|-&lt;br /&gt;
| resolution = Unresolved&lt;br /&gt;
| Best way to search for open issues&lt;br /&gt;
|-&lt;br /&gt;
| type in (Improvement, &amp;quot;New Feature&amp;quot;)&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| votes &amp;gt; 50&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| component in (Assignment, Gradebook)&lt;br /&gt;
| where component is either Assignment or Gradebook&lt;br /&gt;
|-&lt;br /&gt;
| component = Assignment AND component = Gradebook&lt;br /&gt;
| where both Assignement and Gradebook are listed as components&lt;br /&gt;
|-&lt;br /&gt;
| labels = patch&lt;br /&gt;
| issues containing particular label&lt;br /&gt;
|-&lt;br /&gt;
| labels is empty OR labels not in (triaged, triaging_in_progress)&lt;br /&gt;
| issues NOT containing particular label(s)&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=updatedDate%20%3E%20-7d updatedDate &amp;gt; -7d]&lt;br /&gt;
| updated in the last week&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=assignee%20%3D%20currentUser%28%29%20AND%20resolution%20%3D%20Unresolved assignee = currentUser() AND resolution = Unresolved]&lt;br /&gt;
| open issues where you are an assignee&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=reporter%20%3D%20currentUser%28%29 reporter = currentUser()]&lt;br /&gt;
| issues reported by you&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=Participants%20%20%3D%20currentUser() Participants  = currentUser()]&lt;br /&gt;
| issues where you commented, edited or otherwise participated&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=%22Component%20watchers%22%20%3D%20currentUser()%20and%20resolution%20%3D%20Unresolved &amp;quot;Component watchers&amp;quot; = currentUser() and resolution = Unresolved]&lt;br /&gt;
| open issues in the components where you are an automatic watcher (only tracker admins can assign automatic watchers)&lt;br /&gt;
|-&lt;br /&gt;
| assignee in membersOf(&amp;quot;hq-developers&amp;quot;)&lt;br /&gt;
| issues assigned to members of hq-developers group&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=status%20changed%20to%20%22Waiting%20for%20peer%20review%22%20before%20startofday%28-7%29%20and%20status%20%3D%20%22Waiting%20for%20peer%20review%22 status changed to &amp;quot;Waiting for peer review&amp;quot; before startofday(-7) and status = &amp;quot;Waiting for peer review&amp;quot;]&lt;br /&gt;
| issues waiting for peer review for over a week&lt;br /&gt;
|-&lt;br /&gt;
| status WAS NOT &amp;quot;Development in progress&amp;quot;  BEFORE &amp;quot;2011/02/02&amp;quot;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;issue in linkedIssues(&amp;quot;MDL-12345&amp;quot;)&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
| issues linked to particular issue&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;issue in linkedIssues(&amp;quot;MDL-12345&amp;quot;,&amp;quot;duplicated by&amp;quot;)&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
| &amp;lt;nowiki&amp;gt;Returns all the issues directly and indirectly duplicated by &#039;MDL-12345&#039;. i.e. if there is &#039;MDL-12222&#039;  duplicated by &#039;MDL-12345&#039;   and &#039;MDL-11111&#039;  duplicated by &#039;MDL-12222&#039;, both &#039;MDL-11111&#039; and &#039;MDL-12222&#039; will be returned as search results.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| [https://tracker.moodle.org/issues/?jql=issue%20in%20favouriteIssues%28%29 issue in favouriteIssues()]&lt;br /&gt;
| issues that you marked as favourite&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More documentation on [https://confluence.atlassian.com/jirasoftwareserver071/advanced-searching-800707146.html Advanced searching]&lt;br /&gt;
&lt;br /&gt;
=Using filters=&lt;br /&gt;
&lt;br /&gt;
To create a filter click on &amp;quot;Save as&amp;quot; button above the search:&lt;br /&gt;
&lt;br /&gt;
[[{{ns:file}}:savefilter1.png]]&lt;br /&gt;
&lt;br /&gt;
Now you can quickly access your filters but also you can subscribe to it, Click on &amp;quot;Details&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[{{ns:file}}:savefilter3.jpg]]&lt;br /&gt;
&lt;br /&gt;
and then on &amp;quot;New subscription&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[{{ns:file}}:savefilter4.png]]&lt;br /&gt;
&lt;br /&gt;
Now you will be notified daily about new issues in Assignment component. You can manage your filters and subscriptions on [https://tracker.moodle.org/secure/ManageFilters.jspa Manage filters] page.&lt;br /&gt;
Watchers automatically receive notifications about the updates of the issues they are watching. Using filter subscription you can either monitor issues that you are not watching or monitor issues that are in particular state and were not updated.&lt;br /&gt;
&lt;br /&gt;
==Useful queries==&lt;br /&gt;
# [https://tracker.moodle.org/issues/?jql=project%20%3D%20mdl%20and%20resolution%20%3D%20unresolved%20and%20type%20in%20%28bug%29%20and%20%22Affected%20Branches%22%20!~%20MOODLE_31_STABLE%20and%20%22Affected%20Branches%22%20!~%20MOODLE_30_STABLE%20and%20reporter%20%3D%20currentUser%28%29 Issues reported by me not against current versions] - make sure that you keep track of your own issues!&lt;br /&gt;
# [https://tracker.moodle.org/issues/?jql=component%20in%20%28componentsLeadByUser%28%29%29%20AND%20resolution%20%3D%20Unresolved%20AND%20updatedDate%20%3E%20-14d%20AND%20project%20%3D%20MDL%20AND%20%28%20labels%20is%20EMPTY%20OR%20labels%20not%20in%20%28triaged%2C%20triaging_in_progress%29%29%20ORDER%20BY%20updatedDate%20ASC Untriaged issues in my components] (works only for component leads)&lt;br /&gt;
# [https://tracker.moodle.org/issues/?jql=status%20changed%20to%20%22Waiting%20for%20peer%20review%22%20before%20startofday(-21)%20and%20status%20%3D%20%22Waiting%20for%20peer%20review%22 Waiting for peer review for 21 days]&lt;br /&gt;
# [https://tracker.moodle.org/issues/?filter=19324 Integrated this week] - subscribe to this filter on Fridays and keep yourself up-to-date with what is happening in Moodle&lt;br /&gt;
&lt;br /&gt;
[[Category:Tracker]]&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=58624</id>
		<title>Question bank improvements for Moodle 4.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=58624"/>
		<updated>2021-04-01T12:49:31Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Contributors (workforce) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.0&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-70329&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=417599&lt;br /&gt;
|assignee = Project instigated by Thomas Korner, [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]], Antonia Bonaccorso. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle_4.0}}&lt;br /&gt;
&lt;br /&gt;
This is a project to largely re-develop the question bank for Moodle 4.0 (if possible). The aim is to&lt;br /&gt;
&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
&lt;br /&gt;
The project has been explained in detail in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread], so for more details, please read that.&lt;br /&gt;
&lt;br /&gt;
== Project support ==&lt;br /&gt;
&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
* Yvonne Wolf&lt;br /&gt;
&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project ===&lt;br /&gt;
This institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=58620</id>
		<title>Question bank improvements for Moodle 4.0</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Question_bank_improvements_for_Moodle_4.0&amp;diff=58620"/>
		<updated>2021-03-30T08:14:05Z</updated>

		<summary type="html">&lt;p&gt;Finns: /* Contributors (financially) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Question bank improvements for Moodle 4.0&lt;br /&gt;
|state = Development in progress&lt;br /&gt;
|tracker = MDL-70329&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=417599&lt;br /&gt;
|assignee = Project instigated by Thomas Korner, [[User:Luca_B%C3%B6sch|Luca Bösch]], [[User:Tim Hunt|Tim Hunt]], Antonia Bonaccorso. Implementation by Catalyst AU&lt;br /&gt;
}}&lt;br /&gt;
{{Moodle_4.0}}&lt;br /&gt;
&lt;br /&gt;
This is a project to largely re-develop the question bank for Moodle 4.0 (if possible). The aim is to&lt;br /&gt;
&lt;br /&gt;
* add some important new features, like question versioning, and making it easier to track where each question is used.&lt;br /&gt;
* improve how the code is organised, for example by introducing a new &#039;Question bank plugin&#039; type (qbank_).&lt;br /&gt;
* and fix some long-standing bugs, for example the problems with question backup and restore.&lt;br /&gt;
&lt;br /&gt;
The project has been explained in detail in [https://moodle.org/mod/forum/discuss.php?d=417599 this forum thread], so for more details, please read that.&lt;br /&gt;
&lt;br /&gt;
== Project support ==&lt;br /&gt;
&lt;br /&gt;
This project is proceeding thanks to the support of [[Question_bank_improvements_for_Moodle_4.0#Contributors|a number of universities and other organisations]] who crowd-funded the development.&lt;br /&gt;
&lt;br /&gt;
== Work-in-progress ==&lt;br /&gt;
&lt;br /&gt;
In time, we will and more information here, for example links to a prototype site.&lt;br /&gt;
&lt;br /&gt;
== Contributors ==&lt;br /&gt;
&lt;br /&gt;
=== Contributors (initiators) ===&lt;br /&gt;
* The Open University&lt;br /&gt;
* ETH Zurich&lt;br /&gt;
* BFH Bern University of Applied Sciences&lt;br /&gt;
&lt;br /&gt;
=== Contributors (financially) ===&lt;br /&gt;
* Berlin Institute of Technology (Technische Universität Berlin), Germany&lt;br /&gt;
* Dublin City University, Ireland&lt;br /&gt;
* Hochschule Hannover - University of Applied Sciences and Arts, Germany &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
* Johannes Kepler University Linz, Austria&lt;br /&gt;
* University of Applied Sciences and Arts Northwestern Switzerland, Switzerland&lt;br /&gt;
* Zurich University of Applied Sciences, Switzerland &amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Contributors (workforce) ===&lt;br /&gt;
* Catalyst Australia&lt;br /&gt;
&lt;br /&gt;
=== Overflowing funds from the SEB deeper integration project ===&lt;br /&gt;
This institutions are credited here since they participated in the Safe Exam Browser deeper integration project. The remaining funds were allowed to be used in this project here.&lt;br /&gt;
&lt;br /&gt;
* Berlin School of Economics and Law, Germany&lt;br /&gt;
* Neubrandenburg University of Applied Sciences, Germany&lt;br /&gt;
* Ruhr-University Bochum, Germany&lt;br /&gt;
* University of Applied Sciences Upper Austria, Austria&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sup&amp;gt;*&amp;lt;/sup&amp;gt; Institutions funding in both SEB deeper integration as well as Question bank improvements for Moodle 4.0 project&lt;/div&gt;</summary>
		<author><name>Finns</name></author>
	</entry>
</feed>