<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/501/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bruno</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/501/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bruno"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/Special:Contributions/Bruno"/>
	<updated>2026-04-16T15:33:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Use_Stats_Block&amp;diff=128874</id>
		<title>Use Stats Block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Use_Stats_Block&amp;diff=128874"/>
		<updated>2017-09-25T00:50:14Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This block allows displaying use stats for the current user.&lt;br /&gt;
&lt;br /&gt;
Use stats are given as an answer to the &amp;quot;how many time I spent on this Moodle&amp;quot;. This may be usefull in situation where work time should be known to estimate average personnal productivity and enhancing its own process. &lt;br /&gt;
&lt;br /&gt;
In other situations could it be used as an objetive proof of real work in some extreme and conflictual situations we hope they never occur.&lt;br /&gt;
&lt;br /&gt;
== Short overview ==&lt;br /&gt;
&lt;br /&gt;
This block samples the user&#039;s log records and thresholds the activity backtrace. The main hypothesis is that any activity type unless offline activity or in-classroom activity may underlie a constant loggin track generation. &lt;br /&gt;
&lt;br /&gt;
The block compiles all log events and summarizes all intervals larger than an adjustable threshold. Compilation are also made on a course basis.&lt;br /&gt;
&lt;br /&gt;
The more Moodle is used as a daily content editing tool, the more accurate should be this report.&lt;br /&gt;
&lt;br /&gt;
===Limitations===&lt;br /&gt;
&lt;br /&gt;
As the use stats module scans logs for compiling a real use time, the results might be affected by the log cleanup policy. Do not expect keeping more use time tracking results further than the log conservation period setup in central settings.&lt;br /&gt;
&lt;br /&gt;
== Other information ==&lt;br /&gt;
&lt;br /&gt;
=== Global settings ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;block_use_stats_fromwhen&#039;&#039; : the default setting for the compilation range. Used at first time the block is displayed.&lt;br /&gt;
* &#039;&#039;block_use_stats_threshold&#039;&#039; : the threshold applied on log gap to determine if the time gap is within continuous session or not. All time ranges over the threshold will be ignored. The gap corresponds to two&lt;br /&gt;
immediately consequent writes from the same user in the Moodle log.&lt;br /&gt;
* &#039;&#039;block_use_stats_capturemodules&#039;&#039; : stats can be compiled ignoring some activities or some functional sections of Moodle. You may declare the list of log tags that will be measured in Moodle. For a more accurate calculation, you may add the &amp;quot;course&amp;quot; section to the list, that is not handled in the default setting.&lt;br /&gt;
* &#039;&#039;block_use_stats_ignoremodules&#039;&#039; : stats can be compiled ignoring some activities or some functional sections of Moodle. You may declare the list of log tags that will be ignored in Moodle. You will leave the previous setting empty to start with all sections.  &lt;br /&gt;
&lt;br /&gt;
=== Local settings ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Block heading&#039;&#039; : You may change the visible heading of the block.&lt;br /&gt;
&lt;br /&gt;
=== Capabilities ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;block/use_stats:read&#039;&#039; : General capability to allow viewing some information from this block.&lt;br /&gt;
* &#039;&#039;block/use_stats:config&#039;&#039; : General capability to allow configuring the log range.&lt;br /&gt;
* &#039;&#039;block/use_stats:seesitedetails&#039;&#039; : Allows power users to see detailed results from anyone.&lt;br /&gt;
* &#039;&#039;block/use_stats:seecoursedetails&#039;&#039; : Allows power users to see detailed results from other users then themselves in the course they are enrolled in.&lt;br /&gt;
* &#039;&#039;block/use_stats:seegroupdetails&#039;&#039; : Allows power users to see detailed results from other users then themselves from the groups they are member of.&lt;br /&gt;
* &#039;&#039;block/use_stats:seeowndetails&#039;&#039; : usually applyed to students when they are allowed to consult their time report. Gives access to the activity/resource detailed time sheet.&lt;br /&gt;
&lt;br /&gt;
=== Use Stats dependant follow ups ===&lt;br /&gt;
&lt;br /&gt;
You may use Use Stats and the [https://docs.moodle.org/24/en/Use_Time_Based_Course_Report Training Session Report] from Moodle 2.2 version up. Training Session Report aggregates all results in a &amp;quot;pedagogic view&amp;quot; of the course and allows mass export of training session trackings in Excel documents.&lt;br /&gt;
&lt;br /&gt;
=== Reference, information, development and support ===&lt;br /&gt;
&lt;br /&gt;
valery.fremaux-AT-gmail.com&lt;br /&gt;
[[Category:Contributed code]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Temps_d&#039;usage]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=error/moodle/csvloaderror&amp;diff=96690</id>
		<title>error/moodle/csvloaderror</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=error/moodle/csvloaderror&amp;diff=96690"/>
		<updated>2012-03-27T21:01:07Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Unfortunately the module which loads the csv data doesn&#039;t explain what is wrong.&lt;br /&gt;
&lt;br /&gt;
#Check&lt;br /&gt;
## First line must contain column headings SPELLED correctly&lt;br /&gt;
## There should not be quotes (i.e. &amp;quot;)&lt;br /&gt;
## There should not be a trailing comma (i.e. ,)&lt;br /&gt;
## When uploading custom profile field names, make sure that the short name is in lowercase&lt;br /&gt;
&lt;br /&gt;
While you&#039;re here, contrary to popular belief, usernames must be in lowercase in the file to be uploaded.&lt;br /&gt;
&lt;br /&gt;
for more, see https://docs.moodle.org/24/en/admin/tool/uploaduser/index&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Administration_via_command_line&amp;diff=82685</id>
		<title>Administration via command line</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Administration_via_command_line&amp;diff=82685"/>
		<updated>2011-04-10T05:17:58Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Upgrading via command line */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
&lt;br /&gt;
If you have shell access to your web server, you may find various CLI (command line interface) scripts useful during Moodle administration. All command line tools are located in &amp;lt;code&amp;gt;admin/cli/*&amp;lt;/code&amp;gt; directory. To avoid problems with access control, you should run them as the owner of the web server process. It is especially important for CLI installation and upgrade as they create new files in moodledata directory and the web server has to have write access to them. In Linux distributions, the user that runs the web server is usually apache or wwrun or httpd or something similar. As a root, you will probably want to execute Moodle CLI scripts like this:&lt;br /&gt;
&lt;br /&gt;
    $ cd /path/to/your/moodle/dir&lt;br /&gt;
    $ sudo -u apache /usr/bin/php admin/cli/somescript.php --params&lt;br /&gt;
&lt;br /&gt;
Most of the scripts accept common --help (or -h) parameter to display the full usage information, for example:&lt;br /&gt;
&lt;br /&gt;
    $ sudo -u apache /usr/bin/php admin/cli/install.php --help&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation via command line ==&lt;br /&gt;
&lt;br /&gt;
Since version 2.0, Moodle can be installed from the command line. There are two modes of installation. In interactive mode, the install script asks you for all data needed to properly set up new Moodle site. In non-interactive mode, you must provide all required data as the script parameters and then the new site is installed silently. The parameters can be passed in the interactive mode, too. The provided values are then used as the default values during the interactive session.&lt;br /&gt;
&lt;br /&gt;
    $ sudo -u apache /usr/bin/php admin/cli/install.php --lang=cs&lt;br /&gt;
&lt;br /&gt;
== Maintenance mode ==&lt;br /&gt;
&lt;br /&gt;
To switch your site into the maintenance mode via CLI, you can use&lt;br /&gt;
&lt;br /&gt;
    $ sudo -u apache /usr/bin/php admin/cli/maintenance.php --enable&lt;br /&gt;
&lt;br /&gt;
To turn the maintenance mode off, just execute the same script with --disable parameter.&lt;br /&gt;
&lt;br /&gt;
== Offline mode ==&lt;br /&gt;
&lt;br /&gt;
In some situations, you may want to switch your Moodle site into offline mode so that it is not accessible via the web but you can not stop the web server completely (typically because there are other web pages and applications running there). If a file called &amp;lt;code&amp;gt;climaintenance.html&amp;lt;/code&amp;gt; exists in the root folder of moodledata directory, Moodle will automatically display the contents of that file instead of any other page.&lt;br /&gt;
&lt;br /&gt;
    $ cd /var/www/sites/moodle/moodledata/&lt;br /&gt;
    $ echo &#039;&amp;amp;lt;h1&amp;amp;gt;Sorry, maintenance in progress&amp;amp;lt;/h1&amp;amp;gt;&#039; &amp;amp;gt; climaintenance.html&lt;br /&gt;
&lt;br /&gt;
You can prepare a nice formatted HTML page to inform your users about the server being down and keep in the moodledata directory under a name like &amp;lt;code&amp;gt;climaintenance.off&amp;lt;/code&amp;gt; and rename it to the &amp;lt;code&amp;gt;climaintenance.html&amp;lt;/code&amp;gt; if needed.&lt;br /&gt;
&lt;br /&gt;
== Upgrading via command line ==&lt;br /&gt;
&lt;br /&gt;
Moodle can be upgraded from the command line. As with the installation script, there is either interactive or non-interactive mode of the upgrade. The script itself does not put the site into the maintenance mode, you have to do it on your own. Also, the script does not backup any data (if you read this page, you probably have some own scripts to backup your moodledata and the database, right?)&lt;br /&gt;
&lt;br /&gt;
    $ sudo -u aphe cli script for upgrading to moodle 2.0 normally outputs those same messages too.ache /usr/bin/php admin/cli/upgrade.php --non-interactive&lt;br /&gt;
&lt;br /&gt;
Upgrading via command line is a very comfortable way of Moodle upgrade if you use [[CVS]] or [[Git|git]] checkout of the Moodle source code. See the following procedure how to upgrade your site within several seconds to the most recent version while preserving your eventual local customizations tracked in git repository:&lt;br /&gt;
&lt;br /&gt;
    $ cd /var/www/sites/moodle/htdocs/&lt;br /&gt;
    $ git fetch&lt;br /&gt;
    $ sudo -u apache /usr/bin/php admin/cli/maintenance.php --enable&lt;br /&gt;
    $ git merge origin/cvshead&lt;br /&gt;
    $ sudo -u apache /usr/bin/php admin/cli/upgrade.php&lt;br /&gt;
    $ sudo -u apache /usr/bin/php admin/cli/maintenance.php --disable&lt;br /&gt;
&lt;br /&gt;
===Issues with Upgrading via Command Line===&lt;br /&gt;
&lt;br /&gt;
if your config.php contains information about several moodle instances (distinct moodle websites and databases sharing the same codebase), then this script will silently fail&lt;br /&gt;
&lt;br /&gt;
The solution is to temporarily eliminate from config.php all but the one instance you want to upgrade &lt;br /&gt;
&lt;br /&gt;
If this is a problem for the other instances (production sites), then modify the cli script to point to a copy of config.php  (which will be the one edited to contain only one moodle instance at a time)&lt;br /&gt;
&lt;br /&gt;
== Custom site defaults ==&lt;br /&gt;
&lt;br /&gt;
During the install and upgrade via CLI, Moodle sets the administration variables to the default values. You can use different defaults. See MDL-17850 for details. Shortly, all you need to do is to add a file &amp;lt;code&amp;gt;local/defaults.php&amp;lt;/code&amp;gt; into your Moodle installation. The format of the file is like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$defaults[&#039;pluginname&#039;][&#039;settingname&#039;] = &#039;settingvalue&#039;; // for plugins&lt;br /&gt;
$defaults[&#039;moodle&#039;][&#039;settingname&#039;] = &#039;settingvalue&#039;;     // for core settings&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These defaults are used during install, upgrade and are also displayed as defaults at the Site administration pages.&lt;br /&gt;
&lt;br /&gt;
== Reset user password ==&lt;br /&gt;
&lt;br /&gt;
If you happen to forget your admin password (or you want to set a password for any other user of your Moodle system), you can use reset_password.php script. The script sets the correctly salted password for the given user.&lt;br /&gt;
&lt;br /&gt;
    $ sudo -u apache /usr/bin/php admin/cli/reset_password.php&lt;br /&gt;
&lt;br /&gt;
== MySQL storage engine conversion ==&lt;br /&gt;
&lt;br /&gt;
If you run your Moodle site with MySQL database backend and use the default MyISAM as the storage engine for your tables, you may want to convert them to use some more reliable engine like InnoDB (actually, you should want to switch to PostgreSQL ;-) anyway).&lt;br /&gt;
&lt;br /&gt;
    $ sudo -u apache /usr/bin/php admin/cli/mysql_engine.php --engine=InnoDB&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running cron via command line ==&lt;br /&gt;
&lt;br /&gt;
In versions 1.x, you could execute admin/cron.php either from command line or via the web. Since Moodle 2.0, only admin/cli/cron.php script can be run via command line.&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Administration en ligne de commande]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:DML_drivers&amp;diff=78614</id>
		<title>Development:DML drivers</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:DML_drivers&amp;diff=78614"/>
		<updated>2010-12-03T06:41:02Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Query logging */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}Previous versions were using adodb abstraction partially encapsulated by old DML api. The database drivers are now fully separated from the rest of code and it is even possible to create new native drivers that do not rely on adodb abstraction anymore.&lt;br /&gt;
&lt;br /&gt;
At present there are three native drivers - mysqli, pgsql and unfinished Oracle driver. The benefits are:&lt;br /&gt;
* more optimised and probably faster&lt;br /&gt;
* consume less memory&lt;br /&gt;
* better possibility to improve logging, debugging, profiling, etc.&lt;br /&gt;
* less code, easier to fix and maintain&lt;br /&gt;
* and more&lt;br /&gt;
&lt;br /&gt;
Please note old adodb based drivers will be removed before the branching of 2.0.&lt;br /&gt;
&lt;br /&gt;
==Query logging==&lt;br /&gt;
New native DML drivers support logging of database queries to database table. Logging can be enabled in config.php&lt;br /&gt;
&lt;br /&gt;
 $CFG-&amp;gt;dboptions = array (&lt;br /&gt;
  &#039;dbpersist&#039; =&amp;gt; 0,&lt;br /&gt;
  //&#039;logall&#039;   =&amp;gt; true,&lt;br /&gt;
  &#039;logslow&#039;  =&amp;gt; 5,&lt;br /&gt;
  &#039;logerrors&#039;  =&amp;gt; true,&lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;logall&#039;&#039;&#039; - log all queries - suitable only for developers, causes high server loads&lt;br /&gt;
* &#039;&#039;&#039;logslow&#039;&#039;&#039; - log queries that take longer than specified number of seconds (float values are accepted)&lt;br /&gt;
* &#039;&#039;&#039;logerrors&#039;&#039;&#039; - log all error queries&lt;br /&gt;
&lt;br /&gt;
==TODO==&lt;br /&gt;
* add more info here&lt;br /&gt;
* add separate docs pages for each driver - describe all options there&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:DML functions|DML functions]]: Where all the functions used to handle DB data ([[wikipedia:Data_Manipulation_Language|DML]]) are defined.&lt;br /&gt;
* [[Development:DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:DML_drivers&amp;diff=78613</id>
		<title>Development:DML drivers</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:DML_drivers&amp;diff=78613"/>
		<updated>2010-12-03T06:40:25Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Query logging */  spelling correction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}Previous versions were using adodb abstraction partially encapsulated by old DML api. The database drivers are now fully separated from the rest of code and it is even possible to create new native drivers that do not rely on adodb abstraction anymore.&lt;br /&gt;
&lt;br /&gt;
At present there are three native drivers - mysqli, pgsql and unfinished Oracle driver. The benefits are:&lt;br /&gt;
* more optimised and probably faster&lt;br /&gt;
* consume less memory&lt;br /&gt;
* better possibility to improve logging, debugging, profiling, etc.&lt;br /&gt;
* less code, easier to fix and maintain&lt;br /&gt;
* and more&lt;br /&gt;
&lt;br /&gt;
Please note old adodb based drivers will be removed before the branching of 2.0.&lt;br /&gt;
&lt;br /&gt;
==Query logging==&lt;br /&gt;
New native DML drivers support logging of database queries to database table. Logging can be enabled in config.php&lt;br /&gt;
&lt;br /&gt;
 $CFG-&amp;gt;dboptions = array (&lt;br /&gt;
  &#039;dbpersit&#039; =&amp;gt; 0,&lt;br /&gt;
  //&#039;logall&#039;   =&amp;gt; true,&lt;br /&gt;
  &#039;logslow&#039;  =&amp;gt; 5,&lt;br /&gt;
  &#039;logerrors&#039;  =&amp;gt; true,&lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;logall&#039;&#039;&#039; - log all queries - suitable only for developers, causes high server loads&lt;br /&gt;
* &#039;&#039;&#039;logslow&#039;&#039;&#039; - log queries that take longer than specified number of seconds (float values are accepted)&lt;br /&gt;
* &#039;&#039;&#039;logerrors&#039;&#039;&#039; - log all error queries&lt;br /&gt;
&lt;br /&gt;
==TODO==&lt;br /&gt;
* add more info here&lt;br /&gt;
* add separate docs pages for each driver - describe all options there&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Development:DML functions|DML functions]]: Where all the functions used to handle DB data ([[wikipedia:Data_Manipulation_Language|DML]]) are defined.&lt;br /&gt;
* [[Development:DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:DML_functions&amp;diff=78612</id>
		<title>Development:DML functions</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:DML_functions&amp;diff=78612"/>
		<updated>2010-12-03T06:29:56Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Using Recordsets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}This page describes the functions available to access data in the Moodle database. You should &#039;&#039;&#039;exclusively&#039;&#039;&#039; use these functions in order to retrieve or modify database content because these functions provide a high level of abstraction and guarantee that your database manipulation will work against different RDBMSes.&lt;br /&gt;
&lt;br /&gt;
Where possible, tricks and examples will be documented here in order to make developers&#039; lives a bit easier. Of course, feel free to clarify, complete and add more information to  this documentation. It will be welcome, absolutely!&lt;br /&gt;
&lt;br /&gt;
== Main info ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; All the functions shown on this page are for use in &#039;&#039;&#039;Moodle 2.0 upwards&#039;&#039;&#039;, where we changed the [[Development:DB layer 2.0|DB layer]] to support some new features. If you need information for previous Moodle version, take a look to the [[Development:DML functions - pre 2.0|DML functions - pre 2.0]] page. For a detailed reference of changes, see the [[Development:DB layer 2.0 migration docs|migration docs]].&lt;br /&gt;
&lt;br /&gt;
* All the function calls on this page are public methods of the $DB global object, so you&#039;ll need to &amp;quot;import&amp;quot; it within your functions (not needed in global scripts) with one simple:&lt;br /&gt;
&amp;lt;code php&amp;gt;global $DB;&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $table parameters in the functions are meant to be the table name &#039;&#039;without&#039;&#039; prefixes.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;&#039;1&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* When using the xxx_sql() functions, table names must be enclosed between curly braces.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE id = ?&#039;, array(1));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $conditions parameters in the functions are arrays of fieldname=&amp;gt;fieldvalue elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $params parameters in the functions are arrays of values used to fill placeholders in SQL statements. Both the question mark and named placeholders can be used. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039; even if the value passed is the same.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// Question mark placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = ? AND lastname = ?&#039;, &lt;br /&gt;
                       array(&#039;Martin&#039;, &#039;Dougiamas&#039;));&lt;br /&gt;
&lt;br /&gt;
/// Named placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = :firstname AND lastname = :lastname&#039;,&lt;br /&gt;
                       array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The functions ==&lt;br /&gt;
&lt;br /&gt;
===Seeing how many records match a given criteria===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;count_records($table, array $conditions=null) &lt;br /&gt;
  /// Count the records in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;count_records_select($table, $select, array $params=null, $countitem=&amp;quot;COUNT(&#039;x&#039;)&amp;quot;) &lt;br /&gt;
  /// Count the records in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;count_records_sql($sql, array $params=null) &lt;br /&gt;
  /// Get the result of a SQL SELECT COUNT(...) query.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Seeing if one record exists===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;record_exists($table, array $conditions=null) &lt;br /&gt;
  /// Test whether a record exists in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;record_exists_select($table, $select, array $params=null) &lt;br /&gt;
  /// Test whether any records exists in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;record_exists_sql($sql, array $params=null) &lt;br /&gt;
  /// Test whether a SQL SELECT statement returns any records.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a single record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_record($table, array $conditions, $fields=&#039;*&#039;, $ignoremultiple=false) &lt;br /&gt;
  /// Get a single database record as an object where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_record_select($table, $select, array $params=null, $fields=&#039;*&#039;, $ignoremultiple=false)&lt;br /&gt;
  /// Get a single database record as an object which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_record_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single database record as an object using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting an array of records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get a number of records as an array of objects using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_records_menu($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select_menu($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_records_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from one record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_field($table, $return, array $conditions)&lt;br /&gt;
  /// Get a single field value from a table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_field_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Get a single field value from a table record which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_field_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single field value (first field) using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from various records===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_sql($sql, array $params=null)&lt;br /&gt;
  /// Selects records and return values (first field) as an array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting a particular field in the database===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;set_field($table, $newfield, $newvalue, array $conditions=null)&lt;br /&gt;
  /// Set a single field in every table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;set_field_select($table, $newfield, $newvalue, $select, array $params=null)&lt;br /&gt;
  /// Set a single field in every table record which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Deleting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;delete_records($table, array $conditions=null) &lt;br /&gt;
  /// Delete the records from a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;delete_records_select($table, $select, array $params=null)&lt;br /&gt;
  /// Delete one or more records from a table which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inserting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;insert_record($table, $dataobject, $returnid=true, $bulk=false) &lt;br /&gt;
  /// Insert a record into a table and return the &amp;quot;id&amp;quot; field if required.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Updating Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;update_record($table, $dataobject, $bulk=false)&lt;br /&gt;
  /// Update a record in a table.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Recordsets===&lt;br /&gt;
&lt;br /&gt;
Where the number of records to be retrieved from DB is high, the &#039;&#039;&#039;get_records_xxx()&#039;&#039;&#039; functions above are far from optimal, because they load all the records in memory at the same time. Under those circumstances, it is highly recommended to use these &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions instead, which use one nice mechanism to iterate over all the target records and save a lot of memory.&lt;br /&gt;
&lt;br /&gt;
Only one thing is &#039;&#039;&#039;absolutely important&#039;&#039;&#039;: Don&#039;t forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).&lt;br /&gt;
&lt;br /&gt;
Here is the general way to iterate over records using the &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($rs = $DB-&amp;gt;get_recordset(....) {&lt;br /&gt;
    foreach ($rs as $record) {&lt;br /&gt;
     /// Do whatever you want with this record&lt;br /&gt;
    }&lt;br /&gt;
    $rs-&amp;gt;close(); /// Don&#039;t forget to close the recordset!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And this is the list of available functions (100% paired with the get_records_xxx() above):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_recordset($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);&lt;br /&gt;
  /// Get a number of records as a moodle_recordset using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_recordset_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where one field matches one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delegated transactions===&lt;br /&gt;
&lt;br /&gt;
* Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).&lt;br /&gt;
* Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.&lt;br /&gt;
* Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.&lt;br /&gt;
* Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.&lt;br /&gt;
&lt;br /&gt;
A transaction is started by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finished by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually a transaction is rolled back when an exception is thrown. &amp;lt;code&amp;gt;$transaction-&amp;gt;rollback($ex);&amp;lt;/code&amp;gt; must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.&lt;br /&gt;
&lt;br /&gt;
See more details in [[Development:DB layer 2.0 delegated transactions]] or MDL-20625.&lt;br /&gt;
&lt;br /&gt;
===Helper Functions===&lt;br /&gt;
&lt;br /&gt;
In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we&#039;ll avoid conditional queries here and there and have those &amp;quot;incompatibilities&amp;quot; fixed once and for ever.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;sql_bitand($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise AND &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitnot($int1) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise NOT &lt;br /&gt;
  /// operation with 1 integer.&lt;br /&gt;
o $DB-&amp;gt;sql_bitor($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise OR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitxor($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise XOR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_null_from_clause()&lt;br /&gt;
  /// Returns the FROM clause required by some DBs in all SELECT statements.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_ceil($fieldname)&lt;br /&gt;
  /// Returns the correct CEIL expression applied to fieldname.&lt;br /&gt;
o $DB-&amp;gt;sql_ilike()&lt;br /&gt;
  /// Returns the proper SQL to do LIKE in a case-insensitive way.&lt;br /&gt;
o $DB-&amp;gt;sql_length($fieldname)&lt;br /&gt;
  /// Returns the SQL text to be used to calculate the length in characters of one expression.&lt;br /&gt;
o $DB-&amp;gt;sql_modulo($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to calculate module - remainder after division&lt;br /&gt;
o $DB-&amp;gt;sql_position($needle, $haystack)&lt;br /&gt;
  /// Returns the SQL for returning searching one string for the location of another.&lt;br /&gt;
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.&lt;br /&gt;
o $DB-&amp;gt;sql_substr($expr, $start, $length=false)&lt;br /&gt;
  /// Returns the proper substr() SQL text used to extract substrings from DB.&lt;br /&gt;
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.&lt;br /&gt;
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2int($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.&lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2real($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_compare_text($fieldname, $numchars=32) &lt;br /&gt;
  /// Returns the SQL text to be used to compare one TEXT (clob) column.&lt;br /&gt;
  /// with one VARCHAR column.&lt;br /&gt;
o $DB-&amp;gt;sql_order_by_text($fieldname, $numchars=32)&lt;br /&gt;
  /// Returns the SQL text to be used to order by one TEXT (clob) column.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_concat()&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed.&lt;br /&gt;
o $DB-&amp;gt;sql_concat_join($separator=&amp;quot;&#039; &#039;&amp;quot;, $elements=array())&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.&lt;br /&gt;
o $DB-&amp;gt;sql_fullname($first=&#039;firstname&#039;, $last=&#039;lastname&#039;)&lt;br /&gt;
  /// Returns the proper SQL to concatenate $firstname and $lastname.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_isempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is empty.&lt;br /&gt;
o $DB-&amp;gt;sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is not empty.&lt;br /&gt;
o $DB-&amp;gt;sql_empty()&lt;br /&gt;
  /// Returns the empty string char used by every supported DB.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;br /&gt;
* [[Development:DML drivers|DML drivers]]: Database drivers for new DML layer&lt;br /&gt;
* [[Development:DML functions - pre 2.0|DML functions - pre 2.0]]: &#039;&#039;&#039;(deprecated!)&#039;&#039;&#039; For information valid before Moodle 2.0.&lt;br /&gt;
* [[Development:DDL functions|DDL functions]]: Where all the functions used to handle DB objects ([[wikipedia:Data_Definition_Language|DDL]]) are defined.&lt;br /&gt;
* [[Development:DB layer 2.0 examples|DB layer 2.0 examples]]: To see some code examples using various DML functions.&lt;br /&gt;
* [[Development:DB layer 2.0 migration docs|DB layer 2.0 migration docs]]: Information about how to modify your code to work with the new Moodle 2.0 DB layer.&lt;br /&gt;
* [[Development:DTL functions|DTL functions]]: Exporting, importing and moving of data stored in SQL databases&lt;br /&gt;
&lt;br /&gt;
[[Category:DB]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:DML_functions&amp;diff=78611</id>
		<title>Development:DML functions</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:DML_functions&amp;diff=78611"/>
		<updated>2010-12-03T06:28:37Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Using Recordsets */  clearer english&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}This page describes the functions available to access data in the Moodle database. You should &#039;&#039;&#039;exclusively&#039;&#039;&#039; use these functions in order to retrieve or modify database content because these functions provide a high level of abstraction and guarantee that your database manipulation will work against different RDBMSes.&lt;br /&gt;
&lt;br /&gt;
Where possible, tricks and examples will be documented here in order to make developers&#039; lives a bit easier. Of course, feel free to clarify, complete and add more information to  this documentation. It will be welcome, absolutely!&lt;br /&gt;
&lt;br /&gt;
== Main info ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; All the functions shown on this page are for use in &#039;&#039;&#039;Moodle 2.0 upwards&#039;&#039;&#039;, where we changed the [[Development:DB layer 2.0|DB layer]] to support some new features. If you need information for previous Moodle version, take a look to the [[Development:DML functions - pre 2.0|DML functions - pre 2.0]] page. For a detailed reference of changes, see the [[Development:DB layer 2.0 migration docs|migration docs]].&lt;br /&gt;
&lt;br /&gt;
* All the function calls on this page are public methods of the $DB global object, so you&#039;ll need to &amp;quot;import&amp;quot; it within your functions (not needed in global scripts) with one simple:&lt;br /&gt;
&amp;lt;code php&amp;gt;global $DB;&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $table parameters in the functions are meant to be the table name &#039;&#039;without&#039;&#039; prefixes.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;&#039;1&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* When using the xxx_sql() functions, table names must be enclosed between curly braces.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE id = ?&#039;, array(1));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $conditions parameters in the functions are arrays of fieldname=&amp;gt;fieldvalue elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $params parameters in the functions are arrays of values used to fill placeholders in SQL statements. Both the question mark and named placeholders can be used. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039; even if the value passed is the same.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// Question mark placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = ? AND lastname = ?&#039;, &lt;br /&gt;
                       array(&#039;Martin&#039;, &#039;Dougiamas&#039;));&lt;br /&gt;
&lt;br /&gt;
/// Named placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = :firstname AND lastname = :lastname&#039;,&lt;br /&gt;
                       array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The functions ==&lt;br /&gt;
&lt;br /&gt;
===Seeing how many records match a given criteria===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;count_records($table, array $conditions=null) &lt;br /&gt;
  /// Count the records in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;count_records_select($table, $select, array $params=null, $countitem=&amp;quot;COUNT(&#039;x&#039;)&amp;quot;) &lt;br /&gt;
  /// Count the records in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;count_records_sql($sql, array $params=null) &lt;br /&gt;
  /// Get the result of a SQL SELECT COUNT(...) query.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Seeing if one record exists===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;record_exists($table, array $conditions=null) &lt;br /&gt;
  /// Test whether a record exists in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;record_exists_select($table, $select, array $params=null) &lt;br /&gt;
  /// Test whether any records exists in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;record_exists_sql($sql, array $params=null) &lt;br /&gt;
  /// Test whether a SQL SELECT statement returns any records.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a single record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_record($table, array $conditions, $fields=&#039;*&#039;, $ignoremultiple=false) &lt;br /&gt;
  /// Get a single database record as an object where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_record_select($table, $select, array $params=null, $fields=&#039;*&#039;, $ignoremultiple=false)&lt;br /&gt;
  /// Get a single database record as an object which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_record_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single database record as an object using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting an array of records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get a number of records as an array of objects using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_records_menu($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select_menu($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_records_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from one record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_field($table, $return, array $conditions)&lt;br /&gt;
  /// Get a single field value from a table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_field_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Get a single field value from a table record which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_field_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single field value (first field) using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from various records===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_sql($sql, array $params=null)&lt;br /&gt;
  /// Selects records and return values (first field) as an array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting a particular field in the database===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;set_field($table, $newfield, $newvalue, array $conditions=null)&lt;br /&gt;
  /// Set a single field in every table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;set_field_select($table, $newfield, $newvalue, $select, array $params=null)&lt;br /&gt;
  /// Set a single field in every table record which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Deleting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;delete_records($table, array $conditions=null) &lt;br /&gt;
  /// Delete the records from a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;delete_records_select($table, $select, array $params=null)&lt;br /&gt;
  /// Delete one or more records from a table which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inserting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;insert_record($table, $dataobject, $returnid=true, $bulk=false) &lt;br /&gt;
  /// Insert a record into a table and return the &amp;quot;id&amp;quot; field if required.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Updating Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;update_record($table, $dataobject, $bulk=false)&lt;br /&gt;
  /// Update a record in a table.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Recordsets===&lt;br /&gt;
&lt;br /&gt;
Where the number of records to be retrieved from DB is high, the &#039;&#039;&#039;get_records_xxx()&#039;&#039;&#039; functions above are far from optimal, because they use to load all the records in memory at the same time. Under those circumstances, it&#039;s highly recommended to use this &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions instead, which uses one nice mechanism to iterate over all the target records and save a lot of memory.&lt;br /&gt;
&lt;br /&gt;
Only one thing is &#039;&#039;&#039;absolutely important&#039;&#039;&#039;: Don&#039;t forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).&lt;br /&gt;
&lt;br /&gt;
Here is the general way to iterate over records using the &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($rs = $DB-&amp;gt;get_recordset(....) {&lt;br /&gt;
    foreach ($rs as $record) {&lt;br /&gt;
     /// Do whatever you want with this record&lt;br /&gt;
    }&lt;br /&gt;
    $rs-&amp;gt;close(); /// Don&#039;t forget to close the recordset!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And this is the list of available functions (100% paired with the get_records_xxx() above):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_recordset($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);&lt;br /&gt;
  /// Get a number of records as a moodle_recordset using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_recordset_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where one field matches one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delegated transactions===&lt;br /&gt;
&lt;br /&gt;
* Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).&lt;br /&gt;
* Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.&lt;br /&gt;
* Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.&lt;br /&gt;
* Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.&lt;br /&gt;
&lt;br /&gt;
A transaction is started by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finished by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually a transaction is rolled back when an exception is thrown. &amp;lt;code&amp;gt;$transaction-&amp;gt;rollback($ex);&amp;lt;/code&amp;gt; must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.&lt;br /&gt;
&lt;br /&gt;
See more details in [[Development:DB layer 2.0 delegated transactions]] or MDL-20625.&lt;br /&gt;
&lt;br /&gt;
===Helper Functions===&lt;br /&gt;
&lt;br /&gt;
In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we&#039;ll avoid conditional queries here and there and have those &amp;quot;incompatibilities&amp;quot; fixed once and for ever.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;sql_bitand($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise AND &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitnot($int1) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise NOT &lt;br /&gt;
  /// operation with 1 integer.&lt;br /&gt;
o $DB-&amp;gt;sql_bitor($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise OR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitxor($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise XOR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_null_from_clause()&lt;br /&gt;
  /// Returns the FROM clause required by some DBs in all SELECT statements.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_ceil($fieldname)&lt;br /&gt;
  /// Returns the correct CEIL expression applied to fieldname.&lt;br /&gt;
o $DB-&amp;gt;sql_ilike()&lt;br /&gt;
  /// Returns the proper SQL to do LIKE in a case-insensitive way.&lt;br /&gt;
o $DB-&amp;gt;sql_length($fieldname)&lt;br /&gt;
  /// Returns the SQL text to be used to calculate the length in characters of one expression.&lt;br /&gt;
o $DB-&amp;gt;sql_modulo($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to calculate module - remainder after division&lt;br /&gt;
o $DB-&amp;gt;sql_position($needle, $haystack)&lt;br /&gt;
  /// Returns the SQL for returning searching one string for the location of another.&lt;br /&gt;
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.&lt;br /&gt;
o $DB-&amp;gt;sql_substr($expr, $start, $length=false)&lt;br /&gt;
  /// Returns the proper substr() SQL text used to extract substrings from DB.&lt;br /&gt;
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.&lt;br /&gt;
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2int($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.&lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2real($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_compare_text($fieldname, $numchars=32) &lt;br /&gt;
  /// Returns the SQL text to be used to compare one TEXT (clob) column.&lt;br /&gt;
  /// with one VARCHAR column.&lt;br /&gt;
o $DB-&amp;gt;sql_order_by_text($fieldname, $numchars=32)&lt;br /&gt;
  /// Returns the SQL text to be used to order by one TEXT (clob) column.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_concat()&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed.&lt;br /&gt;
o $DB-&amp;gt;sql_concat_join($separator=&amp;quot;&#039; &#039;&amp;quot;, $elements=array())&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.&lt;br /&gt;
o $DB-&amp;gt;sql_fullname($first=&#039;firstname&#039;, $last=&#039;lastname&#039;)&lt;br /&gt;
  /// Returns the proper SQL to concatenate $firstname and $lastname.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_isempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is empty.&lt;br /&gt;
o $DB-&amp;gt;sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is not empty.&lt;br /&gt;
o $DB-&amp;gt;sql_empty()&lt;br /&gt;
  /// Returns the empty string char used by every supported DB.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;br /&gt;
* [[Development:DML drivers|DML drivers]]: Database drivers for new DML layer&lt;br /&gt;
* [[Development:DML functions - pre 2.0|DML functions - pre 2.0]]: &#039;&#039;&#039;(deprecated!)&#039;&#039;&#039; For information valid before Moodle 2.0.&lt;br /&gt;
* [[Development:DDL functions|DDL functions]]: Where all the functions used to handle DB objects ([[wikipedia:Data_Definition_Language|DDL]]) are defined.&lt;br /&gt;
* [[Development:DB layer 2.0 examples|DB layer 2.0 examples]]: To see some code examples using various DML functions.&lt;br /&gt;
* [[Development:DB layer 2.0 migration docs|DB layer 2.0 migration docs]]: Information about how to modify your code to work with the new Moodle 2.0 DB layer.&lt;br /&gt;
* [[Development:DTL functions|DTL functions]]: Exporting, importing and moving of data stored in SQL databases&lt;br /&gt;
&lt;br /&gt;
[[Category:DB]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:DML_functions&amp;diff=78610</id>
		<title>Development:DML functions</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:DML_functions&amp;diff=78610"/>
		<updated>2010-12-03T06:24:10Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Getting a single record */  get_record_sql syntax was incorrect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}This page describes the functions available to access data in the Moodle database. You should &#039;&#039;&#039;exclusively&#039;&#039;&#039; use these functions in order to retrieve or modify database content because these functions provide a high level of abstraction and guarantee that your database manipulation will work against different RDBMSes.&lt;br /&gt;
&lt;br /&gt;
Where possible, tricks and examples will be documented here in order to make developers&#039; lives a bit easier. Of course, feel free to clarify, complete and add more information to  this documentation. It will be welcome, absolutely!&lt;br /&gt;
&lt;br /&gt;
== Main info ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; All the functions shown on this page are for use in &#039;&#039;&#039;Moodle 2.0 upwards&#039;&#039;&#039;, where we changed the [[Development:DB layer 2.0|DB layer]] to support some new features. If you need information for previous Moodle version, take a look to the [[Development:DML functions - pre 2.0|DML functions - pre 2.0]] page. For a detailed reference of changes, see the [[Development:DB layer 2.0 migration docs|migration docs]].&lt;br /&gt;
&lt;br /&gt;
* All the function calls on this page are public methods of the $DB global object, so you&#039;ll need to &amp;quot;import&amp;quot; it within your functions (not needed in global scripts) with one simple:&lt;br /&gt;
&amp;lt;code php&amp;gt;global $DB;&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $table parameters in the functions are meant to be the table name &#039;&#039;without&#039;&#039; prefixes.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;&#039;1&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* When using the xxx_sql() functions, table names must be enclosed between curly braces.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE id = ?&#039;, array(1));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $conditions parameters in the functions are arrays of fieldname=&amp;gt;fieldvalue elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $params parameters in the functions are arrays of values used to fill placeholders in SQL statements. Both the question mark and named placeholders can be used. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039; even if the value passed is the same.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// Question mark placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = ? AND lastname = ?&#039;, &lt;br /&gt;
                       array(&#039;Martin&#039;, &#039;Dougiamas&#039;));&lt;br /&gt;
&lt;br /&gt;
/// Named placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = :firstname AND lastname = :lastname&#039;,&lt;br /&gt;
                       array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The functions ==&lt;br /&gt;
&lt;br /&gt;
===Seeing how many records match a given criteria===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;count_records($table, array $conditions=null) &lt;br /&gt;
  /// Count the records in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;count_records_select($table, $select, array $params=null, $countitem=&amp;quot;COUNT(&#039;x&#039;)&amp;quot;) &lt;br /&gt;
  /// Count the records in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;count_records_sql($sql, array $params=null) &lt;br /&gt;
  /// Get the result of a SQL SELECT COUNT(...) query.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Seeing if one record exists===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;record_exists($table, array $conditions=null) &lt;br /&gt;
  /// Test whether a record exists in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;record_exists_select($table, $select, array $params=null) &lt;br /&gt;
  /// Test whether any records exists in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;record_exists_sql($sql, array $params=null) &lt;br /&gt;
  /// Test whether a SQL SELECT statement returns any records.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a single record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_record($table, array $conditions, $fields=&#039;*&#039;, $ignoremultiple=false) &lt;br /&gt;
  /// Get a single database record as an object where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_record_select($table, $select, array $params=null, $fields=&#039;*&#039;, $ignoremultiple=false)&lt;br /&gt;
  /// Get a single database record as an object which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_record_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single database record as an object using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting an array of records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get a number of records as an array of objects using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_records_menu($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select_menu($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_records_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from one record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_field($table, $return, array $conditions)&lt;br /&gt;
  /// Get a single field value from a table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_field_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Get a single field value from a table record which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_field_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single field value (first field) using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from various records===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_sql($sql, array $params=null)&lt;br /&gt;
  /// Selects records and return values (first field) as an array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting a particular field in the database===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;set_field($table, $newfield, $newvalue, array $conditions=null)&lt;br /&gt;
  /// Set a single field in every table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;set_field_select($table, $newfield, $newvalue, $select, array $params=null)&lt;br /&gt;
  /// Set a single field in every table record which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Deleting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;delete_records($table, array $conditions=null) &lt;br /&gt;
  /// Delete the records from a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;delete_records_select($table, $select, array $params=null)&lt;br /&gt;
  /// Delete one or more records from a table which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inserting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;insert_record($table, $dataobject, $returnid=true, $bulk=false) &lt;br /&gt;
  /// Insert a record into a table and return the &amp;quot;id&amp;quot; field if required.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Updating Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;update_record($table, $dataobject, $bulk=false)&lt;br /&gt;
  /// Update a record in a table.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Recordsets===&lt;br /&gt;
&lt;br /&gt;
While the number of records to be retrieved from DB is high, the &#039;&#039;&#039;get_records_xxx()&#039;&#039;&#039; functions above are far from optimal, because they use to load all the records in memory at the same time. Under those circumstances, it&#039;s highly recommended to use this &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions instead, which uses one nice mechanism to iterate over all the target records and save a lot of memory.&lt;br /&gt;
&lt;br /&gt;
Only one thing is &#039;&#039;&#039;absolutely important&#039;&#039;&#039;: Don&#039;t forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).&lt;br /&gt;
&lt;br /&gt;
Here is the general way to iterate over records using the &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($rs = $DB-&amp;gt;get_recordset(....) {&lt;br /&gt;
    foreach ($rs as $record) {&lt;br /&gt;
     /// Do whatever you want with this record&lt;br /&gt;
    }&lt;br /&gt;
    $rs-&amp;gt;close(); /// Don&#039;t forget to close the recordset!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And this is the list of available functions (100% paired with the get_records_xxx() above):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_recordset($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);&lt;br /&gt;
  /// Get a number of records as a moodle_recordset using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_recordset_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where one field matches one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delegated transactions===&lt;br /&gt;
&lt;br /&gt;
* Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).&lt;br /&gt;
* Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.&lt;br /&gt;
* Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.&lt;br /&gt;
* Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.&lt;br /&gt;
&lt;br /&gt;
A transaction is started by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finished by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually a transaction is rolled back when an exception is thrown. &amp;lt;code&amp;gt;$transaction-&amp;gt;rollback($ex);&amp;lt;/code&amp;gt; must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.&lt;br /&gt;
&lt;br /&gt;
See more details in [[Development:DB layer 2.0 delegated transactions]] or MDL-20625.&lt;br /&gt;
&lt;br /&gt;
===Helper Functions===&lt;br /&gt;
&lt;br /&gt;
In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we&#039;ll avoid conditional queries here and there and have those &amp;quot;incompatibilities&amp;quot; fixed once and for ever.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;sql_bitand($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise AND &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitnot($int1) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise NOT &lt;br /&gt;
  /// operation with 1 integer.&lt;br /&gt;
o $DB-&amp;gt;sql_bitor($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise OR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitxor($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise XOR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_null_from_clause()&lt;br /&gt;
  /// Returns the FROM clause required by some DBs in all SELECT statements.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_ceil($fieldname)&lt;br /&gt;
  /// Returns the correct CEIL expression applied to fieldname.&lt;br /&gt;
o $DB-&amp;gt;sql_ilike()&lt;br /&gt;
  /// Returns the proper SQL to do LIKE in a case-insensitive way.&lt;br /&gt;
o $DB-&amp;gt;sql_length($fieldname)&lt;br /&gt;
  /// Returns the SQL text to be used to calculate the length in characters of one expression.&lt;br /&gt;
o $DB-&amp;gt;sql_modulo($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to calculate module - remainder after division&lt;br /&gt;
o $DB-&amp;gt;sql_position($needle, $haystack)&lt;br /&gt;
  /// Returns the SQL for returning searching one string for the location of another.&lt;br /&gt;
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.&lt;br /&gt;
o $DB-&amp;gt;sql_substr($expr, $start, $length=false)&lt;br /&gt;
  /// Returns the proper substr() SQL text used to extract substrings from DB.&lt;br /&gt;
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.&lt;br /&gt;
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2int($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.&lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2real($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_compare_text($fieldname, $numchars=32) &lt;br /&gt;
  /// Returns the SQL text to be used to compare one TEXT (clob) column.&lt;br /&gt;
  /// with one VARCHAR column.&lt;br /&gt;
o $DB-&amp;gt;sql_order_by_text($fieldname, $numchars=32)&lt;br /&gt;
  /// Returns the SQL text to be used to order by one TEXT (clob) column.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_concat()&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed.&lt;br /&gt;
o $DB-&amp;gt;sql_concat_join($separator=&amp;quot;&#039; &#039;&amp;quot;, $elements=array())&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.&lt;br /&gt;
o $DB-&amp;gt;sql_fullname($first=&#039;firstname&#039;, $last=&#039;lastname&#039;)&lt;br /&gt;
  /// Returns the proper SQL to concatenate $firstname and $lastname.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_isempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is empty.&lt;br /&gt;
o $DB-&amp;gt;sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is not empty.&lt;br /&gt;
o $DB-&amp;gt;sql_empty()&lt;br /&gt;
  /// Returns the empty string char used by every supported DB.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;br /&gt;
* [[Development:DML drivers|DML drivers]]: Database drivers for new DML layer&lt;br /&gt;
* [[Development:DML functions - pre 2.0|DML functions - pre 2.0]]: &#039;&#039;&#039;(deprecated!)&#039;&#039;&#039; For information valid before Moodle 2.0.&lt;br /&gt;
* [[Development:DDL functions|DDL functions]]: Where all the functions used to handle DB objects ([[wikipedia:Data_Definition_Language|DDL]]) are defined.&lt;br /&gt;
* [[Development:DB layer 2.0 examples|DB layer 2.0 examples]]: To see some code examples using various DML functions.&lt;br /&gt;
* [[Development:DB layer 2.0 migration docs|DB layer 2.0 migration docs]]: Information about how to modify your code to work with the new Moodle 2.0 DB layer.&lt;br /&gt;
* [[Development:DTL functions|DTL functions]]: Exporting, importing and moving of data stored in SQL databases&lt;br /&gt;
&lt;br /&gt;
[[Category:DB]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:DML_functions&amp;diff=78609</id>
		<title>Development:DML functions</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:DML_functions&amp;diff=78609"/>
		<updated>2010-12-03T06:22:39Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Getting a single record */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}This page describes the functions available to access data in the Moodle database. You should &#039;&#039;&#039;exclusively&#039;&#039;&#039; use these functions in order to retrieve or modify database content because these functions provide a high level of abstraction and guarantee that your database manipulation will work against different RDBMSes.&lt;br /&gt;
&lt;br /&gt;
Where possible, tricks and examples will be documented here in order to make developers&#039; lives a bit easier. Of course, feel free to clarify, complete and add more information to  this documentation. It will be welcome, absolutely!&lt;br /&gt;
&lt;br /&gt;
== Main info ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; All the functions shown on this page are for use in &#039;&#039;&#039;Moodle 2.0 upwards&#039;&#039;&#039;, where we changed the [[Development:DB layer 2.0|DB layer]] to support some new features. If you need information for previous Moodle version, take a look to the [[Development:DML functions - pre 2.0|DML functions - pre 2.0]] page. For a detailed reference of changes, see the [[Development:DB layer 2.0 migration docs|migration docs]].&lt;br /&gt;
&lt;br /&gt;
* All the function calls on this page are public methods of the $DB global object, so you&#039;ll need to &amp;quot;import&amp;quot; it within your functions (not needed in global scripts) with one simple:&lt;br /&gt;
&amp;lt;code php&amp;gt;global $DB;&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $table parameters in the functions are meant to be the table name &#039;&#039;without&#039;&#039; prefixes.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;&#039;1&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* When using the xxx_sql() functions, table names must be enclosed between curly braces.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE id = ?&#039;, array(1));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $conditions parameters in the functions are arrays of fieldname=&amp;gt;fieldvalue elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $params parameters in the functions are arrays of values used to fill placeholders in SQL statements. Both the question mark and named placeholders can be used. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039; even if the value passed is the same.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// Question mark placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = ? AND lastname = ?&#039;, &lt;br /&gt;
                       array(&#039;Martin&#039;, &#039;Dougiamas&#039;));&lt;br /&gt;
&lt;br /&gt;
/// Named placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = :firstname AND lastname = :lastname&#039;,&lt;br /&gt;
                       array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The functions ==&lt;br /&gt;
&lt;br /&gt;
===Seeing how many records match a given criteria===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;count_records($table, array $conditions=null) &lt;br /&gt;
  /// Count the records in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;count_records_select($table, $select, array $params=null, $countitem=&amp;quot;COUNT(&#039;x&#039;)&amp;quot;) &lt;br /&gt;
  /// Count the records in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;count_records_sql($sql, array $params=null) &lt;br /&gt;
  /// Get the result of a SQL SELECT COUNT(...) query.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Seeing if one record exists===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;record_exists($table, array $conditions=null) &lt;br /&gt;
  /// Test whether a record exists in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;record_exists_select($table, $select, array $params=null) &lt;br /&gt;
  /// Test whether any records exists in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;record_exists_sql($sql, array $params=null) &lt;br /&gt;
  /// Test whether a SQL SELECT statement returns any records.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a single record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_record($table, array $conditions, $fields=&#039;*&#039;, $ignoremultiple=false) &lt;br /&gt;
  /// Get a single database record as an object where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_record_select($table, $select, array $params=null, $fields=&#039;*&#039;, $ignoremultiple=false)&lt;br /&gt;
  /// Get a single database record as an object which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_record_sql($table, $sql, array $params=null)&lt;br /&gt;
  /// Get a single database record as an object using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting an array of records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get a number of records as an array of objects using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_records_menu($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select_menu($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_records_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from one record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_field($table, $return, array $conditions)&lt;br /&gt;
  /// Get a single field value from a table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_field_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Get a single field value from a table record which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_field_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single field value (first field) using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from various records===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_sql($sql, array $params=null)&lt;br /&gt;
  /// Selects records and return values (first field) as an array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting a particular field in the database===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;set_field($table, $newfield, $newvalue, array $conditions=null)&lt;br /&gt;
  /// Set a single field in every table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;set_field_select($table, $newfield, $newvalue, $select, array $params=null)&lt;br /&gt;
  /// Set a single field in every table record which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Deleting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;delete_records($table, array $conditions=null) &lt;br /&gt;
  /// Delete the records from a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;delete_records_select($table, $select, array $params=null)&lt;br /&gt;
  /// Delete one or more records from a table which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inserting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;insert_record($table, $dataobject, $returnid=true, $bulk=false) &lt;br /&gt;
  /// Insert a record into a table and return the &amp;quot;id&amp;quot; field if required.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Updating Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;update_record($table, $dataobject, $bulk=false)&lt;br /&gt;
  /// Update a record in a table.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Recordsets===&lt;br /&gt;
&lt;br /&gt;
While the number of records to be retrieved from DB is high, the &#039;&#039;&#039;get_records_xxx()&#039;&#039;&#039; functions above are far from optimal, because they use to load all the records in memory at the same time. Under those circumstances, it&#039;s highly recommended to use this &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions instead, which uses one nice mechanism to iterate over all the target records and save a lot of memory.&lt;br /&gt;
&lt;br /&gt;
Only one thing is &#039;&#039;&#039;absolutely important&#039;&#039;&#039;: Don&#039;t forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).&lt;br /&gt;
&lt;br /&gt;
Here is the general way to iterate over records using the &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
if ($rs = $DB-&amp;gt;get_recordset(....) {&lt;br /&gt;
    foreach ($rs as $record) {&lt;br /&gt;
     /// Do whatever you want with this record&lt;br /&gt;
    }&lt;br /&gt;
    $rs-&amp;gt;close(); /// Don&#039;t forget to close the recordset!&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And this is the list of available functions (100% paired with the get_records_xxx() above):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_recordset($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);&lt;br /&gt;
  /// Get a number of records as a moodle_recordset using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_recordset_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where one field matches one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delegated transactions===&lt;br /&gt;
&lt;br /&gt;
* Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).&lt;br /&gt;
* Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.&lt;br /&gt;
* Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.&lt;br /&gt;
* Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.&lt;br /&gt;
&lt;br /&gt;
A transaction is started by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finished by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually a transaction is rolled back when an exception is thrown. &amp;lt;code&amp;gt;$transaction-&amp;gt;rollback($ex);&amp;lt;/code&amp;gt; must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.&lt;br /&gt;
&lt;br /&gt;
See more details in [[Development:DB layer 2.0 delegated transactions]] or MDL-20625.&lt;br /&gt;
&lt;br /&gt;
===Helper Functions===&lt;br /&gt;
&lt;br /&gt;
In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we&#039;ll avoid conditional queries here and there and have those &amp;quot;incompatibilities&amp;quot; fixed once and for ever.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;sql_bitand($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise AND &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitnot($int1) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise NOT &lt;br /&gt;
  /// operation with 1 integer.&lt;br /&gt;
o $DB-&amp;gt;sql_bitor($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise OR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitxor($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise XOR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_null_from_clause()&lt;br /&gt;
  /// Returns the FROM clause required by some DBs in all SELECT statements.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_ceil($fieldname)&lt;br /&gt;
  /// Returns the correct CEIL expression applied to fieldname.&lt;br /&gt;
o $DB-&amp;gt;sql_ilike()&lt;br /&gt;
  /// Returns the proper SQL to do LIKE in a case-insensitive way.&lt;br /&gt;
o $DB-&amp;gt;sql_length($fieldname)&lt;br /&gt;
  /// Returns the SQL text to be used to calculate the length in characters of one expression.&lt;br /&gt;
o $DB-&amp;gt;sql_modulo($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to calculate module - remainder after division&lt;br /&gt;
o $DB-&amp;gt;sql_position($needle, $haystack)&lt;br /&gt;
  /// Returns the SQL for returning searching one string for the location of another.&lt;br /&gt;
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.&lt;br /&gt;
o $DB-&amp;gt;sql_substr($expr, $start, $length=false)&lt;br /&gt;
  /// Returns the proper substr() SQL text used to extract substrings from DB.&lt;br /&gt;
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.&lt;br /&gt;
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2int($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.&lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2real($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_compare_text($fieldname, $numchars=32) &lt;br /&gt;
  /// Returns the SQL text to be used to compare one TEXT (clob) column.&lt;br /&gt;
  /// with one VARCHAR column.&lt;br /&gt;
o $DB-&amp;gt;sql_order_by_text($fieldname, $numchars=32)&lt;br /&gt;
  /// Returns the SQL text to be used to order by one TEXT (clob) column.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_concat()&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed.&lt;br /&gt;
o $DB-&amp;gt;sql_concat_join($separator=&amp;quot;&#039; &#039;&amp;quot;, $elements=array())&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.&lt;br /&gt;
o $DB-&amp;gt;sql_fullname($first=&#039;firstname&#039;, $last=&#039;lastname&#039;)&lt;br /&gt;
  /// Returns the proper SQL to concatenate $firstname and $lastname.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_isempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is empty.&lt;br /&gt;
o $DB-&amp;gt;sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is not empty.&lt;br /&gt;
o $DB-&amp;gt;sql_empty()&lt;br /&gt;
  /// Returns the empty string char used by every supported DB.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Development:DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;br /&gt;
* [[Development:DML drivers|DML drivers]]: Database drivers for new DML layer&lt;br /&gt;
* [[Development:DML functions - pre 2.0|DML functions - pre 2.0]]: &#039;&#039;&#039;(deprecated!)&#039;&#039;&#039; For information valid before Moodle 2.0.&lt;br /&gt;
* [[Development:DDL functions|DDL functions]]: Where all the functions used to handle DB objects ([[wikipedia:Data_Definition_Language|DDL]]) are defined.&lt;br /&gt;
* [[Development:DB layer 2.0 examples|DB layer 2.0 examples]]: To see some code examples using various DML functions.&lt;br /&gt;
* [[Development:DB layer 2.0 migration docs|DB layer 2.0 migration docs]]: Information about how to modify your code to work with the new Moodle 2.0 DB layer.&lt;br /&gt;
* [[Development:DTL functions|DTL functions]]: Exporting, importing and moving of data stored in SQL databases&lt;br /&gt;
&lt;br /&gt;
[[Category:DB]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=User:Bruno_Vernier&amp;diff=78533</id>
		<title>User:Bruno Vernier</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=User:Bruno_Vernier&amp;diff=78533"/>
		<updated>2010-11-30T18:03:45Z</updated>

		<summary type="html">&lt;p&gt;Bruno: New page: teacher in Vancouver, British Columbia , Canada&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;teacher in Vancouver, British Columbia , Canada&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Calculated_question_improvements&amp;diff=52128</id>
		<title>Development:Calculated question improvements</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Calculated_question_improvements&amp;diff=52128"/>
		<updated>2009-03-06T06:35:36Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Calculated question dev docs}}&lt;br /&gt;
I will use this page to describe the various improvements I am developping related to the calculated questions.&lt;br /&gt;
The code of 1.8 with the QuickForm HTML structure offer a considerable improvement in the interface user over the preceeding versions.&lt;br /&gt;
However at Université du Québec à Montréal, we moved from WebCT 4 to Moodle 1.6.3 in spring 2007 and will maintian this version for the next academic year. So exceptionnally, I will port down to 1.6 most of the improvements being made to the Moodle HEAD version.&lt;br /&gt;
&lt;br /&gt;
The following content of this page will be updated soon. &lt;br /&gt;
&lt;br /&gt;
==Working progress==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;Improvements&#039;&#039;&#039;&lt;br /&gt;
!HEAD&lt;br /&gt;
!1.8&lt;br /&gt;
!1.7&lt;br /&gt;
!1.6&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Moodle XML Import , Export&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
WebCT Import&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Saving question at each step&lt;br /&gt;
*remove use of $SESSION to store parameters&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Allow save as new question&lt;br /&gt;
*saving also the datasets and data items&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|TO DO&lt;br /&gt;
|TO DO&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Allow saving of multiple answers&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Allow edition of multiple answers&lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|READY&lt;br /&gt;
|READY&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Validation of user data before saving&lt;br /&gt;
*For QuickForm redisplay with red text&lt;br /&gt;
*Older version use notice when saving question-&amp;gt;options so there is a return to editquestion &lt;br /&gt;
|Done&lt;br /&gt;
|Done&lt;br /&gt;
|TESTING&lt;br /&gt;
|TESTING&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Allow addition and removal of dataitems by steps &lt;br /&gt;
of 5,10,15, etc&lt;br /&gt;
|TESTING&lt;br /&gt;
|TESTING&lt;br /&gt;
|TESTING&lt;br /&gt;
|TESTING&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
larger field for formula &lt;br /&gt;
&lt;br /&gt;
|TO DO&lt;br /&gt;
|TO DO&lt;br /&gt;
|TO DO&lt;br /&gt;
|TO DO&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
subquestions &lt;br /&gt;
&lt;br /&gt;
|TO DO&lt;br /&gt;
|TO DO&lt;br /&gt;
|TO DO&lt;br /&gt;
|TO DO&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
Possible steps are :&lt;br /&gt;
* TO DO&lt;br /&gt;
* CODED&lt;br /&gt;
* TESTING&lt;br /&gt;
* READY&lt;br /&gt;
* Done i.e CVS and merged&lt;br /&gt;
07/05/23&lt;br /&gt;
&lt;br /&gt;
==Foolproof and clearer creation process==&lt;br /&gt;
Actually the creation or edition of calculated question is a three steps process ( 3 different pages) where the user can make errors that he cannot readily recuperate.&lt;br /&gt;
* Identify the steps and renaming the save changes or continue buttons.&lt;br /&gt;
* Using javascript to correct for errors or non valid values in each steps before going to the next step.[[Calculated question js validating forms]]&lt;br /&gt;
* Creating buttons to access the previous steps for corrections.&lt;br /&gt;
* Creating a table showing the variables used by the other calculated questions in the same category.&lt;br /&gt;
* Allowing to create or delete data items by 1, 10, 20 etc in one step.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Moving calculated questions to another category==&lt;br /&gt;
Actually the code (Moodle 1.7) for moving questions to another category means simply to change the category field in the database question record.&lt;br /&gt;
Although this is correct for most questions types, this is not the right way to do it with calculated questions because the same category field is also used in the datasets records.&lt;br /&gt;
A dataset can be shared by questions of the same category. &lt;br /&gt;
To search if there is a already sharable dataset in a category, the parameters used are the dataset-&amp;gt;name and the dataset-&amp;gt;category.&lt;br /&gt;
The possibilities are&lt;br /&gt;
#All the dataset used by the question to be moved are reserved for this question (dataset-&amp;gt;category=0). The calculated question can be moved to another category &#039;&#039;&#039;without restriction&#039;&#039;&#039;.This is the actual implementation.&lt;br /&gt;
#At least one of the dataset used by the question to be moved is sharable (dataset-&amp;gt;category = actual question category)&lt;br /&gt;
## If &#039;&#039;&#039;all&#039;&#039;&#039; the sharable dataset are &#039;&#039;&#039;only&#039;&#039;&#039; used by the question to be moved, the calculated question can be selected to move to the other category .&lt;br /&gt;
## If &#039;&#039;&#039;all&#039;&#039;&#039; the questions that are selected to be moved, and &#039;&#039;&#039;all&#039;&#039;&#039; the sharable datasets are only used by these questions to be moved, this set of questions can be selected to move to the other category .&lt;br /&gt;
## In the case that there are questions not selected that could used a sharable dataset, this dataset cannot be moved in the another category.&lt;br /&gt;
###Notify the user that another questions in the initial category share a parameter with this category.&lt;br /&gt;
####The user can choose to cancel the move and select all the other questions (Case 2.2).&lt;br /&gt;
####The user can choose to keep the question in the selected questions to be moved. In this case, the dataset should be duplicated when moving the another category.&lt;br /&gt;
===Duplicate datasets?===&lt;br /&gt;
If a similar sharable dataset already exists in the moveto category ( identical dataset-&amp;gt;name and dataset-&amp;gt;category = movetocategory).&lt;br /&gt;
Notify the user and giving information on the&lt;br /&gt;
#sharable dataset in selected questions to be moved &lt;br /&gt;
#already existing sharable datasets in the move_to_category.&lt;br /&gt;
The user should be able to select which dataset will be used in move_to_category.&lt;br /&gt;
&lt;br /&gt;
To implement these choices we need to add new functions in default questiontype class.&lt;br /&gt;
===function movable_to_category(&amp;amp;$questions,$categoryid)===&lt;br /&gt;
 default return null &lt;br /&gt;
 $questions contain all the question records data for all the selected questions &lt;br /&gt;
 so that qtype implementation could test &amp;lt;br&amp;gt;if the selected questions satisfy option 2.2&lt;br /&gt;
 a $questions-&amp;gt;notify can be added to be used by showbank.php and move_to_category.&lt;br /&gt;
===function move_to_category($question,$tocategory)=== &lt;br /&gt;
the default implementation should something like the actual code&lt;br /&gt;
  {&lt;br /&gt;
           if (!set_field(&#039;question&#039;, &#039;category&#039;, $tocategory-&amp;gt;id, &#039;id&#039;, $question-&amp;gt;id)) {&lt;br /&gt;
                            error(&#039;Could not update category field&#039;);&lt;br /&gt;
                        }&lt;br /&gt;
        return null;&lt;br /&gt;
    }&lt;br /&gt;
the calculated question implementation should be able to duplicate the datasets in the new category&lt;br /&gt;
&lt;br /&gt;
==Improvements in general question editing interface==&lt;br /&gt;
*Showing the text of the questions&lt;br /&gt;
&lt;br /&gt;
==Creation of a short (simple) calculated question==&lt;br /&gt;
The actual calculated question allows for calculated params that can be shared by different problems.&lt;br /&gt;
This could lead to a somewhat cloze used of calculated questions.However the questions cannot migrate individually to another category.&lt;br /&gt;
A short calculated question that just allow for calculated parameters reserved for this question will allow use of this question in drag and drop cloze lesson.&lt;br /&gt;
==Manipulating data items==&lt;br /&gt;
Actual functions and propôsal for new ones for manipulating data items are discussed in [[Data_Item_Functions]]&lt;br /&gt;
==Side effects to other modules==&lt;br /&gt;
* Modification of the question type to allow moving of calculated question to another category.&lt;br /&gt;
* Creation of general functions to standardize the import or export process.&lt;br /&gt;
==Creation and modification of calculated questions==&lt;br /&gt;
See the [[Development:Calculated question bugs and new features proposal]]&lt;br /&gt;
&lt;br /&gt;
See the [[Development:Calculated multiquestions proposal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See the [[Calculated question actual 1.7 interface summary]]&lt;br /&gt;
&lt;br /&gt;
See the [[Calculated question 1.7 bugs solving proposal]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  [[User:Pierre Pichet|Pierre Pichet]]  August 2007 (WST)&lt;br /&gt;
[[Developer_notes]]&lt;br /&gt;
[[Calculated question creation developper docs]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Calculated_question_type_creation&amp;diff=52127</id>
		<title>Development:Calculated question type creation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Calculated_question_type_creation&amp;diff=52127"/>
		<updated>2009-03-06T06:19:26Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* A more FULL PROOF code proposal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Calculated question dev docs}}&lt;br /&gt;
I will use this page and the followings to describe the PHP code principal processes of the calculated question creation and see how it could be improved.&lt;br /&gt;
==Calculated question parameters== &lt;br /&gt;
Calculated question is an extended numerical question where parameters of a mathematical problems are generated and used to calculate the answer using a mathematical formula.&lt;br /&gt;
&lt;br /&gt;
So the answer parameter of a numerical question is replaced by the mathematical formula using the same answer database structure that the numerical question.&lt;br /&gt;
 &lt;br /&gt;
The generated parameters are identified by a special format that is not used in a mathematical PHP equation {param} where the param name begins by a letter and can include alphanumerics symbol a-z A-Z _ 0-9  &lt;br /&gt;
 ex. {ad} {a_2} {a4_r} are valid parameter names &lt;br /&gt;
 {1a} {a+1} {a(0)} are invalid parameter names&lt;br /&gt;
  &lt;br /&gt;
These parameters are transform in datasets defined by a min,max,decimal and generation mode.&lt;br /&gt;
Using these datasets definitions a number of different values are generated (the dataset items) and used to generate different question instances where the parameters have different values although the question structure and answer formula are constant.&lt;br /&gt;
&lt;br /&gt;
==Creating a calculated question==&lt;br /&gt;
Actually the creation of a calculated question is a three step process&lt;br /&gt;
* &#039;&#039;&#039;Defining the common question parameters&#039;&#039;&#039;&lt;br /&gt;
** Question name&lt;br /&gt;
** Question text&lt;br /&gt;
** answer formula, limit, units&lt;br /&gt;
* &#039;&#039;&#039;Defining the dataset definitions range&#039;&#039;&#039; for each of them. The dataset definition ({params}) can be used in this new question only or could be used or add been already created by other questions in the question category in which the new question is created.&lt;br /&gt;
  question category is a set of questions that can contain various question types&lt;br /&gt;
* &#039;&#039;&#039;Defining the dataset definitions parameters&#039;&#039;&#039; (min,max, decimal and generation mode and &#039;&#039;&#039;adding at least one data item&#039;&#039;&#039; for each dataset definitions&lt;br /&gt;
 Actually a set of all the data items is created when you click the add button&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Saving&#039;&#039;&#039; the question parameters,dataset definitions parameters and data items.&lt;br /&gt;
The real saving procedure is done when you &#039;&#039;&#039;add&#039;&#039;&#039;  the &#039;&#039;&#039;first&#039;&#039;&#039; set of data items.&lt;br /&gt;
 Because in the actual code a calculated question needs that&lt;br /&gt;
 &#039;&#039;&#039;all&#039;&#039;&#039; these components be defined to be a &#039;&#039;&#039;valid&#039;&#039;&#039; calculated question,&lt;br /&gt;
 the saving is &#039;&#039;&#039;postponed&#039;&#039;&#039; until you click the &#039;&#039;&#039;add button&#039;&#039;&#039; to add the &#039;&#039;&#039;first&#039;&#039;&#039; set of data items.&lt;br /&gt;
 The parameters already entered are stored in the $Session object&lt;br /&gt;
 even if you click &#039;&#039;&#039;Saving changes&#039;&#039;&#039; at least&lt;br /&gt;
 &#039;&#039;&#039;twice&#039;&#039;&#039; &lt;br /&gt;
   1.&#039;&#039;&#039;Defining the common question parameters&#039;&#039;&#039; &lt;br /&gt;
   2.&#039;&#039;&#039;Defining the dataset definitions range&#039;&#039;&#039; steps.&lt;br /&gt;
 before adding your first set of data items.&lt;br /&gt;
&lt;br /&gt;
==Editing of a question==&lt;br /&gt;
When you modify the an actual question, if you click &#039;&#039;&#039;Saving changes&#039;&#039;&#039;. the changes are saved in the database. &lt;br /&gt;
==Creating a copy of a question==&lt;br /&gt;
When you create a new question as a copy of an actual question , the ordinary parameters are copied but you havo to reconstruct the database sets and the database.&lt;br /&gt;
==Moving a question to another category==&lt;br /&gt;
When you move a question to another category, the ordinary parameters are copied but you havo to reconstruct the database sets and the database.If you come back to the initial category, the initial datasets are retrivied. There is a bug in the transfer related to the complex structure of the calculated questions.&lt;br /&gt;
Correcting this bug is one of my priorities([[User:Pierre Pichet|Pierre Pichet]] 11:59, 21 August 2006 (CDT)).&lt;br /&gt;
==A summary of the actual functions==&lt;br /&gt;
See the [[Calculated question actual 1.7 interface summary]]&lt;br /&gt;
&lt;br /&gt;
==NOTHING is SAVED UNTIL you CLICK the ADD BUTTON==&lt;br /&gt;
In the preceding Moodle version (&amp;lt;1.6), the user could click the BACK TO QUIZ EDITING button before adding a first data set item&lt;br /&gt;
 If the user at the third step click BACK TO QUIZ EDITING when NO dataset items added, &lt;br /&gt;
 he LOOSE all his work because the question general parameters where not solved.&lt;br /&gt;
In the newer Moodle versions (1.65 beta,1.7, June 2006), the BACK TO QUIZ EDITING button does not appear unless there is at least one data set item.&lt;br /&gt;
see [[Calculated question back to quiz button]]&lt;br /&gt;
&lt;br /&gt;
Because of this three steps procedure, the creation of a calculated question is a process which can abort easily if the user do not follow exactly all the three steps in the order the Moodle code expect them.&lt;br /&gt;
Improvements to obtain a &#039;&#039;&#039;FOOLPROOF PROCESS&#039;&#039;&#039; are proposed in the next section.&lt;br /&gt;
&lt;br /&gt;
However, the teacher should always verify that for each added data item set, a valid answer, minimum and maximum value are obtained.&lt;br /&gt;
Fortunately, at this step the newly created calculated question is already saved in the database and the user could go back and modify the question if necessary.&lt;br /&gt;
&lt;br /&gt;
==A more FOOLPROOF code proposal == &lt;br /&gt;
See also [[Calculated question development| a proposed calculated question development]] in Developer notes  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Calculated question type creation]]&lt;br /&gt;
[[Category:Quiz]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Calculated_question_type_creation&amp;diff=52126</id>
		<title>Development:Calculated question type creation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Calculated_question_type_creation&amp;diff=52126"/>
		<updated>2009-03-06T06:19:07Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* NOTHING is SAVED UNTIL you CLICK the ADD BUTTON */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Calculated question dev docs}}&lt;br /&gt;
I will use this page and the followings to describe the PHP code principal processes of the calculated question creation and see how it could be improved.&lt;br /&gt;
==Calculated question parameters== &lt;br /&gt;
Calculated question is an extended numerical question where parameters of a mathematical problems are generated and used to calculate the answer using a mathematical formula.&lt;br /&gt;
&lt;br /&gt;
So the answer parameter of a numerical question is replaced by the mathematical formula using the same answer database structure that the numerical question.&lt;br /&gt;
 &lt;br /&gt;
The generated parameters are identified by a special format that is not used in a mathematical PHP equation {param} where the param name begins by a letter and can include alphanumerics symbol a-z A-Z _ 0-9  &lt;br /&gt;
 ex. {ad} {a_2} {a4_r} are valid parameter names &lt;br /&gt;
 {1a} {a+1} {a(0)} are invalid parameter names&lt;br /&gt;
  &lt;br /&gt;
These parameters are transform in datasets defined by a min,max,decimal and generation mode.&lt;br /&gt;
Using these datasets definitions a number of different values are generated (the dataset items) and used to generate different question instances where the parameters have different values although the question structure and answer formula are constant.&lt;br /&gt;
&lt;br /&gt;
==Creating a calculated question==&lt;br /&gt;
Actually the creation of a calculated question is a three step process&lt;br /&gt;
* &#039;&#039;&#039;Defining the common question parameters&#039;&#039;&#039;&lt;br /&gt;
** Question name&lt;br /&gt;
** Question text&lt;br /&gt;
** answer formula, limit, units&lt;br /&gt;
* &#039;&#039;&#039;Defining the dataset definitions range&#039;&#039;&#039; for each of them. The dataset definition ({params}) can be used in this new question only or could be used or add been already created by other questions in the question category in which the new question is created.&lt;br /&gt;
  question category is a set of questions that can contain various question types&lt;br /&gt;
* &#039;&#039;&#039;Defining the dataset definitions parameters&#039;&#039;&#039; (min,max, decimal and generation mode and &#039;&#039;&#039;adding at least one data item&#039;&#039;&#039; for each dataset definitions&lt;br /&gt;
 Actually a set of all the data items is created when you click the add button&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Saving&#039;&#039;&#039; the question parameters,dataset definitions parameters and data items.&lt;br /&gt;
The real saving procedure is done when you &#039;&#039;&#039;add&#039;&#039;&#039;  the &#039;&#039;&#039;first&#039;&#039;&#039; set of data items.&lt;br /&gt;
 Because in the actual code a calculated question needs that&lt;br /&gt;
 &#039;&#039;&#039;all&#039;&#039;&#039; these components be defined to be a &#039;&#039;&#039;valid&#039;&#039;&#039; calculated question,&lt;br /&gt;
 the saving is &#039;&#039;&#039;postponed&#039;&#039;&#039; until you click the &#039;&#039;&#039;add button&#039;&#039;&#039; to add the &#039;&#039;&#039;first&#039;&#039;&#039; set of data items.&lt;br /&gt;
 The parameters already entered are stored in the $Session object&lt;br /&gt;
 even if you click &#039;&#039;&#039;Saving changes&#039;&#039;&#039; at least&lt;br /&gt;
 &#039;&#039;&#039;twice&#039;&#039;&#039; &lt;br /&gt;
   1.&#039;&#039;&#039;Defining the common question parameters&#039;&#039;&#039; &lt;br /&gt;
   2.&#039;&#039;&#039;Defining the dataset definitions range&#039;&#039;&#039; steps.&lt;br /&gt;
 before adding your first set of data items.&lt;br /&gt;
&lt;br /&gt;
==Editing of a question==&lt;br /&gt;
When you modify the an actual question, if you click &#039;&#039;&#039;Saving changes&#039;&#039;&#039;. the changes are saved in the database. &lt;br /&gt;
==Creating a copy of a question==&lt;br /&gt;
When you create a new question as a copy of an actual question , the ordinary parameters are copied but you havo to reconstruct the database sets and the database.&lt;br /&gt;
==Moving a question to another category==&lt;br /&gt;
When you move a question to another category, the ordinary parameters are copied but you havo to reconstruct the database sets and the database.If you come back to the initial category, the initial datasets are retrivied. There is a bug in the transfer related to the complex structure of the calculated questions.&lt;br /&gt;
Correcting this bug is one of my priorities([[User:Pierre Pichet|Pierre Pichet]] 11:59, 21 August 2006 (CDT)).&lt;br /&gt;
==A summary of the actual functions==&lt;br /&gt;
See the [[Calculated question actual 1.7 interface summary]]&lt;br /&gt;
&lt;br /&gt;
==NOTHING is SAVED UNTIL you CLICK the ADD BUTTON==&lt;br /&gt;
In the preceding Moodle version (&amp;lt;1.6), the user could click the BACK TO QUIZ EDITING button before adding a first data set item&lt;br /&gt;
 If the user at the third step click BACK TO QUIZ EDITING when NO dataset items added, &lt;br /&gt;
 he LOOSE all his work because the question general parameters where not solved.&lt;br /&gt;
In the newer Moodle versions (1.65 beta,1.7, June 2006), the BACK TO QUIZ EDITING button does not appear unless there is at least one data set item.&lt;br /&gt;
see [[Calculated question back to quiz button]]&lt;br /&gt;
&lt;br /&gt;
Because of this three steps procedure, the creation of a calculated question is a process which can abort easily if the user do not follow exactly all the three steps in the order the Moodle code expect them.&lt;br /&gt;
Improvements to obtain a &#039;&#039;&#039;FOOLPROOF PROCESS&#039;&#039;&#039; are proposed in the next section.&lt;br /&gt;
&lt;br /&gt;
However, the teacher should always verify that for each added data item set, a valid answer, minimum and maximum value are obtained.&lt;br /&gt;
Fortunately, at this step the newly created calculated question is already saved in the database and the user could go back and modify the question if necessary.&lt;br /&gt;
&lt;br /&gt;
==A more FULL PROOF code proposal == &lt;br /&gt;
See also [[Calculated question development| a proposed calculated question development]] in Developer notes  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Calculated question type creation]]&lt;br /&gt;
[[Category:Quiz]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=25634</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=25634"/>
		<updated>2007-08-05T00:39:02Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for moodle 1.8+ please read http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=445&lt;br /&gt;
&lt;br /&gt;
the rest of this page concerns moodle 1.5 and 1.6 only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in &#039;&#039;&#039;ONLY&#039;&#039;&#039;:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals &lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality tied to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block can also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your language directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===Setting up Marking block for Moodle 1.6+===&lt;br /&gt;
&lt;br /&gt;
* download block_marking_1.6x from http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=445&lt;br /&gt;
* unzip it in the root folder of your moodle directory&lt;br /&gt;
* adjust the settings in &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
* set &#039;&#039;&#039;$CFG-&amp;gt;block_marking_listnum =&#039;&#039;&#039; &#039;&#039;(some number other than the default 2)&#039;&#039;  via the &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039; (the default is to show two activites needing marking per section (unmarked / resubmitted / unsubmitted.)&lt;br /&gt;
** set it to a higher number to avoid the illusion that not all items are shown &amp;quot;to be marked&amp;quot;  (or click on the &amp;quot;MORE&amp;quot; button instead)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=25633</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=25633"/>
		<updated>2007-08-05T00:38:21Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for moodle 1.8+ please read http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=445&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in &#039;&#039;&#039;ONLY&#039;&#039;&#039;:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals &lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality tied to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block can also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your language directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===Setting up Marking block for Moodle 1.6+===&lt;br /&gt;
&lt;br /&gt;
* download block_marking_1.6x from http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=445&lt;br /&gt;
* unzip it in the root folder of your moodle directory&lt;br /&gt;
* adjust the settings in &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
* set &#039;&#039;&#039;$CFG-&amp;gt;block_marking_listnum =&#039;&#039;&#039; &#039;&#039;(some number other than the default 2)&#039;&#039;  via the &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039; (the default is to show two activites needing marking per section (unmarked / resubmitted / unsubmitted.)&lt;br /&gt;
** set it to a higher number to avoid the illusion that not all items are shown &amp;quot;to be marked&amp;quot;  (or click on the &amp;quot;MORE&amp;quot; button instead)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25212</id>
		<title>Development:Web services API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25212"/>
		<updated>2007-07-19T06:30:03Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* The server script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Web Services API provides Moodle with a web service interface to allow exchange of data and information with other systems.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
# Manage user data - send and retrieve the information,&lt;br /&gt;
# Manage course enrolments - add/remove teachers and students,&lt;br /&gt;
# Course management - create new courses based on templates,&lt;br /&gt;
# Gradebook info - extract grades information from Moodle.&lt;br /&gt;
&lt;br /&gt;
==XML-RPC background==&lt;br /&gt;
The XML-RPC service allows other servers to contact your Moodle server and request that it call a function. The Moodle server might do something, like create a user, or it might fetch some data and serve it back to your host.&lt;br /&gt;
&lt;br /&gt;
To communicate like this with another Moodle host, you&#039;d normally use the Moodle Network [https://docs.moodle.org/en/Moodle_Network] features, but it&#039;s also possible for other kinds of program to contact your Moodle, using plain-old-XML-RPC, with Moodle Network&#039;s encryption or signed-message features.&lt;br /&gt;
&lt;br /&gt;
==The server script==&lt;br /&gt;
* allow trusted sites to access web services by configuring &#039;&#039;&#039;admin/mnet/trustedhosts.php&#039;&#039;&#039;&lt;br /&gt;
* start by pointing your browser to &#039;&#039;&#039;mnet/xmlrpc/server.php&#039;&#039;&#039; - this should show an XML error message&lt;br /&gt;
* use POST data in this format:&lt;br /&gt;
 // $method is something like: &amp;quot;mod/forum/lib/forum_add_instance&amp;quot;&lt;br /&gt;
 // $params is an array of parameters. A parameter might itself be an array.&lt;br /&gt;
 // use only Whitelist characters that are permitted in a method name&lt;br /&gt;
 // The method name must not begin with a / - avoid absolute paths&lt;br /&gt;
 // A dot character . is only allowed in the filename, i.e. something.php&lt;br /&gt;
* use &#039;&#039;&#039;mnet/xmlrpc/client.php&#039;&#039;&#039; to make remote xmlrpc calls&lt;br /&gt;
&lt;br /&gt;
==Things you can do==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?f=965 Web Services forum]  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Web services API]]&lt;br /&gt;
[[Category:Administrator]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25211</id>
		<title>Development:Web services API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25211"/>
		<updated>2007-07-19T06:06:56Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* The server script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Web Services API provides Moodle with a web service interface to allow exchange of data and information with other systems.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
# Manage user data - send and retrieve the information,&lt;br /&gt;
# Manage course enrolments - add/remove teachers and students,&lt;br /&gt;
# Course management - create new courses based on templates,&lt;br /&gt;
# Gradebook info - extract grades information from Moodle.&lt;br /&gt;
&lt;br /&gt;
==XML-RPC background==&lt;br /&gt;
The XML-RPC service allows other servers to contact your Moodle server and request that it call a function. The Moodle server might do something, like create a user, or it might fetch some data and serve it back to your host.&lt;br /&gt;
&lt;br /&gt;
To communicate like this with another Moodle host, you&#039;d normally use the Moodle Network [https://docs.moodle.org/en/Moodle_Network] features, but it&#039;s also possible for other kinds of program to contact your Moodle, using plain-old-XML-RPC, with Moodle Network&#039;s encryption or signed-message features.&lt;br /&gt;
&lt;br /&gt;
==The server script==&lt;br /&gt;
* allow trusted sites to access web services by configuring &#039;&#039;&#039;/admin/mnet/trustedhosts.php&#039;&#039;&#039;&lt;br /&gt;
* start by pointing your browser to &#039;&#039;&#039;/mnet/xmlrpc/server.php&#039;&#039;&#039; - this should show an XML error message&lt;br /&gt;
* use POST data in this format:&lt;br /&gt;
 // $method is something like: &amp;quot;mod/forum/lib/forum_add_instance&amp;quot;&lt;br /&gt;
 // $params is an array of parameters. A parameter might itself be an array.&lt;br /&gt;
 // use only Whitelist characters that are permitted in a method name&lt;br /&gt;
 // The method name must not begin with a / - avoid absolute paths&lt;br /&gt;
 // A dot character . is only allowed in the filename, i.e. something.php&lt;br /&gt;
&lt;br /&gt;
==Things you can do==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?f=965 Web Services forum]  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Web services API]]&lt;br /&gt;
[[Category:Administrator]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25210</id>
		<title>Development:Web services API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25210"/>
		<updated>2007-07-19T05:56:24Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* The server script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Web Services API provides Moodle with a web service interface to allow exchange of data and information with other systems.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
# Manage user data - send and retrieve the information,&lt;br /&gt;
# Manage course enrolments - add/remove teachers and students,&lt;br /&gt;
# Course management - create new courses based on templates,&lt;br /&gt;
# Gradebook info - extract grades information from Moodle.&lt;br /&gt;
&lt;br /&gt;
==XML-RPC background==&lt;br /&gt;
The XML-RPC service allows other servers to contact your Moodle server and request that it call a function. The Moodle server might do something, like create a user, or it might fetch some data and serve it back to your host.&lt;br /&gt;
&lt;br /&gt;
To communicate like this with another Moodle host, you&#039;d normally use the Moodle Network [https://docs.moodle.org/en/Moodle_Network] features, but it&#039;s also possible for other kinds of program to contact your Moodle, using plain-old-XML-RPC, with Moodle Network&#039;s encryption or signed-message features.&lt;br /&gt;
&lt;br /&gt;
==The server script==&lt;br /&gt;
* allow trusted sites to access web services by configuring &#039;&#039;&#039;/admin/mnet/trustedhosts.php&#039;&#039;&#039;&lt;br /&gt;
* start by pointing your browser to &#039;&#039;&#039;/mnet/xmlrpc/server.php&#039;&#039;&#039; - this should show an XML error message&lt;br /&gt;
&lt;br /&gt;
 // $method is something like: &amp;quot;mod/forum/lib/forum_add_instance&amp;quot;&lt;br /&gt;
 // $params is an array of parameters. A parameter might itself be an array.&lt;br /&gt;
 // use only Whitelist characters that are permitted in a method name&lt;br /&gt;
 // The method name must not begin with a / - avoid absolute paths&lt;br /&gt;
 // A dot character . is only allowed in the filename, i.e. something.php&lt;br /&gt;
&lt;br /&gt;
==Things you can do==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?f=965 Web Services forum]  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Web services API]]&lt;br /&gt;
[[Category:Administrator]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25209</id>
		<title>Development:Web services API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25209"/>
		<updated>2007-07-19T05:54:40Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* The server script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Web Services API provides Moodle with a web service interface to allow exchange of data and information with other systems.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
# Manage user data - send and retrieve the information,&lt;br /&gt;
# Manage course enrolments - add/remove teachers and students,&lt;br /&gt;
# Course management - create new courses based on templates,&lt;br /&gt;
# Gradebook info - extract grades information from Moodle.&lt;br /&gt;
&lt;br /&gt;
==XML-RPC background==&lt;br /&gt;
The XML-RPC service allows other servers to contact your Moodle server and request that it call a function. The Moodle server might do something, like create a user, or it might fetch some data and serve it back to your host.&lt;br /&gt;
&lt;br /&gt;
To communicate like this with another Moodle host, you&#039;d normally use the Moodle Network [https://docs.moodle.org/en/Moodle_Network] features, but it&#039;s also possible for other kinds of program to contact your Moodle, using plain-old-XML-RPC, with Moodle Network&#039;s encryption or signed-message features.&lt;br /&gt;
&lt;br /&gt;
==The server script==&lt;br /&gt;
* allow trusted sites to access web services by configuring &#039;&#039;&#039;/admin/mnet/trustedhosts.php&#039;&#039;&#039;&lt;br /&gt;
* start by pointing your browser to &#039;&#039;&#039;/mnet/xmlrpc/server.php&#039;&#039;&#039; - this should show an XML error message&lt;br /&gt;
&lt;br /&gt;
 // $method is something like: &amp;quot;mod/forum/lib/forum_add_instance&amp;quot;&lt;br /&gt;
 // $params is an array of parameters. A parameter might itself be an array.&lt;br /&gt;
&lt;br /&gt;
==Things you can do==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?f=965 Web Services forum]  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Web services API]]&lt;br /&gt;
[[Category:Administrator]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25208</id>
		<title>Development:Web services API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25208"/>
		<updated>2007-07-19T05:33:02Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* The server script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Web Services API provides Moodle with a web service interface to allow exchange of data and information with other systems.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
# Manage user data - send and retrieve the information,&lt;br /&gt;
# Manage course enrolments - add/remove teachers and students,&lt;br /&gt;
# Course management - create new courses based on templates,&lt;br /&gt;
# Gradebook info - extract grades information from Moodle.&lt;br /&gt;
&lt;br /&gt;
==XML-RPC background==&lt;br /&gt;
The XML-RPC service allows other servers to contact your Moodle server and request that it call a function. The Moodle server might do something, like create a user, or it might fetch some data and serve it back to your host.&lt;br /&gt;
&lt;br /&gt;
To communicate like this with another Moodle host, you&#039;d normally use the Moodle Network [https://docs.moodle.org/en/Moodle_Network] features, but it&#039;s also possible for other kinds of program to contact your Moodle, using plain-old-XML-RPC, with Moodle Network&#039;s encryption or signed-message features.&lt;br /&gt;
&lt;br /&gt;
==The server script==&lt;br /&gt;
* allow trusted sites to access web services by configuring &#039;&#039;&#039;/admin/mnet/trustedhosts.php&#039;&#039;&#039;&lt;br /&gt;
* start by pointing your browser to &#039;&#039;&#039;/mnet/xmlrpc/server.php&#039;&#039;&#039; - this should show an XML error message&lt;br /&gt;
&lt;br /&gt;
==Things you can do==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?f=965 Web Services forum]  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Web services API]]&lt;br /&gt;
[[Category:Administrator]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25207</id>
		<title>Development:Web services API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25207"/>
		<updated>2007-07-19T05:29:41Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* The server script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Web Services API provides Moodle with a web service interface to allow exchange of data and information with other systems.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
# Manage user data - send and retrieve the information,&lt;br /&gt;
# Manage course enrolments - add/remove teachers and students,&lt;br /&gt;
# Course management - create new courses based on templates,&lt;br /&gt;
# Gradebook info - extract grades information from Moodle.&lt;br /&gt;
&lt;br /&gt;
==XML-RPC background==&lt;br /&gt;
The XML-RPC service allows other servers to contact your Moodle server and request that it call a function. The Moodle server might do something, like create a user, or it might fetch some data and serve it back to your host.&lt;br /&gt;
&lt;br /&gt;
To communicate like this with another Moodle host, you&#039;d normally use the Moodle Network [https://docs.moodle.org/en/Moodle_Network] features, but it&#039;s also possible for other kinds of program to contact your Moodle, using plain-old-XML-RPC, with Moodle Network&#039;s encryption or signed-message features.&lt;br /&gt;
&lt;br /&gt;
==The server script==&lt;br /&gt;
* start by pointing your browser to &#039;&#039;_http://your_domain/path_to_moodle&#039;&#039;&#039;&#039;&#039;/mnet/xmlrpc/server.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Things you can do==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?f=965 Web Services forum]  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Web services API]]&lt;br /&gt;
[[Category:Administrator]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25206</id>
		<title>Development:Web services API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25206"/>
		<updated>2007-07-19T05:29:25Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* The server script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Web Services API provides Moodle with a web service interface to allow exchange of data and information with other systems.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
# Manage user data - send and retrieve the information,&lt;br /&gt;
# Manage course enrolments - add/remove teachers and students,&lt;br /&gt;
# Course management - create new courses based on templates,&lt;br /&gt;
# Gradebook info - extract grades information from Moodle.&lt;br /&gt;
&lt;br /&gt;
==XML-RPC background==&lt;br /&gt;
The XML-RPC service allows other servers to contact your Moodle server and request that it call a function. The Moodle server might do something, like create a user, or it might fetch some data and serve it back to your host.&lt;br /&gt;
&lt;br /&gt;
To communicate like this with another Moodle host, you&#039;d normally use the Moodle Network [https://docs.moodle.org/en/Moodle_Network] features, but it&#039;s also possible for other kinds of program to contact your Moodle, using plain-old-XML-RPC, with Moodle Network&#039;s encryption or signed-message features.&lt;br /&gt;
&lt;br /&gt;
==The server script==&lt;br /&gt;
* start by pointing your browser to _&#039;&#039;http://your_domain/path_to_moodle&#039;&#039;&#039;&#039;&#039;/mnet/xmlrpc/server.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Things you can do==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?f=965 Web Services forum]  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Web services API]]&lt;br /&gt;
[[Category:Administrator]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25205</id>
		<title>Development:Web services API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25205"/>
		<updated>2007-07-19T05:28:51Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* The server script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Web Services API provides Moodle with a web service interface to allow exchange of data and information with other systems.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
# Manage user data - send and retrieve the information,&lt;br /&gt;
# Manage course enrolments - add/remove teachers and students,&lt;br /&gt;
# Course management - create new courses based on templates,&lt;br /&gt;
# Gradebook info - extract grades information from Moodle.&lt;br /&gt;
&lt;br /&gt;
==XML-RPC background==&lt;br /&gt;
The XML-RPC service allows other servers to contact your Moodle server and request that it call a function. The Moodle server might do something, like create a user, or it might fetch some data and serve it back to your host.&lt;br /&gt;
&lt;br /&gt;
To communicate like this with another Moodle host, you&#039;d normally use the Moodle Network [https://docs.moodle.org/en/Moodle_Network] features, but it&#039;s also possible for other kinds of program to contact your Moodle, using plain-old-XML-RPC, with Moodle Network&#039;s encryption or signed-message features.&lt;br /&gt;
&lt;br /&gt;
==The server script==&lt;br /&gt;
* start by pointing your browser to hhttp://your_domain/path_to_moodle&#039;&#039;&#039;/mnet/xmlrpc/server.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Things you can do==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?f=965 Web Services forum]  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Web services API]]&lt;br /&gt;
[[Category:Administrator]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25204</id>
		<title>Development:Web services API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Web_services_API&amp;diff=25204"/>
		<updated>2007-07-19T05:27:48Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* The server script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Web Services API provides Moodle with a web service interface to allow exchange of data and information with other systems.&lt;br /&gt;
&lt;br /&gt;
For example,&lt;br /&gt;
# Manage user data - send and retrieve the information,&lt;br /&gt;
# Manage course enrolments - add/remove teachers and students,&lt;br /&gt;
# Course management - create new courses based on templates,&lt;br /&gt;
# Gradebook info - extract grades information from Moodle.&lt;br /&gt;
&lt;br /&gt;
==XML-RPC background==&lt;br /&gt;
The XML-RPC service allows other servers to contact your Moodle server and request that it call a function. The Moodle server might do something, like create a user, or it might fetch some data and serve it back to your host.&lt;br /&gt;
&lt;br /&gt;
To communicate like this with another Moodle host, you&#039;d normally use the Moodle Network [https://docs.moodle.org/en/Moodle_Network] features, but it&#039;s also possible for other kinds of program to contact your Moodle, using plain-old-XML-RPC, with Moodle Network&#039;s encryption or signed-message features.&lt;br /&gt;
&lt;br /&gt;
==The server script==&lt;br /&gt;
* start by pointing your browser to http://your_domain/path_to_moodle&#039;&#039;&#039;/mnet/xmlrpc/server.php&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Things you can do==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* Using Moodle [http://moodle.org/mod/forum/view.php?f=965 Web Services forum]  &lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Web services API]]&lt;br /&gt;
[[Category:Administrator]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Themes&amp;diff=23278</id>
		<title>Themes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Themes&amp;diff=23278"/>
		<updated>2007-05-15T02:22:56Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Installing your own theme */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Themes}}&lt;br /&gt;
&lt;br /&gt;
Moodle has a powerful &#039;&#039;&#039;themes&#039;&#039;&#039; system that allows for a variety of effects through the use of XHTML and CSS.&lt;br /&gt;
&lt;br /&gt;
* Themes may be [[Theme config|configured]] at site level, course level and/or user level.&lt;br /&gt;
* Each page is individually-addressable via CSS, allowing you to pinpoint exact items.&lt;br /&gt;
* Our CSS class naming system uses simple English, is consistent and easily understood.&lt;br /&gt;
* New modules can tell Moodle what styles they need and automatically include these in the stylesheet.&lt;br /&gt;
* Themes can be based on the &#039;&#039;standard&#039;&#039; theme, which is very plain but functional.  You simply override styles you want to change by adding to the stylesheet in your own theme.  This means that if you upgrade Moodle later and new styles are needed, your custom theme will still work without any changes, because the new classes will be defined in the &#039;&#039;standard&#039;&#039; theme.&lt;br /&gt;
* Themes can also be based on any other theme.  This allows you to easily create families of themes, or variations on a theme.  For example you might create a spectrum of pastel shades for use in different courses, but with the same basic layout and logos.  You may also want to create a family of differently-coloured themes for accessibility purposes.&lt;br /&gt;
&lt;br /&gt;
== Creating your own theme ==&lt;br /&gt;
&lt;br /&gt;
If you plan to work on your own theme please create a new one (with its own named subfolder) and use Moodle&#039;s [what] feature to base your theme on an existing theme such as &#039;&#039;standard&#039;&#039;. If you just modify one of the delivered themes it will be overwritten by the next Moodle update.&lt;br /&gt;
&lt;br /&gt;
== Installing your own theme ==&lt;br /&gt;
&lt;br /&gt;
Once you have your own theme created, you should follow these steps to install it on your site:&lt;br /&gt;
&lt;br /&gt;
# Zip the theme folder using winzip or similar&lt;br /&gt;
# Upload the .zip file into the theme folder moodle/themes/&lt;br /&gt;
# Unzip&lt;br /&gt;
# note: make sure the new theme folder and its contents are readable by the webserver. in Mac OS X, set Group and Other privileges to  &#039;Read &amp;amp; Write&#039; (select File&amp;gt; Get Info&amp;gt; Ownership &amp;amp; Permissions) otherwise Moodle may not be able to display the newly installed theme.&lt;br /&gt;
# Choose your new theme from within Moodle Admin&amp;gt;Appearances&amp;gt;Themes (version 1.7 +). For older versions, the path is Moodle Admin&amp;gt;Configuration&amp;gt;Themes&lt;br /&gt;
&lt;br /&gt;
== Theme system changes across Moodle versions ==&lt;br /&gt;
&lt;br /&gt;
Moodle 1.5 themes are quite different from previous versions and so a [[Theme upgrade|theme upgrade]] is required. A theme upgrade is also required for the [[1.6 theme upgrade|transition from 1.5 to 1.6]], since the XHTML structure has been reworked for improved [[Accessibility|accessibility]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Themes]]&lt;br /&gt;
&lt;br /&gt;
[[es:Temas]]&lt;br /&gt;
[[fr:Thèmes]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Themes&amp;diff=23277</id>
		<title>Themes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Themes&amp;diff=23277"/>
		<updated>2007-05-15T02:21:45Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Installing your own theme */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Themes}}&lt;br /&gt;
&lt;br /&gt;
Moodle has a powerful &#039;&#039;&#039;themes&#039;&#039;&#039; system that allows for a variety of effects through the use of XHTML and CSS.&lt;br /&gt;
&lt;br /&gt;
* Themes may be [[Theme config|configured]] at site level, course level and/or user level.&lt;br /&gt;
* Each page is individually-addressable via CSS, allowing you to pinpoint exact items.&lt;br /&gt;
* Our CSS class naming system uses simple English, is consistent and easily understood.&lt;br /&gt;
* New modules can tell Moodle what styles they need and automatically include these in the stylesheet.&lt;br /&gt;
* Themes can be based on the &#039;&#039;standard&#039;&#039; theme, which is very plain but functional.  You simply override styles you want to change by adding to the stylesheet in your own theme.  This means that if you upgrade Moodle later and new styles are needed, your custom theme will still work without any changes, because the new classes will be defined in the &#039;&#039;standard&#039;&#039; theme.&lt;br /&gt;
* Themes can also be based on any other theme.  This allows you to easily create families of themes, or variations on a theme.  For example you might create a spectrum of pastel shades for use in different courses, but with the same basic layout and logos.  You may also want to create a family of differently-coloured themes for accessibility purposes.&lt;br /&gt;
&lt;br /&gt;
== Creating your own theme ==&lt;br /&gt;
&lt;br /&gt;
If you plan to work on your own theme please create a new one (with its own named subfolder) and use Moodle&#039;s [what] feature to base your theme on an existing theme such as &#039;&#039;standard&#039;&#039;. If you just modify one of the delivered themes it will be overwritten by the next Moodle update.&lt;br /&gt;
&lt;br /&gt;
== Installing your own theme ==&lt;br /&gt;
&lt;br /&gt;
Once you have your own theme created, you should follow these steps to install it on your site:&lt;br /&gt;
&lt;br /&gt;
# Zip the theme folder using winzip or similar&lt;br /&gt;
# Upload the .zip file into the theme folder moodle/themes/&lt;br /&gt;
# Unzip&lt;br /&gt;
# note: make sure the new theme folder and its contents are readable by the webserver.&lt;br /&gt;
if you are using Mac OS X, make sure that the files have Group and Other privileges set to  &#039;Read &amp;amp; Write&#039; (select File&amp;gt; Get Info&amp;gt; Ownership &amp;amp; Permissions) otherwise Moodle may not be able to display the newly installed theme.&lt;br /&gt;
# Choose your new theme from within Moodle Admin&amp;gt;Appearances&amp;gt;Themes (version 1.7 +). For older versions, the path is Moodle Admin&amp;gt;Configuration&amp;gt;Themes&lt;br /&gt;
&lt;br /&gt;
== Theme system changes across Moodle versions ==&lt;br /&gt;
&lt;br /&gt;
Moodle 1.5 themes are quite different from previous versions and so a [[Theme upgrade|theme upgrade]] is required. A theme upgrade is also required for the [[1.6 theme upgrade|transition from 1.5 to 1.6]], since the XHTML structure has been reworked for improved [[Accessibility|accessibility]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Themes]]&lt;br /&gt;
&lt;br /&gt;
[[es:Temas]]&lt;br /&gt;
[[fr:Thèmes]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Themes&amp;diff=23276</id>
		<title>Themes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Themes&amp;diff=23276"/>
		<updated>2007-05-15T02:21:29Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Themes}}&lt;br /&gt;
&lt;br /&gt;
Moodle has a powerful &#039;&#039;&#039;themes&#039;&#039;&#039; system that allows for a variety of effects through the use of XHTML and CSS.&lt;br /&gt;
&lt;br /&gt;
* Themes may be [[Theme config|configured]] at site level, course level and/or user level.&lt;br /&gt;
* Each page is individually-addressable via CSS, allowing you to pinpoint exact items.&lt;br /&gt;
* Our CSS class naming system uses simple English, is consistent and easily understood.&lt;br /&gt;
* New modules can tell Moodle what styles they need and automatically include these in the stylesheet.&lt;br /&gt;
* Themes can be based on the &#039;&#039;standard&#039;&#039; theme, which is very plain but functional.  You simply override styles you want to change by adding to the stylesheet in your own theme.  This means that if you upgrade Moodle later and new styles are needed, your custom theme will still work without any changes, because the new classes will be defined in the &#039;&#039;standard&#039;&#039; theme.&lt;br /&gt;
* Themes can also be based on any other theme.  This allows you to easily create families of themes, or variations on a theme.  For example you might create a spectrum of pastel shades for use in different courses, but with the same basic layout and logos.  You may also want to create a family of differently-coloured themes for accessibility purposes.&lt;br /&gt;
&lt;br /&gt;
== Creating your own theme ==&lt;br /&gt;
&lt;br /&gt;
If you plan to work on your own theme please create a new one (with its own named subfolder) and use Moodle&#039;s [what] feature to base your theme on an existing theme such as &#039;&#039;standard&#039;&#039;. If you just modify one of the delivered themes it will be overwritten by the next Moodle update.&lt;br /&gt;
&lt;br /&gt;
== Installing your own theme ==&lt;br /&gt;
&lt;br /&gt;
Once you have your own theme created, you should follow these steps to install it on your site:&lt;br /&gt;
&lt;br /&gt;
# Zip the theme folder using winzip or similar&lt;br /&gt;
# Upload the .zip file into the theme folder moodle/themes/&lt;br /&gt;
# Unzip&lt;br /&gt;
# note: make sure the new theme folder and its contents are readable by the webserver.&lt;br /&gt;
 if you are using Mac OS X, make sure that the files have Group and Other privileges set to  &#039;Read &amp;amp; Write&#039; (select File&amp;gt; Get Info&amp;gt; Ownership &amp;amp; Permissions) otherwise Moodle may not be able to display the newly installed theme.&lt;br /&gt;
# Choose your new theme from within Moodle Admin&amp;gt;Appearances&amp;gt;Themes (version 1.7 +). For older versions, the path is Moodle Admin&amp;gt;Configuration&amp;gt;Themes&lt;br /&gt;
&lt;br /&gt;
== Theme system changes across Moodle versions ==&lt;br /&gt;
&lt;br /&gt;
Moodle 1.5 themes are quite different from previous versions and so a [[Theme upgrade|theme upgrade]] is required. A theme upgrade is also required for the [[1.6 theme upgrade|transition from 1.5 to 1.6]], since the XHTML structure has been reworked for improved [[Accessibility|accessibility]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Themes]]&lt;br /&gt;
&lt;br /&gt;
[[es:Temas]]&lt;br /&gt;
[[fr:Thèmes]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22858</id>
		<title>tracksessionip</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22858"/>
		<updated>2007-04-29T04:04:20Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Comments==&lt;br /&gt;
* &amp;quot;It restricts a single session from changing IP, and this is mostly a debugging tool for a strange problem that we think is a PHP bug. It does not stop a single user from having more than one session.&amp;quot;&lt;br /&gt;
** Martin Langhoff in http://moodle.org/mod/forum/discuss.php?d=47271#217274&lt;br /&gt;
* &amp;quot;suppose you logged in using a dial up connection.  If you get disconnected and then reconnect, tracksessionip will not let you open pages even if you had your browser open.&amp;quot;&lt;br /&gt;
** Vikram Solia in http://moodle.org/mod/forum/discuss.php?d=32879#157645&lt;br /&gt;
&lt;br /&gt;
==Config.php==&lt;br /&gt;
* to turn it on, go to config.php and uncomment:&lt;br /&gt;
* $CFG-&amp;gt;tracksessionip= True;&lt;br /&gt;
&lt;br /&gt;
 // If this setting is set to true, then Moodle will track the IP of the&lt;br /&gt;
 // current user to make sure it hasn&#039;t changed during a session.  This&lt;br /&gt;
 // will prevent the possibility of sessions being hijacked via XSS, but it&lt;br /&gt;
 // may break things for users coming using proxies that change all the time,&lt;br /&gt;
 // like AOL.&lt;br /&gt;
&lt;br /&gt;
==Alternative==&lt;br /&gt;
* set dbsessions to &amp;quot;YES&amp;quot; so that sessions are stored in the db&lt;br /&gt;
* non-recommended alternative method is to allow domain users write access to the sessions directory (see note at bottom of [[NTLM_authentication]])&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22857</id>
		<title>tracksessionip</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22857"/>
		<updated>2007-04-29T03:47:33Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
==Comments==&lt;br /&gt;
* &amp;quot;It restricts a single session from changing IP, and this is mostly a debugging tool for a strange problem that we think is a PHP bug. It does not stop a single user from having more than one session.&amp;quot;&lt;br /&gt;
** Martin Langhoff in http://moodle.org/mod/forum/discuss.php?d=47271#217274&lt;br /&gt;
* &amp;quot;suppose you logged in using a dial up connection.  If you get disconnected and then reconnect, tracksessionip will not let you open pages even if you had your browser open.&amp;quot;&lt;br /&gt;
** Vikram Solia in http://moodle.org/mod/forum/discuss.php?d=32879#157645&lt;br /&gt;
&lt;br /&gt;
==Config.php==&lt;br /&gt;
* to turn it on, go to config.php and uncomment:&lt;br /&gt;
* $CFG-&amp;gt;tracksessionip= True;&lt;br /&gt;
&lt;br /&gt;
 // If this setting is set to true, then Moodle will track the IP of the&lt;br /&gt;
 // current user to make sure it hasn&#039;t changed during a session.  This&lt;br /&gt;
 // will prevent the possibility of sessions being hijacked via XSS, but it&lt;br /&gt;
 // may break things for users coming using proxies that change all the time,&lt;br /&gt;
 // like AOL.&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22856</id>
		<title>tracksessionip</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22856"/>
		<updated>2007-04-29T03:42:35Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Config.php */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Martin Langhoff==&lt;br /&gt;
* &amp;quot;It restricts a single session from changing IP, and this is mostly a debugging tool for a strange problem that we think is a PHP bug. It does not stop a single user from having more than one session.&amp;quot;&lt;br /&gt;
* http://moodle.org/mod/forum/discuss.php?d=47271#217274&lt;br /&gt;
&lt;br /&gt;
==Config.php==&lt;br /&gt;
* to turn it on, go to config.php and uncomment:&lt;br /&gt;
* $CFG-&amp;gt;tracksessionip= True;&lt;br /&gt;
&lt;br /&gt;
 // If this setting is set to true, then Moodle will track the IP of the&lt;br /&gt;
 // current user to make sure it hasn&#039;t changed during a session.  This&lt;br /&gt;
 // will prevent the possibility of sessions being hijacked via XSS, but it&lt;br /&gt;
 // may break things for users coming using proxies that change all the time,&lt;br /&gt;
 // like AOL.&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22855</id>
		<title>tracksessionip</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22855"/>
		<updated>2007-04-29T03:41:40Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Martin Langhoff==&lt;br /&gt;
* &amp;quot;It restricts a single session from changing IP, and this is mostly a debugging tool for a strange problem that we think is a PHP bug. It does not stop a single user from having more than one session.&amp;quot;&lt;br /&gt;
* http://moodle.org/mod/forum/discuss.php?d=47271#217274&lt;br /&gt;
&lt;br /&gt;
==Config.php==&lt;br /&gt;
* to turn it on, go to config.php and uncomment:&lt;br /&gt;
* $CFG-&amp;gt;tracksessionip= True;&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22854</id>
		<title>tracksessionip</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22854"/>
		<updated>2007-04-29T03:41:26Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:admin]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Martin Langhoff==&lt;br /&gt;
* &amp;quot;It restricts a single session from changing IP, and this is mostly a debugging tool for a strange problem that we think is a PHP bug. It does not stop a single user from having more than one session.&amp;quot;&lt;br /&gt;
* http://moodle.org/mod/forum/discuss.php?d=47271#217274&lt;br /&gt;
&lt;br /&gt;
==Config.php==&lt;br /&gt;
* to turn it on, go to config.php and uncomment:&lt;br /&gt;
* $CFG-&amp;gt;tracksessionip= True;&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22853</id>
		<title>tracksessionip</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=tracksessionip&amp;diff=22853"/>
		<updated>2007-04-29T03:40:54Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category:administrator]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Martin Langhoff==&lt;br /&gt;
* &amp;quot;It restricts a single session from changing IP, and this is mostly a debugging tool for a strange problem that we think is a PHP bug. It does not stop a single user from having more than one session.&amp;quot;&lt;br /&gt;
* http://moodle.org/mod/forum/discuss.php?d=47271#217274&lt;br /&gt;
&lt;br /&gt;
==Config.php==&lt;br /&gt;
* to turn it on, go to config.php and uncomment:&lt;br /&gt;
* $CFG-&amp;gt;tracksessionip= True;&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15757</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15757"/>
		<updated>2006-09-12T06:25:19Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in &#039;&#039;&#039;ONLY&#039;&#039;&#039;:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals &lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* download block_marking_1.6x from http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=445&lt;br /&gt;
* unzip it in the root folder of your moodle directory&lt;br /&gt;
* adjust the settings in &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
* set &#039;&#039;&#039;$CFG-&amp;gt;block_marking_listnum =&#039;&#039;&#039; &#039;&#039;(some number other than the default 2)&#039;&#039;  via the &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039; (the default is to show two activites needing marking per section (unmarked / resubmitted / unsubmitted.)&lt;br /&gt;
** set it to a higher number to avoid the illusion that not all items are shown &amp;quot;to be marked&amp;quot;  (or click on the &amp;quot;MORE&amp;quot; button instead)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15756</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15756"/>
		<updated>2006-09-12T06:24:59Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals &lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* download block_marking_1.6x from http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=445&lt;br /&gt;
* unzip it in the root folder of your moodle directory&lt;br /&gt;
* adjust the settings in &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
* set &#039;&#039;&#039;$CFG-&amp;gt;block_marking_listnum =&#039;&#039;&#039; &#039;&#039;(some number other than the default 2)&#039;&#039;  via the &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039; (the default is to show two activites needing marking per section (unmarked / resubmitted / unsubmitted.)&lt;br /&gt;
** set it to a higher number to avoid the illusion that not all items are shown &amp;quot;to be marked&amp;quot;  (or click on the &amp;quot;MORE&amp;quot; button instead)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15755</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15755"/>
		<updated>2006-09-12T06:23:46Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals (bug: new submissions not showing up)&lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* download block_marking_1.6x from http://moodle.org/mod/data/view.php?d=13&amp;amp;rid=445&lt;br /&gt;
* unzip it in the root folder of your moodle directory&lt;br /&gt;
* adjust the settings in &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
* set &#039;&#039;&#039;$CFG-&amp;gt;block_marking_listnum =&#039;&#039;&#039; &#039;&#039;(some number other than the default 2)&#039;&#039;  via the &#039;&#039;&#039;admin / configureation /blocks / marking / settings menu&#039;&#039;&#039; (the default is to show two activites needing marking per section (unmarked / resubmitted / unsubmitted.)&lt;br /&gt;
** set it to a higher number to avoid the illusion that not all items are shown &amp;quot;to be marked&amp;quot;  (or click on the &amp;quot;MORE&amp;quot; button instead)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15754</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15754"/>
		<updated>2006-09-12T06:21:26Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals (bug: new submissions not showing up)&lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* Bruno Vernier cleaned up marking block for moodle 1.6 as an attachment in http://moodle.org/mod/forum/discuss.php?d=52184#240002&lt;br /&gt;
** please send him any bugs and suggestions (unless someone else wishes to maintain this block)&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
* set &#039;&#039;&#039;$CFG-&amp;gt;block_marking_listnum =&#039;&#039;&#039; &#039;&#039;(some number other than the default 2)&#039;&#039;  via the a&#039;&#039;&#039;dmin / configureation /blocks / marking / settings menu&#039;&#039;&#039; (the default is to show two activites needing marking per section (unmarked / resubmitted / unsubmitted.)&lt;br /&gt;
** set it to a higher number to avoid the illusion that not all items are shown &amp;quot;to be marked&amp;quot;  (or click on the &amp;quot;MORE&amp;quot; button instead)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15753</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15753"/>
		<updated>2006-09-12T06:14:11Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals (bug: new submissions not showing up)&lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* Bruno Vernier cleaned up marking block for moodle 1.6 as an attachment in http://moodle.org/mod/forum/discuss.php?d=52184#240002&lt;br /&gt;
** please send him any bugs and suggestions (unless someone else wishes to maintain this block)&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
* set &#039;&#039;&#039;$CFG-&amp;gt;block_marking_listnum = 2;&#039;&#039;&#039;  in config.php (the default is to show two activites needing marking per section (unmarked / resubmitted / unsubmitted)&lt;br /&gt;
** set it to a higher number to avoid the illusion that not all items are shown &amp;quot;to be marked&amp;quot;  (or click on the &amp;quot;MORE&amp;quot; button instead)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15752</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15752"/>
		<updated>2006-09-12T06:13:21Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals (bug: new submissions not showing up)&lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* set &#039;&#039;&#039;$CFG-&amp;gt;block_marking_listnum = 2;&#039;&#039;&#039;  in config.php (the default is to show two activites needing marking per section (unmarked / resubmitted / unsubmitted)&lt;br /&gt;
** set it to a higher number to avoid the illusion that not all items are shown &amp;quot;to be marked&amp;quot;  (or click on the &amp;quot;MORE&amp;quot; button instead)&lt;br /&gt;
* Bruno Vernier cleaned up marking block for moodle 1.6 as an attachment in http://moodle.org/mod/forum/discuss.php?d=52184#240002&lt;br /&gt;
** please send him any bugs and suggestions (unless someone else wishes to maintain this block)&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15751</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15751"/>
		<updated>2006-09-12T06:02:41Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals (bug: new submissions not showing up)&lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* set &#039;&#039;&#039;$CFG-&amp;gt;block_marking_listnum = 2;&#039;&#039;&#039;  in config.php (the default is to show two activites needing marking per section (unmarked / resubmitted / unsubmitted)&lt;br /&gt;
** set it to a higher number to avoid the illusion that not all items are shown &amp;quot;to be marked&amp;quot;&lt;br /&gt;
* Bruno Vernier cleaned up marking block for moodle 1.6 as an attachment in http://moodle.org/mod/forum/discuss.php?d=52184#240002&lt;br /&gt;
** please send him any bugs and suggestions (unless someone else wishes to maintain this block)&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15747</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=15747"/>
		<updated>2006-09-11T21:52:07Z</updated>

		<summary type="html">&lt;p&gt;Bruno: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
==purpose:==&lt;br /&gt;
* to allow teacher to quickly see what needs to be &amp;quot;marked&amp;quot; in:&lt;br /&gt;
# assignments&lt;br /&gt;
# journals (bug: new submissions not showing up)&lt;br /&gt;
# lessons&lt;br /&gt;
# forums&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* Bruno Vernier cleaned up marking block for moodle 1.6 as an attachment in http://moodle.org/mod/forum/discuss.php?d=52184#240002&lt;br /&gt;
** please send him any bugs and suggestions (unless someone else wishes to maintain this block)&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
* Bruno Vernier - block packaging and some bug fixes&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Course_settings&amp;diff=15719</id>
		<title>Course settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Course_settings&amp;diff=15719"/>
		<updated>2006-09-11T18:56:01Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* Format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Help files}}&lt;br /&gt;
{{Course admin}}&lt;br /&gt;
&lt;br /&gt;
You are asked to complete the &#039;&#039;&#039;settings&#039;&#039;&#039; page when creating a new course. The choices you make can be edited at a later date by choosing the settings option from the [[Administration block]] menu.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Category==&lt;br /&gt;
&lt;br /&gt;
Your Moodle administrator may have set up several course categories.&lt;br /&gt;
&lt;br /&gt;
For example, &amp;quot;Science&amp;quot;, &amp;quot;Humanities&amp;quot;, &amp;quot;Public Health&amp;quot; etc&lt;br /&gt;
&lt;br /&gt;
Choose the one most applicable for your course. This choice will affect where your course is displayed on the course listing and may make it easier for students to find your course.&lt;br /&gt;
&lt;br /&gt;
==Full name==&lt;br /&gt;
&lt;br /&gt;
The full name of the course is displayed at the top of the screen and in the course listings.&lt;br /&gt;
&lt;br /&gt;
==Short name==&lt;br /&gt;
&lt;br /&gt;
Many institutions have a shorthand way of referring to a course, such as BP102 or COMMS. Even you don&#039;t already have such a name for your course, make one up here. It will be used in several places where the long name isn&#039;t appropriate.  The most common use is in the navigation bar that is at the top of most pages.&lt;br /&gt;
&lt;br /&gt;
[[Image:MoodleCookieTrail.gif|The underlined part is the course Short name.]]&lt;br /&gt;
&lt;br /&gt;
The the above example has underlined the short course name, &amp;quot;Using Moodle&amp;quot;.  The short name also appears in the subject line of email messages that are part of the course.&lt;br /&gt;
&lt;br /&gt;
==ID number==&lt;br /&gt;
&lt;br /&gt;
The ID number is an alpha numeric field.  It has several potential uses. Generally it is not displayed to students.  However, it can be used to match this course against an external system&#039;s ID, as your course catalog ID or can be used in the certificate module as a printed field.&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
The summary of the course is displayed in the course listings.&lt;br /&gt;
&lt;br /&gt;
==Format==&lt;br /&gt;
&lt;br /&gt;
A Moodle course may use one of the following three formats:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weekly format&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The course is organised week by week, with a clear start date and a finish date. Each week consists of activities. Some of them, like journals, may have &amp;quot;open windows&amp;quot; of, say, two weeks after which they become unavailable.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Topics format&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Very similar to the weekly format, except that each &amp;quot;week&amp;quot; is called a topic. A &amp;quot;topic&amp;quot; is not restricted to any time limit. You don&#039;t need to specify any dates.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Social format&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This format is oriented around one main forum, the Social forum, which appears listed on the main page. It is useful for situations that are more freeform. They may not even be courses. For example, it could be used as a departmental notice board.&lt;br /&gt;
&lt;br /&gt;
In Moodle 1.6 this is increased by:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;LAMS course format&#039;&#039;&#039; [[LAMS]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SCORM format&#039;&#039;&#039; [[SCORM]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weekly format, CSS/no tables&#039;&#039;&#039;&lt;br /&gt;
Just an educated guess: This version of the weekly format uses the more modern web layout system CSS (cascading style sheets) to place things on the web page in a more flexible way than the old method with tables.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;non-standard formats&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
such as a patch to allow javascript-based [[layout course editing]]&lt;br /&gt;
&lt;br /&gt;
==Course start date==&lt;br /&gt;
&lt;br /&gt;
This is where you specify the starting time of the course (in your own timezone).&lt;br /&gt;
&lt;br /&gt;
If you are using a &#039;weekly&#039; course format, this will affect the display of the weeks. The first week will start on the date you set here.&lt;br /&gt;
&lt;br /&gt;
This setting will not affect courses using the &#039;social&#039; or &#039;topics&#039; formats.&lt;br /&gt;
&lt;br /&gt;
However, one place this setting will be affect is the display of logs, which use this date as the earliest possible date you can display.&lt;br /&gt;
&lt;br /&gt;
In general, if your course does have a real starting date then it makes sense to set this date to that, no matter what course formats you are using.&lt;br /&gt;
&lt;br /&gt;
==Enrolment duration==&lt;br /&gt;
&lt;br /&gt;
This setting specifies the number of days a student can be enrolled in this course (starting from the moment they enroll).&lt;br /&gt;
&lt;br /&gt;
If this is set, then students are automatically unenrolled after the specified time has elapsed. This is most useful for rolling courses without a specific start or end time.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t set this then the student will remain in this course until they are manually unenrolled or the clean-up function to remove defunct students takes effect.&lt;br /&gt;
&lt;br /&gt;
If you have selected to manage this course as a meta course, your enrolment period will not be used.&lt;br /&gt;
&lt;br /&gt;
==Number of weeks/topics==&lt;br /&gt;
&lt;br /&gt;
This setting is only used by the &#039;weekly&#039; and &#039;topics&#039; course formats.&lt;br /&gt;
&lt;br /&gt;
In the &#039;weekly&#039; format, it specifies the number of weeks that the course will run for, starting from the course starting date.&lt;br /&gt;
&lt;br /&gt;
In the &#039;topics&#039; format, it specifies the number of topics in the course.&lt;br /&gt;
&lt;br /&gt;
Both of these translate to the number of &amp;quot;boxes&amp;quot; down the middle of the course page.&lt;br /&gt;
&lt;br /&gt;
==Group mode==&lt;br /&gt;
&lt;br /&gt;
Here you can define the group mode at the course level. This will be the default group mode for all activities defined within that course. Learn more about [[Groups]]&lt;br /&gt;
&lt;br /&gt;
Note that you don&#039;t &#039;&#039;&#039;need&#039;&#039;&#039; to change this setting to enable groups. The default setting of this and &#039;Force&#039; enables each activity to have its group mode set individually.&lt;br /&gt;
&lt;br /&gt;
==Force==&lt;br /&gt;
&lt;br /&gt;
If the group mode is &amp;quot;forced&amp;quot; at a course-level, then this particular group mode will be applied to every activity in that course. Individual group settings in each activity are then ignored.&lt;br /&gt;
&lt;br /&gt;
This is useful when, for example, one wants to set up a course for a number of completely separate cohorts.&lt;br /&gt;
&lt;br /&gt;
==Availability==&lt;br /&gt;
&lt;br /&gt;
This option allows you to &amp;quot;hide&amp;quot; your course completely. It will not appear on any course listings, except to teachers of the course and administrators. Even if students try to access the course URL directly, they will not be allowed to enter.&lt;br /&gt;
&lt;br /&gt;
==Enrolment key==&lt;br /&gt;
&lt;br /&gt;
A course enrolment key enables access to courses to be restricted to those who know the key.&lt;br /&gt;
&lt;br /&gt;
If left blank, then anyone who has created a Moodle username on the site will be able to enrol in the  course.&lt;br /&gt;
&lt;br /&gt;
If a key is specified, then students who are trying to enter will be asked to supply the key. Once enrolled, Students are not required to enter an enrollment key to gain access.&lt;br /&gt;
&lt;br /&gt;
The idea is that Teachers supply the key to authorised people using another means like private email, snail mail, on the phone or even verbally in a face to face class.&lt;br /&gt;
&lt;br /&gt;
If this password &amp;quot;gets out&amp;quot; and you have unwanted people enrolling, you can unenrol them (see their user profile page) and change this key. Any legitimate students who have already enrolled will not be affected, but the unwanted people won&#039;t be able to get back in.&lt;br /&gt;
&lt;br /&gt;
==Guest access==&lt;br /&gt;
&lt;br /&gt;
You have the choice of allowing [[Guest access | &amp;quot;guests&amp;quot;]] into your course.&lt;br /&gt;
&lt;br /&gt;
People can log in as guests using the &amp;quot;Login as a guest&amp;quot; button on the login screen.&lt;br /&gt;
&lt;br /&gt;
Guests ALWAYS have &amp;quot;read-only&amp;quot; access - meaning they can&#039;t leave any posts or otherwise mess up the course for real students.&lt;br /&gt;
&lt;br /&gt;
This can be handy when you want to let a colleague in to look around at your work, or to let students see a course before they have decided to enrol.&lt;br /&gt;
&lt;br /&gt;
Note that you have a choice between two types of guest access: with the enrolment key or without. If you choose to allow guests who have the key, then the guest will need to provide the current enrolment key EVERY TIME they log in (unlike students who only need to do it once). This lets you restrict your guests. If you choose to allow guests without a key, then anyone can get straight into your course.&lt;br /&gt;
&lt;br /&gt;
==Cost==&lt;br /&gt;
&lt;br /&gt;
Course cost. This will be shown if you have selected another enrolment method except internal.&lt;br /&gt;
&lt;br /&gt;
==Hidden sections==&lt;br /&gt;
&lt;br /&gt;
This option allows you to decide how the hidden sections in your course are displayed to students.&lt;br /&gt;
&lt;br /&gt;
By default, a small area is shown (in collapsed form, usually gray) to indicate where the hidden section is, though they still can not actually see the hidden activities and texts. This is particularly useful in the Weekly format, so that non-class weeks are clear.&lt;br /&gt;
&lt;br /&gt;
If you choose, these can be completely hidden, so that students don&#039;t even know sections of the course are hidden.&lt;br /&gt;
&lt;br /&gt;
==News items to show==&lt;br /&gt;
&lt;br /&gt;
A special forum called &amp;quot;News&amp;quot; appears in the &amp;quot;weekly&amp;quot; and &amp;quot;topics&amp;quot; course formats. It&#039;s a good place to post notices for all students to see. (By default, all students are subscribed to this forum, and will receive your notices by email.)&lt;br /&gt;
&lt;br /&gt;
This setting determines how many recent items appear on your course home page, in a news box down the right-hand side.&lt;br /&gt;
&lt;br /&gt;
If you set it to &amp;quot;0 news items&amp;quot; then the news box won&#039;t even appear.&lt;br /&gt;
&lt;br /&gt;
==Show grades==&lt;br /&gt;
&lt;br /&gt;
Many of the activities allow grades to be set.&lt;br /&gt;
&lt;br /&gt;
By default, the results of all grades within the course can be seen in the Grades page, available from the main course page.&lt;br /&gt;
&lt;br /&gt;
If a teacher is not interested in using grades in a course, or just wants to hide grades from students, then they can disable the display of grades in the Course Settings. This does not prevent individual activities from using or setting grades, it just disables the results being displayed to students.&lt;br /&gt;
&lt;br /&gt;
==Show activity reports==&lt;br /&gt;
&lt;br /&gt;
Activity reports are available for each participant that show their activity in the current course. As well as listings of their contributions, these reports include detailed access logs.&lt;br /&gt;
&lt;br /&gt;
Teachers always have access to these reports, using the button visible on each persons&#039;s profile page.&lt;br /&gt;
&lt;br /&gt;
Student access to their own reports is controlled by the teacher via a course setting. For some courses these reports can be a useful tool for a student to reflect on their involvement and appearance within the online environment, but for some courses this may not be necessary.&lt;br /&gt;
&lt;br /&gt;
Another reason for turning it off is that the report can place a bit of load on the server while being generated. For large or long classes it may be more efficient to keep it off.&lt;br /&gt;
&lt;br /&gt;
==Maximum upload size==&lt;br /&gt;
&lt;br /&gt;
This setting defines the largest size of file that can be uploaded by students in this course, limited by the site wide setting created by the administrator.&lt;br /&gt;
&lt;br /&gt;
It is possible to further restrict this size through settings within each activity module.&lt;br /&gt;
&lt;br /&gt;
==Your word for Teacher/Teachers/Student/Students==&lt;br /&gt;
&lt;br /&gt;
You can change the words for teacher and student for a particular course.&lt;br /&gt;
&lt;br /&gt;
==Force language==&lt;br /&gt;
&lt;br /&gt;
If you force a language in a course, the interface of Moodle in this course will be in this particular language, even if a student has selected a different preferred language in his/her personal profile.&lt;br /&gt;
&lt;br /&gt;
==Is this a meta course?==&lt;br /&gt;
&lt;br /&gt;
[[Metacourses]] are courses which take their enrolments from courses i.e. for every course &#039;enrolled&#039; on the metacourse, all students in the course are enrolled in the metacourse.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Teacher|Course/edit]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=15622</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=15622"/>
		<updated>2006-09-10T07:10:18Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* lesson_question_instances */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please note that this page deals with a future version of [[Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table. (does not exist in moodle 1.6.1 standard)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1 but there is different set of fields in lesson_branch)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Sorry, I did not see this until I had added my comments inline. I hope that is not too much of a problem.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=15621</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=15621"/>
		<updated>2006-09-10T07:09:40Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* lesson_branches */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please note that this page deals with a future version of [[Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1 but there is different set of fields in lesson_branch)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Sorry, I did not see this until I had added my comments inline. I hope that is not too much of a problem.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=15620</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=15620"/>
		<updated>2006-09-10T07:08:53Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* lesson_branches */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please note that this page deals with a future version of [[Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Sorry, I did not see this until I had added my comments inline. I hope that is not too much of a problem.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=15619</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=15619"/>
		<updated>2006-09-10T06:51:04Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* lesson_default */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please note that this page deals with a future version of [[Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Sorry, I did not see this until I had added my comments inline. I hope that is not too much of a problem.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Modules]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=14924</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=14924"/>
		<updated>2006-08-27T00:26:51Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* setting up marking block for moodle 1.6+ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* Bruno Vernier cleaned up marking block for moodle 1.6 as an attachment in http://moodle.org/mod/forum/discuss.php?d=52184#240002&lt;br /&gt;
** please send him any bugs and suggestions (unless someone else wishes to maintain this block)&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=14923</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=14923"/>
		<updated>2006-08-26T23:15:51Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* setting up marking block for moodle 1.6+ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* now the one in http://download.moodle.org/download.php/modules/block_marking_1.5.zip is chronologically the latest (as of aug 25, 2006)&lt;br /&gt;
** it seems to work in 1.6 (despite its 1.5 label) according to Mike Churchward and Bruno Vernier  (not thoroughly tested)&lt;br /&gt;
** there are some Warning notices (in debug mode only) aug 26, 2006&lt;br /&gt;
** also clicking on the links produces &amp;quot;parameter missing&amp;quot; errors ... it needs to use optional_param instead of optional_variable&lt;br /&gt;
** get the corrected marking.php from http://moodle.org/mod/forum/discuss.php?d=52184#239991&lt;br /&gt;
** switch lang files too (the correct lang file is in block/marking/lang/en/blocks_marking.php)&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=14922</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=14922"/>
		<updated>2006-08-26T22:50:36Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* setting up marking block for moodle 1.6+ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* now the one in http://download.moodle.org/download.php/modules/block_marking_1.5.zip is chronologically the latest (as of aug 25, 2006)&lt;br /&gt;
** it seems to work in 1.6 (despite its 1.5 label) according to Mike Churchward and Bruno Vernier  (not thoroughly tested)&lt;br /&gt;
** there are some Warning notices (in debug mode only) aug 26, 2006&lt;br /&gt;
** also clicking on the links produces &amp;quot;parameter missing&amp;quot; errors ... it needs to use optional_param instead of optional_variable&lt;br /&gt;
** get the corrected marking.php from http://moodle.org/mod/forum/discuss.php?d=52184#239991&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=14921</id>
		<title>Marking block</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/501/en/index.php?title=Marking_block&amp;diff=14921"/>
		<updated>2006-08-26T22:31:24Z</updated>

		<summary type="html">&lt;p&gt;Bruno: /* setting up marking block for moodle 1.6+ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Marking&#039;&#039;&#039; block is a Moodle block add-on that provides a summary of activities awaiting grading. It includes a separate page that provides an alternate gradebook functionality ties to the marking block. This block is restricted to teachers and administrators.&lt;br /&gt;
&lt;br /&gt;
This block displays marking information for newly submitted, resubmitted, and overdue (activities past their defined close dates) activities. The marking page provides the same information and easy access to the grading functions for these activities.&lt;br /&gt;
&lt;br /&gt;
This block cam also display a list of students below a certain grade level.&lt;br /&gt;
&lt;br /&gt;
The block can be configured to display a maximum number of students in each list and to set the grade level to display below.&lt;br /&gt;
&lt;br /&gt;
This directory uses custom code for all activities it summarizes. There are few common activity library functions that can perform the same operations, and thus any new activities to be added will need new code.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
{{Moodle 1.5}}&lt;br /&gt;
To install and use, unzip this file into your Moodle root directory making sure&lt;br /&gt;
that you &#039;use folder names&#039;. This will add a new block directory (marking) to&lt;br /&gt;
your &#039;/blocks&#039; directory and some language files to your langage directory.&lt;br /&gt;
Once unzipped, visit your admin screen and configure the new block the way you&lt;br /&gt;
want.&lt;br /&gt;
&lt;br /&gt;
===setting up marking block for moodle 1.6+===&lt;br /&gt;
{{Moodle 1.6}}&lt;br /&gt;
* now the one in http://download.moodle.org/download.php/modules/block_marking_1.5.zip is chronologically the latest (as of aug 25, 2006)&lt;br /&gt;
** it seems to work in 1.6 (despite its 1.5 label) according to Mike Churchward and Bruno Vernier  (not thoroughly tested)&lt;br /&gt;
** there are some Warning notices (in debug mode only) aug 26, 2006&lt;br /&gt;
** also clicking on the links produces &amp;quot;parameter missing&amp;quot; errors ... looks like it needs to use optional_param instead of require_variable&lt;br /&gt;
&lt;br /&gt;
==Credits==&lt;br /&gt;
&lt;br /&gt;
The marking block has been designed and built with the contributions of the&lt;br /&gt;
following people:&lt;br /&gt;
* Fernando Oliviera - G8 First Nation Schools &amp;gt; original design concept of the marking page&lt;br /&gt;
* Darren Smith - Egglescliffe School &amp;gt; orginal design concept of the marking block, and additional design of the marking page&lt;br /&gt;
* Mike Churchward - churchward.ca (mike AT churchward DOT ca)&amp;gt; original technical design and development&lt;br /&gt;
&lt;br /&gt;
==To do==&lt;br /&gt;
&lt;br /&gt;
* Make sure all strings are in language file&lt;br /&gt;
* Allow configuration of each section (i.e. enable/disable &#039;below average list&#039;)&lt;br /&gt;
* Create a local block library file and better compartmentalize functions&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* [http://download.moodle.org/download.php/modules/block_marking.zip Download]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=45432 Link to forum post with a lang/en file with all strings filled in]&lt;br /&gt;
&lt;br /&gt;
[[Category:Block (non-standard)]]&lt;/div&gt;</summary>
		<author><name>Bruno</name></author>
	</entry>
</feed>