<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Raymor</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Raymor"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Raymor"/>
	<updated>2026-06-08T06:41:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Logging_2&amp;diff=46161</id>
		<title>Logging 2</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Logging_2&amp;diff=46161"/>
		<updated>2014-08-18T21:48:18Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Benefits of the new logging system */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox Project&lt;br /&gt;
|name = Logging stage 2&lt;br /&gt;
|state = Completed&lt;br /&gt;
|tracker = MDL-37658&lt;br /&gt;
|discussion = https://moodle.org/mod/forum/discuss.php?d=235318&lt;br /&gt;
|assignee = moodle.com BACKEND team&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Benefits of the new logging system =&lt;br /&gt;
A few benefits of the new logging system are:&lt;br /&gt;
* it allows capture of richer information from Moodle about actions;&lt;br /&gt;
* it provides control over how much information is logged;&lt;br /&gt;
* it abstracts log writing and reading so logging can be scaled;&lt;br /&gt;
* it lets you write/read logs to/from any external system through the use of logstore plugins;&lt;br /&gt;
* it allows control over how much logging history is kept; and&lt;br /&gt;
* it supports research, reporting and analytics.&lt;br /&gt;
&lt;br /&gt;
== Why is Logging an important topic? ==&lt;br /&gt;
&lt;br /&gt;
Logging is fundamental to research, reporting and analytics. Logging allows informed, evidence based decisions to be made.&lt;br /&gt;
&lt;br /&gt;
It is important that changes to Moodle are based on measured data.  We need to be able to:&lt;br /&gt;
* prove there is a problem and&lt;br /&gt;
* prove that a given change is an improvement.&lt;br /&gt;
&lt;br /&gt;
Logging data can be used by different Moodle users.&lt;br /&gt;
* Better data allows researchers to study what happens in online teaching.&lt;br /&gt;
* Better data gives admins more feedback on how to run their site - both technically and in relation to processes. (Please note this change is not about profiling).&lt;br /&gt;
* Better data gives teachers better feedback to improve their teaching processes.&lt;br /&gt;
* Better data gives students better feedback to improve their learning.&lt;br /&gt;
&lt;br /&gt;
We can&#039;t predict all forms of analysis that might happen in future.&lt;br /&gt;
* The logging system needs to be flexible in order to accommodate applications by these different users.&lt;br /&gt;
* The logging API needs to be constructed in a way that is possible to improve in future.&lt;br /&gt;
&lt;br /&gt;
== Problems with the old logging approach ==&lt;br /&gt;
&lt;br /&gt;
The old logging infrastructure had a number of issues that were resolved by this project.&lt;br /&gt;
* Logging was added ad-hoc by developers and had spotty coverage.&lt;br /&gt;
* Some logged actions did not contain important information needed later.&lt;br /&gt;
* There were performance and scalability problems, such as:&lt;br /&gt;
** log tables were joined in many popular queries and were slow;&lt;br /&gt;
** logged events were stored in a single Moodle database table, which was not scalable;&lt;br /&gt;
** it was not possible to configure levels of logging ; and&lt;br /&gt;
** it was not possible to disable logging completely.&lt;br /&gt;
&lt;br /&gt;
= Logging =&lt;br /&gt;
&lt;br /&gt;
The new [[Event 2|Events API]] introduced in Moodle 2.6 provides a notification mechanism and single collection point for actions within Moodle. The Events system also defines information about events that can be extended with additional information and functionality by core code and plugins, as needed.&lt;br /&gt;
&lt;br /&gt;
In order to capture events a logging API was specified, consisting of a number of plugin types.&lt;br /&gt;
&lt;br /&gt;
To transition from the old logging system to the new, work was required in a number of areas.&lt;br /&gt;
&lt;br /&gt;
* In places where we previously added information to &#039;the&#039; log table, we must instead generate a new event.&lt;br /&gt;
* The standard Moodle distribution now includes three simple logging storage plugins that will store events in new format (to an internal or external database).&lt;br /&gt;
* The original logging code and DB tables are available for full backwards compatibility for users of customised reports. It is possible to enable logging to the old {log} table if required.&lt;br /&gt;
* All standard reports have been upgraded to use the new logging system and use a logging retrieval plugin to access log information.&lt;br /&gt;
* Custom report plugins (add-ons) will be able to query the {log} table, but should ideally shift to the new logging system over time, so that sites are not forced to continue double logging.&lt;br /&gt;
&lt;br /&gt;
== Old log usage analysis ==&lt;br /&gt;
&lt;br /&gt;
See [[Logging_usage|this analysis]] to see log usage in Moodle 2.5 core code.&lt;br /&gt;
&lt;br /&gt;
== Example scenario ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Writing to the log&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# A student submits an assignment.&lt;br /&gt;
# An event is triggered by the Assignment module.&lt;br /&gt;
# The log manager plugin observes the event and determines if it is log-worthy depending on some admin settings.&lt;br /&gt;
# The log manager sends the event to all enabled log storage subplugins implementing \tool_log\log\writer. Storage plugins may decide to filter out some events based on their admin settings.&lt;br /&gt;
# The log store plugin(s) stores the event data optionally including extra information such as remote IP or original logged-in-as user id.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reading from the log&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# A teacher opens an activity report.&lt;br /&gt;
# The activity report queries available log readers by using the current log manager (implementing \core\log\manager).&lt;br /&gt;
# If there is more than one log reader (implementing \core\log\sql_select_reader) available they can select the source of data for the report.&lt;br /&gt;
# The report requests events from the log reader and displays them.&lt;br /&gt;
&lt;br /&gt;
== From event to report ==&lt;br /&gt;
&lt;br /&gt;
There are four steps of how event is captured, logged and potentially presented in a report. These steps are summarised in [[#Figure1|Figure 1]] below and can be described as follows.&lt;br /&gt;
&lt;br /&gt;
# Handling of events and filtering what needs to be logged. See interface \core\log\manager below.&lt;br /&gt;
# Storing the event data in the log storage (DB, filesystem, etc.). See interface \tool_log\log\writer below.&lt;br /&gt;
# Retrieving the data from log storage - each plugin implements some methods to query and extract logs back to Moodle. See interfaces \core\log\reader and \core\log\sql_reader below.&lt;br /&gt;
# Displaying the data in the report.&lt;br /&gt;
&lt;br /&gt;
One plugin may cover multiple steps. For example we expect that most of log writer plugins will also implement log reader. It is also possible to create a report that has built-in event handling, log writing and reading and report presentation (all four steps). Also external logging systems may not wish to allow log data they capture to be read back into Moodle, handling such data instead through an external system, so they may not implement steps 3 and 4.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;Figure1&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;&lt;br /&gt;
[[File:logging_plugins_relation.png]]&lt;br /&gt;
&#039;&#039;&#039;Figure 1. Logging plugins relationship diagram&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [[#Figure2|Figure 2]] below shows how the requests are made between user actions, plugins and core when:&lt;br /&gt;
&lt;br /&gt;
* configuring logging (which log writer plugins are enabled);&lt;br /&gt;
* an event occurs;&lt;br /&gt;
* a report is configured (selecting log store) and&lt;br /&gt;
* a report is viewed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;Figure2&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:logging_sequence.png|logging_sequence.png]]&lt;br /&gt;
&#039;&#039;&#039;Figure 2. Logging plugins sequence diagram&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Public API ==&lt;br /&gt;
&lt;br /&gt;
This section describes all interfaces that need to be implemented by log manager and each log storage class.&lt;br /&gt;
&lt;br /&gt;
=== Reading API ===&lt;br /&gt;
* &#039;&#039;&#039;function \get_log_manager()&#039;&#039;&#039; - returns the current log manager if configured or some dummy instance otherwise, it uses the signleton pattern.&lt;br /&gt;
* &#039;&#039;&#039;interface \core\log\manager&#039;&#039;&#039; - log manager interface, in standard distribution implemented by \tool_log\log\manager and \core\log\dummy_manager&lt;br /&gt;
** public function get_readers($interface = null) returns the active storages implementing reader interface, returns array(classname =&amp;gt; storage instance, ...)&lt;br /&gt;
* &#039;&#039;&#039;interface \core\log\reader&#039;&#039;&#039; - general event reader&lt;br /&gt;
** public function get_name() - returns name of the log storage, this will be used when selection data source in reports.&lt;br /&gt;
** public function get_description() - some help for admins.&lt;br /&gt;
** public function is_logging() - is latest data available?&lt;br /&gt;
* &#039;&#039;&#039;interface \core\log\sql_select_reader&#039;&#039;&#039; extends \core\log\reader - general log storage that supports sql selects (or emulates them)&lt;br /&gt;
** public function get_events_select($selectwhere, array $params, $order, $limitfrom, $limitnum) - returns event object instances matching given parameters.&lt;br /&gt;
** public function get_events_select_count($selectwhere, array $params) - returns number of events that would be returned from get_events() with the same parameters.&lt;br /&gt;
*** $selectwhere is supposed to be a limited sql predicate.&lt;br /&gt;
*** The set of operators allowed in $selectwhere are :- =, &amp;lt;&amp;gt;, &amp;gt;, &amp;gt;=, &amp;lt;, &amp;lt;=&lt;br /&gt;
*** The set of keywords allowed in $selectwhere are :- IN, BETWEEN, LIKE, IS NULL, IS NOT NULL&lt;br /&gt;
*** Logical operators OR, AND&lt;br /&gt;
*** NOT operator&lt;br /&gt;
*** ( and ) brackets&lt;br /&gt;
*** ? and :named parameter placeholders &lt;br /&gt;
*** Use of anything besides the mentioned keywords/operators is strictly forbidden.&lt;br /&gt;
* &#039;&#039;&#039;interface \core\log\sql_internal_reader&#039;&#039;&#039; extends \core\log\reader - log storage that can expose data as read-only database view or table.&lt;br /&gt;
** public function get_internal_log_table_name() - returns database table or view; structure is described in phpdocs, it will include all columns defined by log_sql&lt;br /&gt;
&lt;br /&gt;
Most reports are expected to use only the reading API. Please note that all non-sql readers need to somehow translate the $selectwhere SQL query syntax.&lt;br /&gt;
&lt;br /&gt;
When reports are searching for log readers, they use the get_log_manager()-&amp;gt;get_readers($interface = null) where $interface is the name of reader interface that the report supports.&lt;br /&gt;
If there are multiple readers returned by the log manager, then the report is responsible for letting the user choose which storage to create the report on.&lt;br /&gt;
&lt;br /&gt;
=== Writing API ===&lt;br /&gt;
* &#039;&#039;&#039;interface \tool_log\log\store&#039;&#039;&#039; - must be implemented by each store subplugin.&lt;br /&gt;
** public function __construct(\tool_log\log\manager $manager) - no parameters, configuration is taken from admin settings.&lt;br /&gt;
** public function dispose() - called when reading/writing finished.&lt;br /&gt;
* &#039;&#039;&#039;interface \tool_log\log\writer&#039;&#039;&#039; extends \tool_log\log\store - interface indicating the log store may be used for writing.&lt;br /&gt;
** public function write(\core\event\base $event) - called from event observer defined in log manager.&lt;br /&gt;
&lt;br /&gt;
The writing API is defined in tool_log plugin, the log stores are defined as new subplugin of this plugin.&lt;br /&gt;
&lt;br /&gt;
Each log store plugin will be responsible for filtering of events, it may use standardised admin settings and filtering or decide to implement custom filtering.&lt;br /&gt;
&lt;br /&gt;
== Standard logging plugins ==&lt;br /&gt;
&lt;br /&gt;
Standard Moodle distribution will include four plugins.&lt;br /&gt;
&lt;br /&gt;
=== Logging management plugin (tool_log) ===&lt;br /&gt;
&lt;br /&gt;
Defines:&lt;br /&gt;
&lt;br /&gt;
  class \tool_log\log\manager implements \core\log\manager;&lt;br /&gt;
&lt;br /&gt;
The log manager is responsible for step 1 from [[#Figure1|Figure 1]] above. It allows admins to configure which log store subplugin is enabled and in which order they appear. The log store plugins are implemented as tool_log subplugins with class &amp;quot;store&amp;quot; in their namespace (\logstore_xxxx\log\store).&lt;br /&gt;
&lt;br /&gt;
The log manager registers a &#039;*&#039; event observer, this observer is external - it means that events are received only when database transactions are not in progress.&lt;br /&gt;
&lt;br /&gt;
=== Standard log storage plugin (logstore_standard) ===&lt;br /&gt;
&lt;br /&gt;
Defines:&lt;br /&gt;
&lt;br /&gt;
  class \logstore_standard\log\store implements \core\log\sql_internal_reader, \tool_log\log\writer;&lt;br /&gt;
&lt;br /&gt;
The name logstore_standard does not seem to be optimal - &#039;&#039;logstore_db&#039;&#039; is not allowed because it collides with standard /db/ subdirectory in plugins and &#039;&#039;logstore_database&#039;&#039; should be probably reserved for external database logging (to prevent any confusion).&lt;br /&gt;
&lt;br /&gt;
This log storage plugin is responsible for steps 2 and 3 from [[#Figure1|Figure 1]] above. It is the primary replacement for the former {log} table. The performance will be similar to former log table, but for smaller sites, this simple default will suffice.&lt;br /&gt;
&lt;br /&gt;
Each plugin decides how much data is kept, when it is deleted, etc.&lt;br /&gt;
&lt;br /&gt;
==== Storage settings ====&lt;br /&gt;
&lt;br /&gt;
Each storage plugin with a writer interface is responsible for backlisting or filtering of events. Some of the examples of filtering that can done is as follows.&lt;br /&gt;
* Include guests actions (default &#039;&#039;Yes&#039;&#039;)&lt;br /&gt;
* Include log levels (default &#039;&#039;empty&#039;&#039;), accepts constants from [[Event_2#Level_property]]&lt;br /&gt;
* Include by CRUD (default &#039;&#039;empty&#039;&#039;), accepts C, R, U, and D&lt;br /&gt;
* Include by component (default &#039;&#039;empty&#039;&#039;)&lt;br /&gt;
* Include by event name (default &#039;&#039;empty&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
=== External database log storage plugin (logstore_database) ===&lt;br /&gt;
&lt;br /&gt;
Defines:&lt;br /&gt;
&lt;br /&gt;
  class \logstore_database\log\store implements \core\log\sql_select_reader, \tool_log\log\writer;&lt;br /&gt;
&lt;br /&gt;
This log storage plugin is responsible for step 2 only from [[#Figure1|Figure 1]] above. There will be no interface to read from it provided with Moodle core.&lt;br /&gt;
&lt;br /&gt;
=== Legacy log table reader (logstore_legacy) ===&lt;br /&gt;
&lt;br /&gt;
Defines:&lt;br /&gt;
&lt;br /&gt;
  class \logstore_legacy\log\store implements \core\log\sql_select_reader, \tool_log\log\store;&lt;br /&gt;
&lt;br /&gt;
This plugin will not conduct any log writing; it will translate existing {log} table data into the new event format and transforms new SQL selects to match the legacy table format. This serves as an emulation layer that allows new reports to access historical data stored in mdl_log table. Users will have to select this datasource manually if they want to see historical data that is not present in new log tables.&lt;br /&gt;
&lt;br /&gt;
In new reports the legacy data will be presented using a special legacy event class that can not be triggered: \logstore_legacy\event\legacy&lt;br /&gt;
&lt;br /&gt;
== Performance ==&lt;br /&gt;
&lt;br /&gt;
Compared to older Moodle versions, the new system will need to deal with higher number of log entries. This has been improved by buffering log entry writes together with new bulk insert operations in the DML layer. Helper traits were introduced \tool_log\helper\buffered_writer to help stores easily buffer the events.&lt;br /&gt;
&lt;br /&gt;
Running new and old event logging at the same time with result in twice the number of DB inserts. It is therefore recommended to disable the old logging as soon as possible.&lt;br /&gt;
&lt;br /&gt;
In [https://tracker.moodle.org/browse/MDL-42894 MDL-42894], a logging API comparison was done and it&#039;s results were promising.&lt;br /&gt;
{| class=&amp;quot;nicetable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Enabled Stores&lt;br /&gt;
! dbwrites&lt;br /&gt;
! dbreads&lt;br /&gt;
! Time used&lt;br /&gt;
! Session size&lt;br /&gt;
! Memory&lt;br /&gt;
! Server load&lt;br /&gt;
|-&lt;br /&gt;
| Legacy + Standard store&lt;br /&gt;
| Little increase&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Increased&lt;br /&gt;
|-&lt;br /&gt;
| Only Standard store&lt;br /&gt;
| Decrease&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Increased&lt;br /&gt;
|-&lt;br /&gt;
| Only Legacy store&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Decrease&lt;br /&gt;
|-&lt;br /&gt;
| Neither Legacy nor Standard store&lt;br /&gt;
| Decrease&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Same&lt;br /&gt;
| Decrease&lt;br /&gt;
|}&lt;br /&gt;
FYI: Serverload is showing worse in most cases, but as this was done on my local machine with all interference, I am ignoring this for now.&lt;br /&gt;
--[[User:Rajesh Taneja|Rajesh Taneja]] ([[User talk:Rajesh Taneja|talk]]) 16:19, 14 February 2014 (WST)&lt;br /&gt;
&lt;br /&gt;
== Screenshots ==&lt;br /&gt;
=== Log management page ===&lt;br /&gt;
[[File:event-observer.png |frame|center| Log management page]]&lt;br /&gt;
&lt;br /&gt;
=== Log store settings pages ===&lt;br /&gt;
[[File:event-observer-2.png |frame|center| settings page for a the standard log setup]]&lt;br /&gt;
[[File:external-log-settings.png |frame|center| settings page for an external log: Database setup]]&lt;br /&gt;
[[File:external-filter-logs.png |frame|center| settings page for an external log: Filtering]]&lt;br /&gt;
&lt;br /&gt;
== Overarching considerations ==&lt;br /&gt;
&lt;br /&gt;
We can&#039;t actually predict all use cases, so we must think generically and plan for worst cases. Here are some overarching principles that will be followed in the implementation of the new logging system.&lt;br /&gt;
&lt;br /&gt;
* Things that don&#039;t need to use logs should not use logs. (Recent activity, etc)&lt;br /&gt;
* Logging calls should be as cheap as possible.&lt;br /&gt;
* The Events API will be the central communication mechanism, allowing lots of potential information gathering tools to exist in future.&lt;br /&gt;
* Use plug-ins to determine where to put logs permanently (NoSQL, SAS, file...). Initially, the default will be to the current log table.&lt;br /&gt;
* Log everything we possibly can think of.&lt;br /&gt;
* Define log level settings (on each logging call) so different sites can choose what they want logged, which allows controls cotrol of log size, speed, etc..&lt;br /&gt;
* The functionality of the pre-existing function add_to_log() should be retained for backward compatibility, but allowing admins to disable it.&lt;br /&gt;
&lt;br /&gt;
= Reports =&lt;br /&gt;
&lt;br /&gt;
[[Logging usage#Reports]] describes current reports.&lt;br /&gt;
&lt;br /&gt;
= Migration to new logging API =&lt;br /&gt;
&lt;br /&gt;
== Follow-up Projects ==&lt;br /&gt;
&lt;br /&gt;
* Converting completion to use events - MDL-42897&lt;br /&gt;
* Developing a &#039;&#039;Timeline&#039;&#039; page/block so each user to see a stream of activity that is relevant to them individually - MDL-42898&lt;br /&gt;
&lt;br /&gt;
== Related ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Here are some ideas of how new even data and observers can be put to use.&#039;&#039;&#039; Please note that the log storage API is not optimised for these tasks.&lt;br /&gt;
* Timely notifications of critical events (defined by users), for example more than five people posted in the same forum within an hour.&lt;br /&gt;
* &amp;quot;Red circle&amp;quot; notification badge counter icons everywhere in Moodle highlighting things that a user needs to pay attention attention to, such as ???.&lt;br /&gt;
* Colour heatmaps overlaid on course pages showing recent usage patterns of the course.&lt;br /&gt;
* Visualisation of live activity across a whole site (for admins) (is that logging or event handling?)&lt;br /&gt;
* Live engagement analytics reporting ??? that take specific actions into account, such as ???.&lt;br /&gt;
* Identification of students at risk based on their involvement in the course (or lack of it).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Logging of exceptions, errors and debugging&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Logging of Errors and warnings is not part of this specification, it meeds to be handled via a completely separate mechanism.&lt;br /&gt;
** People report errors that cannot be duplicated. Logging errors with a stack trace, session variables and other relevant data could be useful for debugging.&lt;br /&gt;
* Standard logs may theoretically produce errors and exceptions that need to be logged somewhere else.&lt;br /&gt;
* There is no synchronization with server logs to help debugging performance issues. (This will not be addressed by new logging API.)&lt;br /&gt;
* There is no logging of error information to help debug Moodle issues. (This will not be addressed by new logging API.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Performance logging and profiling&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
We need to measure the performance of logging system and store the information somewhere.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Other&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* There is no mechanism for archiving, so old logs are deleted and lost.&lt;br /&gt;
* Log deletion is indiscriminate, with no control of what log information is deleted or retained.&lt;br /&gt;
&lt;br /&gt;
== Places where we need more logs ==&lt;br /&gt;
&lt;br /&gt;
The principle work of this project is to replace the existing logging API. Once the new system is in place, the coverage of logging around Moodle can be improved.&lt;br /&gt;
&lt;br /&gt;
Suggestions for places in Moodle where logging is needed should be reported as Tracker issues and linked to the Epic MDL-28443 &amp;quot;Action logging improvements&amp;quot;. Feel free to echo significant areas here.&lt;br /&gt;
&lt;br /&gt;
* Activities on site, course and activity administration pages.&lt;br /&gt;
* Micro activities in a page (more than one per load), such as ???.&lt;br /&gt;
* AJAX calls (eg on course page), such as ???.&lt;br /&gt;
* Logging of long events (such as an LDAP synchronisation) should have:&lt;br /&gt;
** one unique identifier per event (like for example postfix mail server) to help admin monitor the cron processes and&lt;br /&gt;
** at least 2 log entries (begining and end) for each event, possibly more.&lt;br /&gt;
* Should be careful about logging confidential information. Anonymous events can be used to controll privacy.&lt;br /&gt;
* Shouldn’t delete logs when course is deleted. There is no API to delete logs, each log storage controls the rotation or deleting of old data individually.&lt;br /&gt;
&lt;br /&gt;
=See also=&lt;br /&gt;
&lt;br /&gt;
* [[Event 2]]&lt;br /&gt;
* [[Migrating logging calls in plugins]]&lt;br /&gt;
* [[Migrating reports accessing logs]]&lt;br /&gt;
&lt;br /&gt;
Other logging systems:&lt;br /&gt;
* http://logstash.net/ &lt;br /&gt;
* http://fluentd.org/&lt;br /&gt;
* http://logging.apache.org/log4php/&lt;br /&gt;
&lt;br /&gt;
Examples of data-based learning technology development:&lt;br /&gt;
* http://onlinelibrary.wiley.com/doi/10.1111/j.1467-8535.2008.00928.x/abstract &lt;br /&gt;
* http://www.sciencedirect.com/science/article/pii/S0360131510000461 -&amp;gt; qtype_pmatch&lt;br /&gt;
* http://www.tandfonline.com/doi/abs/10.1080/02680513.2011.567754&lt;br /&gt;
* http://oro.open.ac.uk/24619/&lt;br /&gt;
* [http://www.adlnet.gov/tla/lrs/ A Learning Record Store (LRS)] is a system that stores the tracking statements communicated through the [https://github.com/adlnet/xAPI-Spec Experience API (xAPI)]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=45643</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=45643"/>
		<updated>2014-07-07T19:01:11Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
The question was:&lt;br /&gt;
&lt;br /&gt;
Should past activity completions be retroactively affected by changes to settings?&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
This question was decided by by Martin Dougiamas on Tue Mar 25 per tracker issue MDL-39624. Dougiamas decided:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Completion of an activity is final and not affected by future settings changes (unless you manually reset it and are warned loudly and students are informed).&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Documentation of the reasoning, pro and con, is below as it was posted prior to the decision being made.&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== Can changes for these two reasons be separated? (Not really.) ==&lt;br /&gt;
&lt;br /&gt;
(sam marshall)&lt;br /&gt;
&lt;br /&gt;
It will be technically difficult to separate the &#039;changing based on what a student has done&#039; from &#039;changing settings&#039;. I think we will need to make the behaviour consistent so that either of two rules applies:&lt;br /&gt;
&lt;br /&gt;
OPTION B: Once a &#039;completed&#039; or &#039;completed-passed&#039; completion status is obtained, it should not change unless a teacher manually resets it.&lt;br /&gt;
&lt;br /&gt;
OR (as supposedly true at present)&lt;br /&gt;
&lt;br /&gt;
OPTION A: All completion statuses should change if the conditions or data changes.&lt;br /&gt;
&lt;br /&gt;
(Note that I left completed-failed undefined because we want to let people retry things so it can&#039;t be 100% consistent this way...)&lt;br /&gt;
&lt;br /&gt;
In other words I don&#039;t think we should attempt to treat &#039;changes in data&#039; and &#039;changes in settings&#039; as distinct situations that can be handled differently, as the page above might imply. &lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s why I think it is impossible to treat the two cases (changes to actual data/user input vs changes to settings) as separate in general. Imagine that we are trying to do so (update &#039;completed&#039; to &#039;not completed&#039; for data changes, but not for setting changes). Consider this sequence:&lt;br /&gt;
&lt;br /&gt;
1. In a forum, 3 posts are required for completion.&lt;br /&gt;
&lt;br /&gt;
2. Student A makes 4 posts and is marked complete. Student B makes 3 posts and is marked complete.&lt;br /&gt;
&lt;br /&gt;
3. Somebody changes the settings so that 5 posts are now required. (This is a settings change, so completion states aren&#039;t updated.)&lt;br /&gt;
&lt;br /&gt;
4. Somebody deletes one of Student A&#039;s posts so that they now only have 3 posts. (This is a data change, so completion state is updated.)&lt;br /&gt;
&lt;br /&gt;
In this situation, there has been a change to the data, so if we are treating those as separate then it is correct to potentially mark the student as not complete. But we do not store the historical values of all the setting, so we have to consider this according to current data; i.e. every time somebody gets a post deleted the system needs to check if they still have more than 5, and student A does not. As a result, student A would be marked &#039;not complete&#039;.&lt;br /&gt;
&lt;br /&gt;
This would be unfair because both students A and B have made 3 valid posts but B is still marked complete and A is not. (Note: In the current system, both A and B would have been marked incomplete at stage 3. In Option B, both A and B would remain complete; a student C who only made their posts after step 3 would have a disadvantage, but at least that&#039;s more easily understood i.e. when teachers change the settings they know they are making it harder for people from now on.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[In other words, the new criteria would apply only to currently active students, and removing a post indicates activity. This would not be ideal, but it separating them may be better than the alternatives. - Ray Morris]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=45642</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=45642"/>
		<updated>2014-07-07T18:58:07Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
The question was:&lt;br /&gt;
&lt;br /&gt;
Should past activity completions be retroactively affected by changes to settings?&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
This question was decided by by Martin Dougiamas on Tue Mar 25 per tracker issue MDL-39624&lt;br /&gt;
&lt;br /&gt;
[[Completion of an activity is final and not affected by future settings changes (unless you manually reset it and are warned loudly and students are informed).]]&lt;br /&gt;
&lt;br /&gt;
Documentation of the reasoning, pro and con, is below as it was posted prior to the decision being made.&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== Can changes for these two reasons be separated? (Not really.) ==&lt;br /&gt;
&lt;br /&gt;
(sam marshall)&lt;br /&gt;
&lt;br /&gt;
It will be technically difficult to separate the &#039;changing based on what a student has done&#039; from &#039;changing settings&#039;. I think we will need to make the behaviour consistent so that either of two rules applies:&lt;br /&gt;
&lt;br /&gt;
OPTION B: Once a &#039;completed&#039; or &#039;completed-passed&#039; completion status is obtained, it should not change unless a teacher manually resets it.&lt;br /&gt;
&lt;br /&gt;
OR (as supposedly true at present)&lt;br /&gt;
&lt;br /&gt;
OPTION A: All completion statuses should change if the conditions or data changes.&lt;br /&gt;
&lt;br /&gt;
(Note that I left completed-failed undefined because we want to let people retry things so it can&#039;t be 100% consistent this way...)&lt;br /&gt;
&lt;br /&gt;
In other words I don&#039;t think we should attempt to treat &#039;changes in data&#039; and &#039;changes in settings&#039; as distinct situations that can be handled differently, as the page above might imply. &lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s why I think it is impossible to treat the two cases (changes to actual data/user input vs changes to settings) as separate in general. Imagine that we are trying to do so (update &#039;completed&#039; to &#039;not completed&#039; for data changes, but not for setting changes). Consider this sequence:&lt;br /&gt;
&lt;br /&gt;
1. In a forum, 3 posts are required for completion.&lt;br /&gt;
&lt;br /&gt;
2. Student A makes 4 posts and is marked complete. Student B makes 3 posts and is marked complete.&lt;br /&gt;
&lt;br /&gt;
3. Somebody changes the settings so that 5 posts are now required. (This is a settings change, so completion states aren&#039;t updated.)&lt;br /&gt;
&lt;br /&gt;
4. Somebody deletes one of Student A&#039;s posts so that they now only have 3 posts. (This is a data change, so completion state is updated.)&lt;br /&gt;
&lt;br /&gt;
In this situation, there has been a change to the data, so if we are treating those as separate then it is correct to potentially mark the student as not complete. But we do not store the historical values of all the setting, so we have to consider this according to current data; i.e. every time somebody gets a post deleted the system needs to check if they still have more than 5, and student A does not. As a result, student A would be marked &#039;not complete&#039;.&lt;br /&gt;
&lt;br /&gt;
This would be unfair because both students A and B have made 3 valid posts but B is still marked complete and A is not. (Note: In the current system, both A and B would have been marked incomplete at stage 3. In Option B, both A and B would remain complete; a student C who only made their posts after step 3 would have a disadvantage, but at least that&#039;s more easily understood i.e. when teachers change the settings they know they are making it harder for people from now on.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[In other words, the new criteria would apply only to currently active students, and removing a post indicates activity. This would not be ideal, but it separating them may be better than the alternatives. - Ray Morris]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Plugin_validation&amp;diff=44484</id>
		<title>Plugin validation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Plugin_validation&amp;diff=44484"/>
		<updated>2014-04-17T15:08:39Z</updated>

		<summary type="html">&lt;p&gt;Raymor: Fixed linked to policy on advertising&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before a plugin can be made available via the [http://moodle.org/plugins/ Moodle Plugins directory] it has to pass both an automatic and a manual validation process. The automatic checks are repeated for each new version of the plugin that is added, however the [http://moodle.org/mod/forum/discuss.php?d=192083#p837517 manual checks are only done for the initial release]. The aim is to complete manual checks within three working days of first submission, but sometimes based on timing and/or allocation of resources, it can take longer than that, so please be patient.&lt;br /&gt;
&lt;br /&gt;
==The process==&lt;br /&gt;
 Plugin submission --&amp;gt; Waiting for approval --&amp;gt; Approved.&lt;br /&gt;
 * Waiting for approval --&amp;gt; Needs more work --&amp;gt; Waiting for approval&lt;br /&gt;
 ** Click &#039;Schedule this plugin for re-approval&#039; under &#039;Admin block&#039; &amp;gt; &#039;{your plugin}&#039; &amp;gt; &#039;Schedule this plugin for re-approval&#039; when ready to go back into the approval queue.&lt;br /&gt;
&lt;br /&gt;
Note: Plugin approvers are always get notified on all plugins that aren&#039;t approved. Feel free to leave us messages in the plugin comments during this phase.&lt;br /&gt;
&lt;br /&gt;
==Automatic validation==&lt;br /&gt;
&lt;br /&gt;
===General rules for all plugin types===&lt;br /&gt;
* Plugin name with [[Frankenstyle]] prefix must be unique in moodle.org/plugins. If there is another plugin with the same name you must either add new versions to this plugin (if it is yours) or rename your plugin if the names are accidentally the same. First in first served.&lt;br /&gt;
* The plugin must be uploaded as a single zip file&lt;br /&gt;
* The zip file must contain a single subfolder, named after your plugin (although the validator can also automatically rename subfolders generated by repos such as GitHub, which appear in the form &#039;username-moodle-pluginname-branchname&#039;)&lt;br /&gt;
* The subfolder must be laid out in such a way that the uploaded file could be unzipped directly into the top-level folder for that plugin type (e.g. an activity plugin called &#039;myplugin&#039; should install correctly when unzipped in the Moodle /mod folder, creating a subfolder /mod/myplugin with all the standard files within it).&lt;br /&gt;
* The subfolder must contain a file called [[version.php]]. It should describe properties like &#039;version&#039;, &#039;requires&#039;, &#039;cron&#039;, &#039;component&#039;, &#039;maturity&#039;, &#039;release&#039; and &#039;dependencies&#039; . See exceptions below.&lt;br /&gt;
* Language file must be present in lang/en/FULLNAME.php (for Moodle 2.0+) or lang/en_utf8/FULLNAME.php (for Moodle 1.9). FULLNAME is the plugin name with frankenstyle prefix. See exceptions below.&lt;br /&gt;
* Language file must declare either $string[&#039;modulename&#039;] (for activity modules) or $string[&#039;filtername&#039;] (for Filters) or $string[&#039;pluginname&#039;] (for all other plugin types). See exceptions below.&lt;br /&gt;
* The names of all database tables should start with the full &#039;frankenstyle&#039; plugin name. For example block_myblock, or auth_paypal. See exceptions below.&lt;br /&gt;
* (Recommended) the subfolder should contain a file called README.txt (the validator can automatically rename other extensions to .txt) with details about the current release of the plugin.&lt;br /&gt;
&lt;br /&gt;
Note: If you prefer using a readme.md file, please create a [http://en.wikipedia.org/wiki/Symbolic_link symbolic link] from it to a README.txt file. This way users without any markdown reader can easily doubleclick to open and read the README.txt with their default text editor. See [http://en.wikipedia.org/wiki/NTFS_symbolic_link#Syntax mklink command for Windows] or [http://en.wikipedia.org/wiki/Symbolic_link#POSIX_and_Unix-like_operating_systems ln command for Unix-like systems].&lt;br /&gt;
&lt;br /&gt;
===Exceptions===&lt;br /&gt;
* [[version.php]] is required for Moodle 2.5 and onwards. It isn&#039;t strictly required (but it is always recommended) for older moodle versions for the following plugin types:&lt;br /&gt;
** Themes for Moodle 2.0 to 2.4&lt;br /&gt;
** Course formats for Moodle 2.0 to 2.4&lt;br /&gt;
** Blocks for Moodle 1.9&lt;br /&gt;
** Auth for Moodle 1.9&lt;br /&gt;
* language file is not required for plugins for Moodle 1.9 that are not activity modules&lt;br /&gt;
* $string[&#039;pluginname&#039;] is not required for plugins for Moodle 1.9 that are not activity modules&lt;br /&gt;
* Question types for Moodle versions &amp;lt;= 2.1 instead of $string[&#039;pluginname&#039;] should declare $string[NAME] (where NAME is the name of the plugin without frankenstyle prefix). Starting from 2.2 this was fixed and $string[&#039;pluginname&#039;] shall be used.&lt;br /&gt;
* database tables are allowed to skip mod_ prefix for activity modules&lt;br /&gt;
* database tables are allowed to have question_ prefix instead of qtype_ for Question types. This is for historical reasons, all newly developed plugins are encouraged to have qtype_ prefix.&lt;br /&gt;
&lt;br /&gt;
===Additional checks for activity modules===&lt;br /&gt;
* $module-&amp;gt;version defined in version.php&lt;br /&gt;
* $module-&amp;gt;requires defined in version.php&lt;br /&gt;
* file lib.php exists&lt;br /&gt;
* file lib.php contains “function xxxx_add_instance”&lt;br /&gt;
* file lib.php contains “function xxxx_update_instance”&lt;br /&gt;
* file view.php exists&lt;br /&gt;
* file index.php exists&lt;br /&gt;
* db/install.xml exists&lt;br /&gt;
* db/upgrade.php exists&lt;br /&gt;
* db/access.php exists&lt;br /&gt;
&lt;br /&gt;
===Checks for particular plugin types===&lt;br /&gt;
* Themes: file config.php exists&lt;br /&gt;
* Blocks: file block_xxxx.php exists&lt;br /&gt;
* Auth: file auth.php exists&lt;br /&gt;
* Course formats: file format.php exists&lt;br /&gt;
&lt;br /&gt;
==The Other category in the plugins directory==&lt;br /&gt;
&lt;br /&gt;
If your plugin does not yet meet all the different standards, you are encouraged to add it to the [https://moodle.org/plugins/browse.php?list=category&amp;amp;id=38 Moodle Plugins Directory Other category]. Plugins in this category will be excluded from any automated processes such as installations or updates. Then when the plugin is improved to meet the standards, it can be moved to an another category in the plugins directory.&lt;br /&gt;
&lt;br /&gt;
==Manual checks==&lt;br /&gt;
Before the plugin is publicly viewable a trusted reviewer will look through the code to make sure it is a valid plugin. Currently, these checks are completed by [https://moodle.org/user/view.php?id=1146834&amp;amp;course=5 Aparup Banerjee] (who is also part of the Sites team) and [http://moodle.org/user/view.php?id=51473&amp;amp;course=5 Anthony Borrow] (on a volunteer basis), so please bear with us if this sometimes takes a little longer than you expect. These checks include:&lt;br /&gt;
* The plugin installs cleanly&lt;br /&gt;
* It does not contain any obviously harmful code&lt;br /&gt;
* It is not a spam entry (This is somewhat along the lines of the [https://docs.moodle.org/24/en/Policy_on_Advertising policy on advertising] too)&lt;br /&gt;
* It is not a duplicate of an already uploaded plugin&lt;br /&gt;
* It mentions GPL license (if not a boilerplate atop every file then somewhere in the downloadable zip).  (or be [http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses| completely GPL compatible])&lt;br /&gt;
** On what the copyright should be, refer to https://moodle.org/mod/forum/discuss.php?d=213610#p1117434&lt;br /&gt;
* It has documentation and referenced URLs in basic english.&lt;br /&gt;
* It does not lead to unrelated sites which can simply be linked to in content nor have unnecessarily repeated links.&lt;br /&gt;
* Links that facilitate sharing (source control, issue tracker, documentation, discussion) are in the &#039;Useful links&#039; section where possible.&lt;br /&gt;
* Conventions are followed where possible. ( eg: https://docs.moodle.org/dev/Guidelines_for_contributed_code#How_to_submit_code)&lt;br /&gt;
* Table config_plugin (not config) is used to store settings particular to a plugin.&lt;br /&gt;
&lt;br /&gt;
Comments made during the review can usually be removed prior to approval if requested.&lt;br /&gt;
&lt;br /&gt;
===Recommended URLs===&lt;br /&gt;
We usually request for the following data to be entered along with the plugin entry in order to facilitate easier sharing of information and feedback. So, in order of recommendation, they are :&lt;br /&gt;
# [https://docs.moodle.org/dev/Guidelines_for_contributed_code#How_to_submit_code| Code repository], this could be any publicly accessible code repository.  The suggested naming convention of the repository is [https://docs.moodle.org/dev/Guidelines_for_contributed_code#How_to_submit_code| moodle-{plugintype}_{pluginname}].&lt;br /&gt;
#*Moodle development [https://docs.moodle.org/dev/Process#Develop_the_code_using_Git| uses git] almost 100% of the time as such lots of developers choose to have git repositories for their plugins too. There are popular public repositories, noteably github.com has some support on plugins directory for uploading of versions via a github repository plugin.&lt;br /&gt;
# Issue/Bug tracker. This is to enable users and other a quick link to easily report issues they encounter with your plugin. &lt;br /&gt;
#*You can choose to have a new component created in [https://tracker.moodle.org/browse/CONTRIB/| Tracker]. You can also choose to have it elsewhere as long as it is publicly accessible. (See [https://moodle.org/mod/forum/discuss.php?d=213419&amp;amp;mode=3| related discussion])&lt;br /&gt;
# Documentation. This could be at docs.moodle.org or anywhere publicly accessible.&lt;br /&gt;
# Website. This could be to demo, further describe or simply to link to one relevant page.&lt;br /&gt;
&lt;br /&gt;
===Other recommendations===&lt;br /&gt;
* Long and short descriptions are populated to allow for easy search/indexing of your plugin.&lt;br /&gt;
&lt;br /&gt;
==Frequently asked questions==&lt;br /&gt;
===Q: My code contains several components, why can&#039;t I distribute it as a single package?===&lt;br /&gt;
A: Moodle&#039;s architecture supposes that plugins are installed independently. However you can contact [https://moodle.org/user/view.php?id=1146834&amp;amp;course=5 Aparup] or [http://moodle.org/user/view.php?id=51473&amp;amp;course=5 Anthony] and ask for your plugins to be made into a set.&lt;br /&gt;
 &lt;br /&gt;
For versions from Moodle 2.2 onwards you can specify that one plugin depends on another in your [[version.php]] file.&lt;br /&gt;
&lt;br /&gt;
===Q: I don&#039;t know which Moodle plugin type I should use. Can I just make a &#039;local&#039; plugin and get it done?===&lt;br /&gt;
&lt;br /&gt;
A: Most of the time there will be an applicable plugin type that will fit your add-on plugin. Using an appropriate plugin type allows you to use the relevant [[API]] and provide users with a common user interface throughout Moodle.  This minimises work for you.  The plugin will also be more easily understood by administrators and more people will use it. &lt;br /&gt;
&lt;br /&gt;
We have seen that quite often a local plugin could actually have been an [[Admin tools|admin tool]] plugin, so consider if that is applicable in your case.&lt;br /&gt;
&lt;br /&gt;
Here is the full  [https://docs.moodle.org/dev/Plugins list of plugins] to choose from. If you think there is a need for a new plugin type, we&#039;re happy to consider API improvements.&lt;br /&gt;
&lt;br /&gt;
For more information about [[Local plugins]], see [https://moodle.org/mod/forum/discuss.php?d=224231 this clarification].&lt;br /&gt;
&lt;br /&gt;
===Q: I&#039;ve a plugin to share that requires closed (or non-GPL compatible) source software. Can i share this in the plugins directory? ===&lt;br /&gt;
&lt;br /&gt;
A: Yes you can but there are several things you must do to share this properly. Paraphrasing Martin, this is OK to be approved IF (and only if):&lt;br /&gt;
&lt;br /&gt;
 1) We give users FULL information on the dependency and what they need to do, in the description of the plugin.&lt;br /&gt;
 2) We make it explicit that the required code is closed source and that we cannot vouch for it. The risks are all theirs to judge from wherever they obtain the software.&lt;br /&gt;
&lt;br /&gt;
You can use the &#039;Potential privacy issues&#039; field when editing the plugin to help describe this clearly.&lt;br /&gt;
&lt;br /&gt;
Note: Your plugin must still satisfy other validations, such as not breaking moodle (without the required non-GPL software).&lt;br /&gt;
&lt;br /&gt;
===Q: How to help with language support to any plugin in the plugins directory?===&lt;br /&gt;
A: Read this post for the procedure - http://lang.moodle.org/mod/forum/discuss.php?d=2485&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[Plugin documentation]] for information on providing documentation for your plugin right here in docs.moodle.org&lt;br /&gt;
* [[Plugin reviews]] for information on how to volunteer to write plugin reviews&lt;br /&gt;
* Continuous integration with [https://docs.moodle.org/dev/Travis#Moodle_plugins Travis-ci].&lt;br /&gt;
&lt;br /&gt;
[[Category:Plugins]]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=44223</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=44223"/>
		<updated>2014-03-25T13:49:25Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
The question was:&lt;br /&gt;
&lt;br /&gt;
Should past activity completions be retroactively affected by changes to settings?&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
This question was decided by by Martin Dougiamas on Tue Mar 25 per tracker issue MDL-37993&lt;br /&gt;
&lt;br /&gt;
[[Completion of an activity is final and not affected by future settings changes (unless you manually reset it and are warned loudly and students are informed).]]&lt;br /&gt;
&lt;br /&gt;
Documentation of the reasoning, pro and con, is below as it was posted prior to the decision being made.&lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== Can changes for these two reasons be separated? (Not really.) ==&lt;br /&gt;
&lt;br /&gt;
(sam marshall)&lt;br /&gt;
&lt;br /&gt;
It will be technically difficult to separate the &#039;changing based on what a student has done&#039; from &#039;changing settings&#039;. I think we will need to make the behaviour consistent so that either of two rules applies:&lt;br /&gt;
&lt;br /&gt;
OPTION B: Once a &#039;completed&#039; or &#039;completed-passed&#039; completion status is obtained, it should not change unless a teacher manually resets it.&lt;br /&gt;
&lt;br /&gt;
OR (as supposedly true at present)&lt;br /&gt;
&lt;br /&gt;
OPTION A: All completion statuses should change if the conditions or data changes.&lt;br /&gt;
&lt;br /&gt;
(Note that I left completed-failed undefined because we want to let people retry things so it can&#039;t be 100% consistent this way...)&lt;br /&gt;
&lt;br /&gt;
In other words I don&#039;t think we should attempt to treat &#039;changes in data&#039; and &#039;changes in settings&#039; as distinct situations that can be handled differently, as the page above might imply. &lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s why I think it is impossible to treat the two cases (changes to actual data/user input vs changes to settings) as separate in general. Imagine that we are trying to do so (update &#039;completed&#039; to &#039;not completed&#039; for data changes, but not for setting changes). Consider this sequence:&lt;br /&gt;
&lt;br /&gt;
1. In a forum, 3 posts are required for completion.&lt;br /&gt;
&lt;br /&gt;
2. Student A makes 4 posts and is marked complete. Student B makes 3 posts and is marked complete.&lt;br /&gt;
&lt;br /&gt;
3. Somebody changes the settings so that 5 posts are now required. (This is a settings change, so completion states aren&#039;t updated.)&lt;br /&gt;
&lt;br /&gt;
4. Somebody deletes one of Student A&#039;s posts so that they now only have 3 posts. (This is a data change, so completion state is updated.)&lt;br /&gt;
&lt;br /&gt;
In this situation, there has been a change to the data, so if we are treating those as separate then it is correct to potentially mark the student as not complete. But we do not store the historical values of all the setting, so we have to consider this according to current data; i.e. every time somebody gets a post deleted the system needs to check if they still have more than 5, and student A does not. As a result, student A would be marked &#039;not complete&#039;.&lt;br /&gt;
&lt;br /&gt;
This would be unfair because both students A and B have made 3 valid posts but B is still marked complete and A is not. (Note: In the current system, both A and B would have been marked incomplete at stage 3. In Option B, both A and B would remain complete; a student C who only made their posts after step 3 would have a disadvantage, but at least that&#039;s more easily understood i.e. when teachers change the settings they know they are making it harder for people from now on.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[In other words, the new criteria would apply only to currently active students, and removing a post indicates activity. This would not be ideal, but it separating them may be better than the alternatives. - Ray Morris]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=44222</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=44222"/>
		<updated>2014-03-25T13:21:13Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
The question was:&lt;br /&gt;
&lt;br /&gt;
Should past activity completions be retroactively affected by changes to settings?&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
This question was decided by by Martin Dougiamas on Tue Mar 25 per tracker issue MDL-37993&lt;br /&gt;
https://tracker.moodle.org/browse/MDL-37993&lt;br /&gt;
&lt;br /&gt;
[[Completion of an activity is final and not affected by future settings changes (unless you manually reset it and are warned loudly and students are informed).]]&lt;br /&gt;
&lt;br /&gt;
Documentation of the reasoning, pro and con, is below as it was posted prior to the decision being made.&lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== Can changes for these two reasons be separated? (Not really.) ==&lt;br /&gt;
&lt;br /&gt;
(sam marshall)&lt;br /&gt;
&lt;br /&gt;
It will be technically difficult to separate the &#039;changing based on what a student has done&#039; from &#039;changing settings&#039;. I think we will need to make the behaviour consistent so that either of two rules applies:&lt;br /&gt;
&lt;br /&gt;
OPTION B: Once a &#039;completed&#039; or &#039;completed-passed&#039; completion status is obtained, it should not change unless a teacher manually resets it.&lt;br /&gt;
&lt;br /&gt;
OR (as supposedly true at present)&lt;br /&gt;
&lt;br /&gt;
OPTION A: All completion statuses should change if the conditions or data changes.&lt;br /&gt;
&lt;br /&gt;
(Note that I left completed-failed undefined because we want to let people retry things so it can&#039;t be 100% consistent this way...)&lt;br /&gt;
&lt;br /&gt;
In other words I don&#039;t think we should attempt to treat &#039;changes in data&#039; and &#039;changes in settings&#039; as distinct situations that can be handled differently, as the page above might imply. &lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s why I think it is impossible to treat the two cases (changes to actual data/user input vs changes to settings) as separate in general. Imagine that we are trying to do so (update &#039;completed&#039; to &#039;not completed&#039; for data changes, but not for setting changes). Consider this sequence:&lt;br /&gt;
&lt;br /&gt;
1. In a forum, 3 posts are required for completion.&lt;br /&gt;
&lt;br /&gt;
2. Student A makes 4 posts and is marked complete. Student B makes 3 posts and is marked complete.&lt;br /&gt;
&lt;br /&gt;
3. Somebody changes the settings so that 5 posts are now required. (This is a settings change, so completion states aren&#039;t updated.)&lt;br /&gt;
&lt;br /&gt;
4. Somebody deletes one of Student A&#039;s posts so that they now only have 3 posts. (This is a data change, so completion state is updated.)&lt;br /&gt;
&lt;br /&gt;
In this situation, there has been a change to the data, so if we are treating those as separate then it is correct to potentially mark the student as not complete. But we do not store the historical values of all the setting, so we have to consider this according to current data; i.e. every time somebody gets a post deleted the system needs to check if they still have more than 5, and student A does not. As a result, student A would be marked &#039;not complete&#039;.&lt;br /&gt;
&lt;br /&gt;
This would be unfair because both students A and B have made 3 valid posts but B is still marked complete and A is not. (Note: In the current system, both A and B would have been marked incomplete at stage 3. In Option B, both A and B would remain complete; a student C who only made their posts after step 3 would have a disadvantage, but at least that&#039;s more easily understood i.e. when teachers change the settings they know they are making it harder for people from now on.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[In other words, the new criteria would apply only to currently active students, and removing a post indicates activity. This would not be ideal, but it separating them may be better than the alternatives. - Ray Morris]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=44221</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=44221"/>
		<updated>2014-03-25T13:20:26Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
The question was &lt;br /&gt;
Should past activity completions be retroactively affected by changes to settings?&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
This question was decided by by Martin Dougiamas on Tue Mar 25 per tracker issue MDL-37993&lt;br /&gt;
https://tracker.moodle.org/browse/MDL-37993&lt;br /&gt;
&lt;br /&gt;
Completion of an activity is final and not affected by future settings changes (unless you manually reset it and are warned loudly and students are informed).&lt;br /&gt;
&lt;br /&gt;
Documentation of the reasoning, pro and con, is below as it was posted prior to the decision being made.&lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== Can changes for these two reasons be separated? (Not really.) ==&lt;br /&gt;
&lt;br /&gt;
(sam marshall)&lt;br /&gt;
&lt;br /&gt;
It will be technically difficult to separate the &#039;changing based on what a student has done&#039; from &#039;changing settings&#039;. I think we will need to make the behaviour consistent so that either of two rules applies:&lt;br /&gt;
&lt;br /&gt;
OPTION B: Once a &#039;completed&#039; or &#039;completed-passed&#039; completion status is obtained, it should not change unless a teacher manually resets it.&lt;br /&gt;
&lt;br /&gt;
OR (as supposedly true at present)&lt;br /&gt;
&lt;br /&gt;
OPTION A: All completion statuses should change if the conditions or data changes.&lt;br /&gt;
&lt;br /&gt;
(Note that I left completed-failed undefined because we want to let people retry things so it can&#039;t be 100% consistent this way...)&lt;br /&gt;
&lt;br /&gt;
In other words I don&#039;t think we should attempt to treat &#039;changes in data&#039; and &#039;changes in settings&#039; as distinct situations that can be handled differently, as the page above might imply. &lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s why I think it is impossible to treat the two cases (changes to actual data/user input vs changes to settings) as separate in general. Imagine that we are trying to do so (update &#039;completed&#039; to &#039;not completed&#039; for data changes, but not for setting changes). Consider this sequence:&lt;br /&gt;
&lt;br /&gt;
1. In a forum, 3 posts are required for completion.&lt;br /&gt;
&lt;br /&gt;
2. Student A makes 4 posts and is marked complete. Student B makes 3 posts and is marked complete.&lt;br /&gt;
&lt;br /&gt;
3. Somebody changes the settings so that 5 posts are now required. (This is a settings change, so completion states aren&#039;t updated.)&lt;br /&gt;
&lt;br /&gt;
4. Somebody deletes one of Student A&#039;s posts so that they now only have 3 posts. (This is a data change, so completion state is updated.)&lt;br /&gt;
&lt;br /&gt;
In this situation, there has been a change to the data, so if we are treating those as separate then it is correct to potentially mark the student as not complete. But we do not store the historical values of all the setting, so we have to consider this according to current data; i.e. every time somebody gets a post deleted the system needs to check if they still have more than 5, and student A does not. As a result, student A would be marked &#039;not complete&#039;.&lt;br /&gt;
&lt;br /&gt;
This would be unfair because both students A and B have made 3 valid posts but B is still marked complete and A is not. (Note: In the current system, both A and B would have been marked incomplete at stage 3. In Option B, both A and B would remain complete; a student C who only made their posts after step 3 would have a disadvantage, but at least that&#039;s more easily understood i.e. when teachers change the settings they know they are making it harder for people from now on.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[In other words, the new criteria would apply only to currently active students, and removing a post indicates activity. This would not be ideal, but it separating them may be better than the alternatives. - Ray Morris]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39937</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39937"/>
		<updated>2013-05-21T16:21:55Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is an open policy question:&lt;br /&gt;
Should past activity completions be retroactively affected by changes to settings?&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== Can changes for these two reasons be separated? (Not really.) ==&lt;br /&gt;
&lt;br /&gt;
(sam marshall)&lt;br /&gt;
&lt;br /&gt;
It will be technically difficult to separate the &#039;changing based on what a student has done&#039; from &#039;changing settings&#039;. I think we will need to make the behaviour consistent so that either of two rules applies:&lt;br /&gt;
&lt;br /&gt;
OPTION B: Once a &#039;completed&#039; or &#039;completed-passed&#039; completion status is obtained, it should not change unless a teacher manually resets it.&lt;br /&gt;
&lt;br /&gt;
OR (as supposedly true at present)&lt;br /&gt;
&lt;br /&gt;
OPTION A: All completion statuses should change if the conditions or data changes.&lt;br /&gt;
&lt;br /&gt;
(Note that I left completed-failed undefined because we want to let people retry things so it can&#039;t be 100% consistent this way...)&lt;br /&gt;
&lt;br /&gt;
In other words I don&#039;t think we should attempt to treat &#039;changes in data&#039; and &#039;changes in settings&#039; as distinct situations that can be handled differently, as the page above might imply. &lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s why I think it is impossible to treat the two cases (changes to actual data/user input vs changes to settings) as separate in general. Imagine that we are trying to do so (update &#039;completed&#039; to &#039;not completed&#039; for data changes, but not for setting changes). Consider this sequence:&lt;br /&gt;
&lt;br /&gt;
1. In a forum, 3 posts are required for completion.&lt;br /&gt;
&lt;br /&gt;
2. Student A makes 4 posts and is marked complete. Student B makes 3 posts and is marked complete.&lt;br /&gt;
&lt;br /&gt;
3. Somebody changes the settings so that 5 posts are now required. (This is a settings change, so completion states aren&#039;t updated.)&lt;br /&gt;
&lt;br /&gt;
4. Somebody deletes one of Student A&#039;s posts so that they now only have 3 posts. (This is a data change, so completion state is updated.)&lt;br /&gt;
&lt;br /&gt;
In this situation, there has been a change to the data, so if we are treating those as separate then it is correct to potentially mark the student as not complete. But we do not store the historical values of all the setting, so we have to consider this according to current data; i.e. every time somebody gets a post deleted the system needs to check if they still have more than 5, and student A does not. As a result, student A would be marked &#039;not complete&#039;.&lt;br /&gt;
&lt;br /&gt;
This would be unfair because both students A and B have made 3 valid posts but B is still marked complete and A is not. (Note: In the current system, both A and B would have been marked incomplete at stage 3. In Option B, both A and B would remain complete; a student C who only made their posts after step 3 would have a disadvantage, but at least that&#039;s more easily understood i.e. when teachers change the settings they know they are making it harder for people from now on.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[In other words, the new criteria would apply only to currently active students, and removing a post indicates activity. This would not be ideal, but it separating them may be better than the alternatives. - Ray Morris]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39689</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39689"/>
		<updated>2013-05-14T13:08:11Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is an open policy question:&lt;br /&gt;
Should past activity completions be retroactively affected by changes to settings?&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== Can changes for these two reasons be separated? (Not really.) ==&lt;br /&gt;
&lt;br /&gt;
(sam marshall)&lt;br /&gt;
&lt;br /&gt;
It will be technically difficult to separate the &#039;changing based on what a student has done&#039; from &#039;changing settings&#039;. I think we will need to make the behaviour consistent so that either of two rules applies:&lt;br /&gt;
&lt;br /&gt;
OPTION B: Once a &#039;completed&#039; or &#039;completed-passed&#039; completion status is obtained, it should not change unless a teacher manually resets it.&lt;br /&gt;
&lt;br /&gt;
OR (as supposedly true at present)&lt;br /&gt;
&lt;br /&gt;
OPTION A: All completion statuses should change if the conditions or data changes.&lt;br /&gt;
&lt;br /&gt;
(Note that I left completed-failed undefined because we want to let people retry things so it can&#039;t be 100% consistent this way...)&lt;br /&gt;
&lt;br /&gt;
In other words I don&#039;t think we should attempt to treat &#039;changes in data&#039; and &#039;changes in settings&#039; as distinct situations that can be handled differently, as the page above might imply. &lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s why I think it is impossible to treat the two cases (changes to actual data/user input vs changes to settings) as separate in general. Imagine that we are trying to do so (update &#039;completed&#039; to &#039;not completed&#039; for data changes, but not for setting changes). Consider this sequence:&lt;br /&gt;
&lt;br /&gt;
1. In a forum, 3 posts are required for completion.&lt;br /&gt;
&lt;br /&gt;
2. Student A makes 4 posts and is marked complete. Student B makes 3 posts and is marked complete.&lt;br /&gt;
&lt;br /&gt;
3. Somebody changes the settings so that 5 posts are now required. (This is a settings change, so completion states aren&#039;t updated.)&lt;br /&gt;
&lt;br /&gt;
4. Somebody deletes one of Student A&#039;s posts so that they now only have 3 posts. (This is a data change, so completion state is updated.)&lt;br /&gt;
&lt;br /&gt;
In this situation, there has been a change to the data, so if we are treating those as separate then it is correct to potentially mark the student as not complete. But we do not store the historical values of all the setting, so we have to consider this according to current data; i.e. every time somebody gets a post deleted the system needs to check if they still have more than 5, and student A does not. As a result, student A would be marked &#039;not complete&#039;.&lt;br /&gt;
&lt;br /&gt;
This would be unfair because both students A and B have made 3 valid posts but B is still marked complete and A is not. (Note: In the current system, both A and B would have been marked incomplete at stage 3. In Option B, both A and B would remain complete; a student C who only made their posts after step 3 would have a disadvantage, but at least that&#039;s more easily understood i.e. when teachers change the settings they know they are making it harder for people from now on.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[In other words, the new criteria would apply only to currently active students, and removing a post indicates activity. - Ray Morris]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39632</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39632"/>
		<updated>2013-05-13T18:58:15Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Summary */ removed extraneous / redundant word &amp;quot;might&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is an open policy question:&lt;br /&gt;
Should past activity completions be retroactively affected by changes to settings?&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== Can changes for these two reasons be separated? (Not really.) ==&lt;br /&gt;
&lt;br /&gt;
(sam marshall)&lt;br /&gt;
&lt;br /&gt;
It will be technically difficult to separate the &#039;changing based on what a student has done&#039; from &#039;changing settings&#039;. I think we will need to make the behaviour consistent so that either of two rules applies:&lt;br /&gt;
&lt;br /&gt;
OPTION B: Once a &#039;completed&#039; or &#039;completed-passed&#039; completion status is obtained, it should not change unless a teacher manually resets it.&lt;br /&gt;
&lt;br /&gt;
OR (as supposedly true at present)&lt;br /&gt;
&lt;br /&gt;
OPTION A: All completion statuses should change if the conditions or data changes.&lt;br /&gt;
&lt;br /&gt;
(Note that I left completed-failed undefined because we want to let people retry things so it can&#039;t be 100% consistent this way...)&lt;br /&gt;
&lt;br /&gt;
In other words I don&#039;t think we should attempt to treat &#039;changes in data&#039; and &#039;changes in settings&#039; as distinct situations that can be handled differently, as the page above might imply. &lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
Here&#039;s why I think it is impossible to treat the two cases (changes to actual data/user input vs changes to settings) as separate in general. Imagine that we are trying to do so (update &#039;completed&#039; to &#039;not completed&#039; for data changes, but not for setting changes). Consider this sequence:&lt;br /&gt;
&lt;br /&gt;
1. In a forum, 3 posts are required for completion.&lt;br /&gt;
&lt;br /&gt;
2. Student A makes 4 posts and is marked complete. Student B makes 3 posts and is marked complete.&lt;br /&gt;
&lt;br /&gt;
3. Somebody changes the settings so that 5 posts are now required. (This is a settings change, so completion states aren&#039;t updated.)&lt;br /&gt;
&lt;br /&gt;
4. Somebody deletes one of Student A&#039;s posts so that they now only have 3 posts. (This is a data change, so completion state is updated.)&lt;br /&gt;
&lt;br /&gt;
In this situation, there has been a change to the data, so if we are treating those as separate then it is correct to potentially mark the student as not complete. But we do not store the historical values of all the setting, so we have to consider this according to current data; i.e. every time somebody gets a post deleted the system needs to check if they still have more than 5, and student A does not. As a result, student A would be marked &#039;not complete&#039;.&lt;br /&gt;
&lt;br /&gt;
This would be unfair because both students A and B have made 3 valid posts but B is still marked complete and A is not. (Note: In the current system, both A and B would have been marked incomplete at stage 3. In Option B, both A and B would remain complete; a student C who only made their posts after step 3 would have a disadvantage, but at least that&#039;s more easily understood i.e. when teachers change the settings they know they are making it harder for people from now on.)&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39610</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39610"/>
		<updated>2013-05-10T16:30:24Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Summary */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is an open policy question:&lt;br /&gt;
Should past activity completions might be retroactively affected by changes to settings?&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39609</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39609"/>
		<updated>2013-05-10T16:23:32Z</updated>

		<summary type="html">&lt;p&gt;Raymor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is an open policy question as to how past activity completions might be affected by changes to settings, whether or not certain changes should be retroactive.&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
[https://moodle.org/mod/forum/discuss.php?d=226129 Forum discussion of the question]&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-37993 Tracker issue which initiated the discussion]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39608</id>
		<title>Policy - Retroactive effects of completion settings</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Policy_-_Retroactive_effects_of_completion_settings&amp;diff=39608"/>
		<updated>2013-05-10T16:18:03Z</updated>

		<summary type="html">&lt;p&gt;Raymor: Created page with &amp;quot;== Summary ==   There is an open policy question as to how past activity completions might be affected by changes to settings, whether or not certain changes should be retroactiv...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is an open policy question as to how past activity completions might be affected by changes to settings, whether or not certain changes should be retroactive.&lt;br /&gt;
That is, after a student completes an activity and it&#039;s marked as &amp;quot;completed-passed&amp;quot;, &amp;quot;completed-failed&amp;quot;, etc., might it later become &amp;quot;incomplete&amp;quot;?  &lt;br /&gt;
&lt;br /&gt;
As one example, a student might complete a Quiz, with a passing grade.  The quiz is marked as completed-passed, which opens up a Certificate. The student prints the certificate and files it with regulators.&lt;br /&gt;
Six months later, the teacher decides that from now on the passing grade should be higher.  The teacher changes the &amp;quot;grade to pass&amp;quot; setting. Should the student who completed and passed six months prior now &lt;br /&gt;
be marked as &amp;quot;failed&amp;quot;, and their certificate revoked?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two major categories of actions were mentioned, and two types of &amp;quot;intentions&amp;quot;, or use-case scenarios, with different policies appearing reasonable depending on the type of &lt;br /&gt;
action and use-case or intention of the user.  Actions can be a) changes to what a student has done , such as submitting or deleting an assignment or b) settings/requirements adjustments by the teacher. &lt;br /&gt;
Settings changes may be the result of two types of intentions - a decision that the new requirements should be different from the old, or a correction to an incorrect setting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to what a student has done ==&lt;br /&gt;
&lt;br /&gt;
Sam Marshall gave two examples suggesting that when there is a change to what a student has done, that could change the fact that something the student completed something.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Example 1: If you just use &#039;on grade&#039; completion, if a student does something and gets a grade, it will be marked complete. If the teacher then deletes their grade from gradebook, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: In forum, if you set it to be complete after making 3 posts, and the student makes 3 posts, it will be marked complete. But if the teacher then deletes one of the posts, it will be marked incomplete again.&lt;br /&gt;
&lt;br /&gt;
It could be argued that things should not be automatically &#039;un-completed&#039; in this way (there are cases when both the above examples definitely seem appropriate, but it might be OK if the teacher had to manually un-complete them as well)&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
No reasoning was posted with an opposing view on what should happen when changes are made to &#039;&#039;what a student has done&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Changes to settings ==&lt;br /&gt;
&lt;br /&gt;
There are different opinions in regards to changes to settings, such as the grade required to pass.  If a student completes an activity, such as passing a test, and some time later the &amp;quot;grade to pass&amp;quot; is changed, should their &amp;quot;completed-passed&amp;quot; be changed to &amp;quot;completed-failed&amp;quot;, or should the changes apply &amp;quot;from now on&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Per Ekström wrote:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
I would say, no.&lt;br /&gt;
&lt;br /&gt;
As a student, you&#039;re given a deal; &amp;quot;Get a score of X or higher and you pass.&amp;quot; If the bar is raised, and it&#039;s applied retroactively, then you are basicly breaking your end of the bargain. A pass is a pass no matter what, even if a teacher afterwards raise to 80%. ...&lt;br /&gt;
&lt;br /&gt;
The most important thing with a grading system is that it&#039;s predictable and perceived fair. Retroactivity makes it everything but. Therefore I do not recommend it.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where Ekström uses the word &amp;quot;deal&amp;quot;, common law uses the word &amp;quot;contract&amp;quot;, and &amp;quot;breaking your end of the bargain&amp;quot; could be called &amp;quot;fraud&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Another example supporting this view was posted:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
 Working as a private investigator without passing the required classes and staying up with continuing education is a crime.  If I took the class and later the teacher changed the requirements and the system retroactively failed me, that would expose me, the student, to criminal charges.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A different view was expressed by Tim Hunt:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
As a teacher, you are only human. Sometimes you make mistakes. You accidentally create a quiz with a passing grade of 90% (or forget to set the passing grade so it defaults ot 0%?). Then some students attempt the quiz and point out the mistake to you, so then you correct it to 80% and expect Moodle to automatically fix the completion state for students who already got between 80 and 90%.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It was suggested that if the teacher knows they made a mistake and are correcting it, they can also correct the results of that mistake - manually changing passes to fails or vice-versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That is the open question - &#039;&#039;if settings/requirements are changed&#039;&#039;, should Moodle automatically, retroactively change prior completions based on the new settings?&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Activity_completion_API&amp;diff=39607</id>
		<title>Activity completion API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Activity_completion_API&amp;diff=39607"/>
		<updated>2013-05-10T15:07:26Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* See Also */  - removed &amp;quot;of of&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
Modules do not need to be changed to support conditional availability, but they do need changing to support the completion system. &lt;br /&gt;
&lt;br /&gt;
If you make no changes to a module whatsoever, it can only support &#039;manual&#039; completion (where the user ticks a box).&lt;br /&gt;
&lt;br /&gt;
== Feature support ==&lt;br /&gt;
&lt;br /&gt;
To support the completion system, your module must include a &#039;&#039;modulename&#039;&#039;&amp;lt;tt&amp;gt;_supports&amp;lt;/tt&amp;gt; function in its &amp;lt;tt&amp;gt;lib.php&amp;lt;/tt&amp;gt;. Here is an example:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * Indicates API features that the forum supports.&lt;br /&gt;
  *&lt;br /&gt;
  * @param string $feature&lt;br /&gt;
  * @return mixed True if yes (some features may use other values)&lt;br /&gt;
  */&lt;br /&gt;
 function forum_supports($feature) {&lt;br /&gt;
     switch($feature) {&lt;br /&gt;
         case FEATURE_COMPLETION_TRACKS_VIEWS: return true;&lt;br /&gt;
         case FEATURE_COMPLETION_HAS_RULES: return true;&lt;br /&gt;
         default: return null;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The relevant features for completion are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;FEATURE_COMPLETION_TRACKS_VIEWS&#039;&#039;&#039; - the module can support completion &#039;on view&#039;, meaning that an activity becomes marked complete as soon as a user clicks on it.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;FEATURE_GRADE_HAS_GRADE&#039;&#039;&#039; - the module provides (or may provide, depending on settings) a grade for students. When a module supports grades, it can support completion &#039;on grade&#039;, meaning that an activity becomes marked complete as soon as a user is assigned a grade.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;FEATURE_COMPLETION_HAS_RULES&#039;&#039;&#039; - the module has custom completion rules.&lt;br /&gt;
&lt;br /&gt;
== Completion on view ==&lt;br /&gt;
&lt;br /&gt;
Completion on view means that, if selected, an activity is marked complete as soon as the user views it. &#039;View&#039; is usually defined as seeing the module&#039;s main page; if you click on the activity, and there isn&#039;t an error, you have probably viewed it. However it is up to each module precisely how they define &#039;view&#039;.&lt;br /&gt;
&lt;br /&gt;
=== How to implement ===&lt;br /&gt;
&lt;br /&gt;
In your module&#039;s &#039;&#039;modulename&#039;&#039;&amp;lt;tt&amp;gt;_supports&amp;lt;/tt&amp;gt; function, return true for FEATURE_COMPLETION_TRACKS_VIEWS.&lt;br /&gt;
&lt;br /&gt;
Then add this code to run whenever a user successfully views the activity. In order for navigation to work as expected (i.e. so that the navigation block on the module&#039;s page takes account that you have viewed this activity, if there is another activity that depends on it) you should put this code before printing the page header.&lt;br /&gt;
&lt;br /&gt;
 $completion = new completion_info($course);&lt;br /&gt;
 $completion-&amp;gt;set_module_viewed($cm);&lt;br /&gt;
&lt;br /&gt;
=== Performance issues ===&lt;br /&gt;
&lt;br /&gt;
Calling this method has no significant performance cost if &#039;on view&#039; completion is not enabled for the activity. If it is enabled, then the performance cost is kept low because the &#039;viewed&#039; state is cached; it doesn&#039;t add a database query to every request.&lt;br /&gt;
&lt;br /&gt;
== Completion on grade ==&lt;br /&gt;
&lt;br /&gt;
Completion on grade means that, if selected, an activity is marked complete as soon as the user receives a grade from that activity.&lt;br /&gt;
&lt;br /&gt;
=== How to implement ===&lt;br /&gt;
&lt;br /&gt;
In your module&#039;s _supports function, return true for FEATURE_GRADE_HAS_GRADE. No other action is necessary.&lt;br /&gt;
&lt;br /&gt;
=== Performance issues ===&lt;br /&gt;
&lt;br /&gt;
When &#039;on grade&#039; completion is enabled, there will be some additional database queries after a grade is assigned or changed. Unless your activity changes grades very frequently, this is unlikely to be an issue.&lt;br /&gt;
&lt;br /&gt;
== Custom completion rules ==&lt;br /&gt;
&lt;br /&gt;
Custom completion rules allow for module-specific conditions. For example, the forum has custom rules so that you can make it mark a user completed when they make a certain number of posts to the forum.&lt;br /&gt;
&lt;br /&gt;
It is a lot harder to implement custom completion rules than it is to use the system-provided &#039;view&#039; or &#039;grade&#039; conditions, but the instructions below should help make it clear.&lt;br /&gt;
&lt;br /&gt;
=== Implementation overview ===&lt;br /&gt;
&lt;br /&gt;
To implement custom completion rules, you need to:&lt;br /&gt;
&lt;br /&gt;
# Return true for FEATURE_COMPLETION_HAS_RULES in your module&#039;s _supports function.&lt;br /&gt;
# Add database fields to your module&#039;s main table to store the custom completion settings.&lt;br /&gt;
# Add backup and restore code to back up these fields.&lt;br /&gt;
# Add controls to your module&#039;s settings form so that users can select the custom rules, altering these database settings.&lt;br /&gt;
# Add a function that checks the value of these rules (if set).&lt;br /&gt;
# Add code so that whenever the value affecting a rule might change, you inform the completion system.&lt;br /&gt;
&lt;br /&gt;
=== Database fields for completion settings ===&lt;br /&gt;
&lt;br /&gt;
When you provide a custom completion rule for a module, that rule requires data to be stored with each module instance: whether the rule is enabled for that instance, and any options that apply to the rule.&lt;br /&gt;
&lt;br /&gt;
Usually the best place to store this information is your module&#039;s main table because:&lt;br /&gt;
&lt;br /&gt;
* The information in the relevant row of this table is likely to be available in most parts of your code, so code changes are minimised.&lt;br /&gt;
* You already read this row with most requests, so there is no need for additional database queries which would reduce performance.&lt;br /&gt;
* The main table is used for most other module options so it is a logical place for this information.&lt;br /&gt;
&lt;br /&gt;
If you are adding a basic completion condition you probably only need to add one field. To add a field to an existing module, you need to change the install.xml and then the update.php in the same way as adding any other field.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Throughout this section I am using the forum as an example. The forum provides three completion options but because they all behave the same way, I am only showing one of them.&lt;br /&gt;
&lt;br /&gt;
The forum adds this field to store a completion option:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;completionposts&#039;&#039;&#039; - this may be 0 or an integer. If it&#039;s an integer, say 3, then the user needs to add 3 forum posts (either new discussions or replies) in order for the forum to count as &#039;completed&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Backup and restore for completion fields ===&lt;br /&gt;
&lt;br /&gt;
Modules do not need to back up the generic completion options, which are handled by the system, but they do need to back up any custom options. You should add backup and restore logic for the fields mentioned above. &lt;br /&gt;
&lt;br /&gt;
Remember that your restore code should handle the case when these fields are not present, setting the fields to a suitable default value.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
The following code in &amp;lt;tt&amp;gt;backup_forum_stepslib.php&amp;lt;/tt&amp;gt; lists the fields to back up:&lt;br /&gt;
&lt;br /&gt;
  $forum = new backup_nested_element(&#039;forum&#039;, array(&#039;id&#039;), array(&lt;br /&gt;
            &#039;type&#039;, &#039;name&#039;, &#039;intro&#039;, &#039;introformat&#039;,&lt;br /&gt;
            &#039;assessed&#039;, &#039;assesstimestart&#039;, &#039;assesstimefinish&#039;, &#039;scale&#039;,&lt;br /&gt;
            &#039;maxbytes&#039;, &#039;maxattachments&#039;, &#039;forcesubscribe&#039;, &#039;trackingtype&#039;,&lt;br /&gt;
            &#039;rsstype&#039;, &#039;rssarticles&#039;, &#039;timemodified&#039;, &#039;warnafter&#039;,&lt;br /&gt;
            &#039;blockafter&#039;, &#039;blockperiod&#039;, &#039;completiondiscussions&#039;, &#039;completionreplies&#039;,&lt;br /&gt;
            &#039;completionposts&#039;));&lt;br /&gt;
&lt;br /&gt;
As you can see, I added the &#039;&#039;&#039;completionposts&#039;&#039;&#039; field (and the others that aren&#039;t covered in this example) to the list of fields.&lt;br /&gt;
&lt;br /&gt;
=== Form changes for completion settings ===&lt;br /&gt;
&lt;br /&gt;
When you have custom completion conditions, you need to add controls to your module&#039;s settings form &amp;lt;tt&amp;gt;mod_form.php&amp;lt;/tt&amp;gt; so that users can select these conditions. You can add any necessary controls.&lt;br /&gt;
&lt;br /&gt;
* Implement the &amp;lt;tt&amp;gt;add_completion_rules&amp;lt;/tt&amp;gt; function which adds the form controls for your new rules.&lt;br /&gt;
&lt;br /&gt;
* Implement the &amp;lt;tt&amp;gt;completion_rule_enabled&amp;lt;/tt&amp;gt; function which is called during form validation to check whether one of your module&#039;s completion rules has been selected.&lt;br /&gt;
&lt;br /&gt;
* Implement other form changes if necessary to set up the form with your data. If your data is in the form of simple text boxes or dropdowns then this is not necessary, but you might want to have a checkbox that enables the rule with a separate control to set its value. This needs form tweaks.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
The forum offers a checkbox with a text input box beside it. You tick the checkbox to enable the rule, then type in the desired number of posts.&lt;br /&gt;
&lt;br /&gt;
First, the function that adds these controls:&lt;br /&gt;
&lt;br /&gt;
 function add_completion_rules() {&lt;br /&gt;
     $mform =&amp;amp; $this-&amp;gt;_form;&lt;br /&gt;
 &lt;br /&gt;
     $group=array();&lt;br /&gt;
     $group[] =&amp;amp; $mform-&amp;gt;createElement(&#039;checkbox&#039;, &#039;completionpostsenabled&#039;, &#039; &#039;, get_string(&#039;completionposts&#039;,&#039;forum&#039;));&lt;br /&gt;
     $group[] =&amp;amp; $mform-&amp;gt;createElement(&#039;text&#039;, &#039;completionposts&#039;, &#039; &#039;, array(&#039;size&#039;=&amp;gt;3));&lt;br /&gt;
     $mform-&amp;gt;setType(&#039;completionposts&#039;,PARAM_INT);&lt;br /&gt;
     $mform-&amp;gt;addGroup($group, &#039;completionpostsgroup&#039;, get_string(&#039;completionpostsgroup&#039;,&#039;forum&#039;), array(&#039; &#039;), false);&lt;br /&gt;
     $mform-&amp;gt;setHelpButton(&#039;completionpostsgroup&#039;, array(&#039;completion&#039;, get_string(&#039;completionpostshelp&#039;, &#039;forum&#039;), &#039;forum&#039;));&lt;br /&gt;
     $mform-&amp;gt;disabledIf(&#039;completionposts&#039;,&#039;completionpostsenabled&#039;,&#039;notchecked&#039;);&lt;br /&gt;
 &lt;br /&gt;
     return array(&#039;completionpostsgroup&#039;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* The function creates a checkbox and a text input field, which is set to accept only numbers.&lt;br /&gt;
* These are grouped together so they appear on the same line, and we add a help button.&lt;br /&gt;
* The text input field is disabled if the checkbox isn&#039;t ticked.&lt;br /&gt;
* Note that this function must return the top-level element associated with the completion rule. (If there are multiple elements, you can return more than one.) &lt;br /&gt;
** This is used so that your controls become disabled if automatic completion is not selected.&lt;br /&gt;
&lt;br /&gt;
Next, a function for checking whether the user selected this option:&lt;br /&gt;
&lt;br /&gt;
 function completion_rule_enabled($data) {&lt;br /&gt;
     return (!empty($data[&#039;completionpostsenabled&#039;]) &amp;amp;&amp;amp; $data[&#039;completionposts&#039;]!=0);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* The custom completion rule is enabled if the &#039;enabled&#039; checkbox is ticked and the text field value is something other than zero.&lt;br /&gt;
** This is used to give an error if the user selects automatic completion, but fails to select any conditions.&lt;br /&gt;
&lt;br /&gt;
That&#039;s all the &#039;required&#039; functions, but we need to add some extra code to support the checkbox behaviour. I overrode get_data so that if there is a value in the edit field, but the checkbox is not ticked, the value counts as zero (the rule will not be enabled).&lt;br /&gt;
&lt;br /&gt;
 function get_data() {&lt;br /&gt;
     $data = parent::get_data();&lt;br /&gt;
     if (!$data) {&lt;br /&gt;
         return $data;&lt;br /&gt;
     }&lt;br /&gt;
     if (!empty($data-&amp;gt;completionunlocked)) {&lt;br /&gt;
         // Turn off completion settings if the checkboxes aren&#039;t ticked&lt;br /&gt;
         $autocompletion = !empty($data-&amp;gt;completion) &amp;amp;&amp;amp; $data-&amp;gt;completion==COMPLETION_TRACKING_AUTOMATIC;&lt;br /&gt;
         if (empty($data-&amp;gt;completionpostsenabled) || !$autocompletion) {&lt;br /&gt;
            $data-&amp;gt;completionposts = 0;&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
     return $data;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
You may have noticed the &#039;completionunlocked&#039; check. When some users have already completed the activity, the completion settings are &#039;locked&#039;; they are disabled and cannot be edited, so there will be no value set for those fields in the &amp;lt;code&amp;gt;$data&amp;lt;/code&amp;gt; object. Normally this will automatically work but when dealing with checkboxes you need to include a check for the &#039;completionunlocked&#039; value before doing anything that would cause one of those fields to be changed in the database.&lt;br /&gt;
&lt;br /&gt;
Finally, forum already had a &amp;lt;tt&amp;gt;data_preprocessing&amp;lt;/tt&amp;gt; function but I added code to this to set up the checkboxes when the form is displayed, and to make the default value of the text fields 1 instead of 0:&lt;br /&gt;
&lt;br /&gt;
 function data_preprocessing(&amp;amp;$default_values){&lt;br /&gt;
     // [Existing code, not shown]&lt;br /&gt;
 &lt;br /&gt;
     // Set up the completion checkboxes which aren&#039;t part of standard data.&lt;br /&gt;
     // We also make the default value (if you turn on the checkbox) for those&lt;br /&gt;
     // numbers to be 1, this will not apply unless checkbox is ticked.&lt;br /&gt;
     $default_values[&#039;completionpostsenabled&#039;]=&lt;br /&gt;
         !empty($default_values[&#039;completionposts&#039;]) ? 1 : 0;&lt;br /&gt;
     if(empty($default_values[&#039;completionposts&#039;])) {&lt;br /&gt;
         $default_values[&#039;completionposts&#039;]=1;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Phew! That&#039;s the form done.&lt;br /&gt;
&lt;br /&gt;
=== Completion state function ===&lt;br /&gt;
&lt;br /&gt;
When you create completion conditions, you need to write a function &#039;&#039;module&#039;&#039;&amp;lt;tt&amp;gt;_get_completion_state&amp;lt;/tt&amp;gt; that checks the value of those conditions for a particular user. &lt;br /&gt;
&lt;br /&gt;
The function receives as parameters &amp;lt;tt&amp;gt;$course&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;$cm&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;$userid&amp;lt;/tt&amp;gt; - all self-explanatory, I hope - and &amp;lt;tt&amp;gt;$type&amp;lt;/tt&amp;gt;. This has two values: &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;COMPLETION_AND&#039;&#039;&#039; - if multiple conditions are selected, the user must meet all of them.&lt;br /&gt;
* &#039;&#039;&#039;COMPLETION_OR&#039;&#039;&#039; (not currently used) - if multiple conditions are selected, any one of them is good enough to complete the activity.&lt;br /&gt;
&lt;br /&gt;
Your function should return:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;true&#039;&#039;&#039; if your custom completion options are enabled and the user meets the conditions.&lt;br /&gt;
* &#039;&#039;&#039;false&#039;&#039;&#039; if your custom completion options are enabled but the user does not yet meet the conditions.&lt;br /&gt;
* &amp;lt;tt&amp;gt;$type&amp;lt;/tt&amp;gt; (not false!) if none of your custom completion options are not enabled.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the function for forum (simplified to include only the one completion option):&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * Obtains the automatic completion state for this forum based on any conditions&lt;br /&gt;
  * in forum settings.&lt;br /&gt;
  *&lt;br /&gt;
  * @param object $course Course&lt;br /&gt;
  * @param object $cm Course-module&lt;br /&gt;
  * @param int $userid User ID&lt;br /&gt;
  * @param bool $type Type of comparison (or/and; can be used as return value if no conditions)&lt;br /&gt;
  * @return bool True if completed, false if not, $type if conditions not set.&lt;br /&gt;
  */&lt;br /&gt;
 function forum_get_completion_state($course,$cm,$userid,$type) {&lt;br /&gt;
     global $CFG,$DB;&lt;br /&gt;
 &lt;br /&gt;
     // Get forum details&lt;br /&gt;
     if(!($forum=$DB-&amp;gt;get_record(&#039;forum&#039;,array(&#039;id&#039;=&amp;gt;$cm-&amp;gt;instance)))) {&lt;br /&gt;
         throw new Exception(&amp;quot;Can&#039;t find forum {$cm-&amp;gt;instance}&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     // If completion option is enabled, evaluate it and return true/false &lt;br /&gt;
     if($forum-&amp;gt;completionposts) {&lt;br /&gt;
         return $forum-&amp;gt;completionposts &amp;lt;= $DB-&amp;gt;get_field_sql(&amp;quot;&lt;br /&gt;
 SELECT &lt;br /&gt;
     COUNT(1) &lt;br /&gt;
 FROM &lt;br /&gt;
     {forum_posts} fp &lt;br /&gt;
     INNER JOIN {forum_discussions} fd ON fp.discussion=fd.id&lt;br /&gt;
 WHERE&lt;br /&gt;
     fp.userid=:userid AND fd.forum=:forumid&amp;quot;,&lt;br /&gt;
             array(&#039;userid&#039;=&amp;gt;$userid,&#039;forumid&#039;=&amp;gt;$forum-&amp;gt;id));&lt;br /&gt;
     } else {&lt;br /&gt;
         // Completion option is not enabled so just return $type&lt;br /&gt;
         return $type;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Notifying the completion system ===&lt;br /&gt;
&lt;br /&gt;
Finally you need to notify the completion system whenever these values might have changed for a user (in the case of the forum example, whenever somebody adds or deletes a post). The completion system will end up calling the function above - but only if it needs to. &lt;br /&gt;
&lt;br /&gt;
* To ensure performance is not compromised, you should notify the system only when the completion state might actually have changed. Don&#039;t notify the system unless your custom completion rule is actually enabled.&lt;br /&gt;
* You need to pass in the &#039;possible result&#039; of the change. This is used to significantly improve performance.  There are three values:&lt;br /&gt;
** &#039;&#039;&#039;COMPLETION_COMPLETE&#039;&#039;&#039; - this change will either have no effect on the user&#039;s completion state, or it will make it complete. The change cannot make a user&#039;s state &#039;&#039;in&#039;&#039;complete if it was complete previously. In the forum example, when you add a post, there is no way this can make the user&#039;s state incomplete, so this possible result applies.&lt;br /&gt;
** &#039;&#039;&#039;COMPLETION_INCOMPLETE&#039;&#039;&#039; - this change will either have no effect on the user&#039;s completion state, or it will make it incomplete. The change cannot make a user&#039;s state complete if it was incomplete previously. Deleting a forum post would fall into this category.&lt;br /&gt;
** &#039;&#039;&#039;COMPLETION_UNKNOWN&#039;&#039;&#039; - this change might have either effect. Using this option is much slower than the others, so try to avoid using it in anything that might happen frequently.&lt;br /&gt;
* If the user whose completion state would be updated is not the current user, then the optional &amp;lt;tt&amp;gt;$userid&amp;lt;/tt&amp;gt; parameter must be included. For example, if a teacher deletes a student&#039;s forum post, then it is the student&#039;s completion state which may need updating, not the teacher&#039;s.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code that runs when somebody makes a new forum post:&lt;br /&gt;
&lt;br /&gt;
 // Update completion state&lt;br /&gt;
 $completion=new completion_info($course);&lt;br /&gt;
 if($completion-&amp;gt;is_enabled($cm) &amp;amp;&amp;amp; $forum-&amp;gt;completionposts) {&lt;br /&gt;
     $completion-&amp;gt;update_state($cm,COMPLETION_COMPLETE);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[[Conditional activities|Activity completion and availability]] - Original Specification&lt;br /&gt;
&lt;br /&gt;
[[Course completion]] - Original Specification&lt;br /&gt;
&lt;br /&gt;
[[Policy - Retroactive effects of completion settings]]&lt;br /&gt;
&lt;br /&gt;
[[Core APIs]]&lt;br /&gt;
&lt;br /&gt;
=== User Docs ===&lt;br /&gt;
[https://docs.moodle.org/en/Category:Completion Completion Docs]&lt;br /&gt;
&lt;br /&gt;
[https://docs.moodle.org/en/Activity_completion Activity Completion]&lt;br /&gt;
&lt;br /&gt;
[https://docs.moodle.org/en/Course_completion Course Completion]&lt;br /&gt;
&lt;br /&gt;
[[Category:Conditional activities]]&lt;br /&gt;
&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Activity_completion_API&amp;diff=39157</id>
		<title>Activity completion API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Activity_completion_API&amp;diff=39157"/>
		<updated>2013-04-18T14:10:02Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
Modules do not need to be changed to support conditional availability, but they do need changing to support the completion system. &lt;br /&gt;
&lt;br /&gt;
If you make no changes to a module whatsoever, it can only support &#039;manual&#039; completion (where the user ticks a box).&lt;br /&gt;
&lt;br /&gt;
== Feature support ==&lt;br /&gt;
&lt;br /&gt;
To support the completion system, your module must include a &#039;&#039;modulename&#039;&#039;&amp;lt;tt&amp;gt;_supports&amp;lt;/tt&amp;gt; function in its &amp;lt;tt&amp;gt;lib.php&amp;lt;/tt&amp;gt;. Here is an example:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * Indicates API features that the forum supports.&lt;br /&gt;
  *&lt;br /&gt;
  * @param string $feature&lt;br /&gt;
  * @return mixed True if yes (some features may use other values)&lt;br /&gt;
  */&lt;br /&gt;
 function forum_supports($feature) {&lt;br /&gt;
     switch($feature) {&lt;br /&gt;
         case FEATURE_COMPLETION_TRACKS_VIEWS: return true;&lt;br /&gt;
         case FEATURE_COMPLETION_HAS_RULES: return true;&lt;br /&gt;
         default: return null;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The relevant features for completion are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;FEATURE_COMPLETION_TRACKS_VIEWS&#039;&#039;&#039; - the module can support completion &#039;on view&#039;, meaning that an activity becomes marked complete as soon as a user clicks on it.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;FEATURE_GRADE_HAS_GRADE&#039;&#039;&#039; - the module provides (or may provide, depending on settings) a grade for students. When a module supports grades, it can support completion &#039;on grade&#039;, meaning that an activity becomes marked complete as soon as a user is assigned a grade.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;FEATURE_COMPLETION_HAS_RULES&#039;&#039;&#039; - the module has custom completion rules.&lt;br /&gt;
&lt;br /&gt;
== Completion on view ==&lt;br /&gt;
&lt;br /&gt;
Completion on view means that, if selected, an activity is marked complete as soon as the user views it. &#039;View&#039; is usually defined as seeing the module&#039;s main page; if you click on the activity, and there isn&#039;t an error, you have probably viewed it. However it is up to each module precisely how they define &#039;view&#039;.&lt;br /&gt;
&lt;br /&gt;
=== How to implement ===&lt;br /&gt;
&lt;br /&gt;
In your module&#039;s &#039;&#039;modulename&#039;&#039;&amp;lt;tt&amp;gt;_supports&amp;lt;/tt&amp;gt; function, return true for FEATURE_COMPLETION_TRACKS_VIEWS.&lt;br /&gt;
&lt;br /&gt;
Then add this code to run whenever a user successfully views the activity. In order for navigation to work as expected (i.e. so that the navigation block on the module&#039;s page takes account that you have viewed this activity, if there is another activity that depends on it) you should put this code before printing the page header.&lt;br /&gt;
&lt;br /&gt;
 $completion = new completion_info($course);&lt;br /&gt;
 $completion-&amp;gt;set_module_viewed($cm);&lt;br /&gt;
&lt;br /&gt;
=== Performance issues ===&lt;br /&gt;
&lt;br /&gt;
Calling this method has no significant performance cost if &#039;on view&#039; completion is not enabled for the activity. If it is enabled, then the performance cost is kept low because the &#039;viewed&#039; state is cached; it doesn&#039;t add a database query to every request.&lt;br /&gt;
&lt;br /&gt;
== Completion on grade ==&lt;br /&gt;
&lt;br /&gt;
Completion on grade means that, if selected, an activity is marked complete as soon as the user receives a grade from that activity.&lt;br /&gt;
&lt;br /&gt;
=== How to implement ===&lt;br /&gt;
&lt;br /&gt;
In your module&#039;s _supports function, return true for FEATURE_GRADE_HAS_GRADE. No other action is necessary.&lt;br /&gt;
&lt;br /&gt;
=== Performance issues ===&lt;br /&gt;
&lt;br /&gt;
When &#039;on grade&#039; completion is enabled, there will be some additional database queries after a grade is assigned or changed. Unless your activity changes grades very frequently, this is unlikely to be an issue.&lt;br /&gt;
&lt;br /&gt;
== Custom completion rules ==&lt;br /&gt;
&lt;br /&gt;
Custom completion rules allow for module-specific conditions. For example, the forum has custom rules so that you can make it mark a user completed when they make a certain number of posts to the forum.&lt;br /&gt;
&lt;br /&gt;
It is a lot harder to implement custom completion rules than it is to use the system-provided &#039;view&#039; or &#039;grade&#039; conditions, but the instructions below should help make it clear.&lt;br /&gt;
&lt;br /&gt;
=== Implementation overview ===&lt;br /&gt;
&lt;br /&gt;
To implement custom completion rules, you need to:&lt;br /&gt;
&lt;br /&gt;
# Return true for FEATURE_COMPLETION_HAS_RULES in your module&#039;s _supports function.&lt;br /&gt;
# Add database fields to your module&#039;s main table to store the custom completion settings.&lt;br /&gt;
# Add backup and restore code to back up these fields.&lt;br /&gt;
# Add controls to your module&#039;s settings form so that users can select the custom rules, altering these database settings.&lt;br /&gt;
# Add a function that checks the value of these rules (if set).&lt;br /&gt;
# Add code so that whenever the value affecting a rule might change, you inform the completion system.&lt;br /&gt;
&lt;br /&gt;
=== Database fields for completion settings ===&lt;br /&gt;
&lt;br /&gt;
When you provide a custom completion rule for a module, that rule requires data to be stored with each module instance: whether the rule is enabled for that instance, and any options that apply to the rule.&lt;br /&gt;
&lt;br /&gt;
Usually the best place to store this information is your module&#039;s main table because:&lt;br /&gt;
&lt;br /&gt;
* The information in the relevant row of this table is likely to be available in most parts of your code, so code changes are minimised.&lt;br /&gt;
* You already read this row with most requests, so there is no need for additional database queries which would reduce performance.&lt;br /&gt;
* The main table is used for most other module options so it is a logical place for this information.&lt;br /&gt;
&lt;br /&gt;
If you are adding a basic completion condition you probably only need to add one field. To add a field to an existing module, you need to change the install.xml and then the update.php in the same way as adding any other field.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Throughout this section I am using the forum as an example. The forum provides three completion options but because they all behave the same way, I am only showing one of them.&lt;br /&gt;
&lt;br /&gt;
The forum adds this field to store a completion option:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;completionposts&#039;&#039;&#039; - this may be 0 or an integer. If it&#039;s an integer, say 3, then the user needs to add 3 forum posts (either new discussions or replies) in order for the forum to count as &#039;completed&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Backup and restore for completion fields ===&lt;br /&gt;
&lt;br /&gt;
Modules do not need to back up the generic completion options, which are handled by the system, but they do need to back up any custom options. You should add backup and restore logic for the fields mentioned above. &lt;br /&gt;
&lt;br /&gt;
Remember that your restore code should handle the case when these fields are not present, setting the fields to a suitable default value.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
The following code in &amp;lt;tt&amp;gt;backup_forum_stepslib.php&amp;lt;/tt&amp;gt; lists the fields to back up:&lt;br /&gt;
&lt;br /&gt;
  $forum = new backup_nested_element(&#039;forum&#039;, array(&#039;id&#039;), array(&lt;br /&gt;
            &#039;type&#039;, &#039;name&#039;, &#039;intro&#039;, &#039;introformat&#039;,&lt;br /&gt;
            &#039;assessed&#039;, &#039;assesstimestart&#039;, &#039;assesstimefinish&#039;, &#039;scale&#039;,&lt;br /&gt;
            &#039;maxbytes&#039;, &#039;maxattachments&#039;, &#039;forcesubscribe&#039;, &#039;trackingtype&#039;,&lt;br /&gt;
            &#039;rsstype&#039;, &#039;rssarticles&#039;, &#039;timemodified&#039;, &#039;warnafter&#039;,&lt;br /&gt;
            &#039;blockafter&#039;, &#039;blockperiod&#039;, &#039;completiondiscussions&#039;, &#039;completionreplies&#039;,&lt;br /&gt;
            &#039;completionposts&#039;));&lt;br /&gt;
&lt;br /&gt;
As you can see, I added the &#039;&#039;&#039;completionposts&#039;&#039;&#039; field (and the others that aren&#039;t covered in this example) to the list of fields.&lt;br /&gt;
&lt;br /&gt;
=== Form changes for completion settings ===&lt;br /&gt;
&lt;br /&gt;
When you have custom completion conditions, you need to add controls to your module&#039;s settings form &amp;lt;tt&amp;gt;mod_form.php&amp;lt;/tt&amp;gt; so that users can select these conditions. You can add any necessary controls.&lt;br /&gt;
&lt;br /&gt;
* Implement the &amp;lt;tt&amp;gt;add_completion_rules&amp;lt;/tt&amp;gt; function which adds the form controls for your new rules.&lt;br /&gt;
&lt;br /&gt;
* Implement the &amp;lt;tt&amp;gt;completion_rule_enabled&amp;lt;/tt&amp;gt; function which is called during form validation to check whether one of your module&#039;s completion rules has been selected.&lt;br /&gt;
&lt;br /&gt;
* Implement other form changes if necessary to set up the form with your data. If your data is in the form of simple text boxes or dropdowns then this is not necessary, but you might want to have a checkbox that enables the rule with a separate control to set its value. This needs form tweaks.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
The forum offers a checkbox with a text input box beside it. You tick the checkbox to enable the rule, then type in the desired number of posts.&lt;br /&gt;
&lt;br /&gt;
First, the function that adds these controls:&lt;br /&gt;
&lt;br /&gt;
 function add_completion_rules() {&lt;br /&gt;
     $mform =&amp;amp; $this-&amp;gt;_form;&lt;br /&gt;
 &lt;br /&gt;
     $group=array();&lt;br /&gt;
     $group[] =&amp;amp; $mform-&amp;gt;createElement(&#039;checkbox&#039;, &#039;completionpostsenabled&#039;, &#039; &#039;, get_string(&#039;completionposts&#039;,&#039;forum&#039;));&lt;br /&gt;
     $group[] =&amp;amp; $mform-&amp;gt;createElement(&#039;text&#039;, &#039;completionposts&#039;, &#039; &#039;, array(&#039;size&#039;=&amp;gt;3));&lt;br /&gt;
     $mform-&amp;gt;setType(&#039;completionposts&#039;,PARAM_INT);&lt;br /&gt;
     $mform-&amp;gt;addGroup($group, &#039;completionpostsgroup&#039;, get_string(&#039;completionpostsgroup&#039;,&#039;forum&#039;), array(&#039; &#039;), false);&lt;br /&gt;
     $mform-&amp;gt;setHelpButton(&#039;completionpostsgroup&#039;, array(&#039;completion&#039;, get_string(&#039;completionpostshelp&#039;, &#039;forum&#039;), &#039;forum&#039;));&lt;br /&gt;
     $mform-&amp;gt;disabledIf(&#039;completionposts&#039;,&#039;completionpostsenabled&#039;,&#039;notchecked&#039;);&lt;br /&gt;
 &lt;br /&gt;
     return array(&#039;completionpostsgroup&#039;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* The function creates a checkbox and a text input field, which is set to accept only numbers.&lt;br /&gt;
* These are grouped together so they appear on the same line, and we add a help button.&lt;br /&gt;
* The text input field is disabled if the checkbox isn&#039;t ticked.&lt;br /&gt;
* Note that this function must return the top-level element associated with the completion rule. (If there are multiple elements, you can return more than one.) &lt;br /&gt;
** This is used so that your controls become disabled if automatic completion is not selected.&lt;br /&gt;
&lt;br /&gt;
Next, a function for checking whether the user selected this option:&lt;br /&gt;
&lt;br /&gt;
 function completion_rule_enabled($data) {&lt;br /&gt;
     return (!empty($data[&#039;completionpostsenabled&#039;]) &amp;amp;&amp;amp; $data[&#039;completionposts&#039;]!=0);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* The custom completion rule is enabled if the &#039;enabled&#039; checkbox is ticked and the text field value is something other than zero.&lt;br /&gt;
** This is used to give an error if the user selects automatic completion, but fails to select any conditions.&lt;br /&gt;
&lt;br /&gt;
That&#039;s all the &#039;required&#039; functions, but we need to add some extra code to support the checkbox behaviour. I overrode get_data so that if there is a value in the edit field, but the checkbox is not ticked, the value counts as zero (the rule will not be enabled).&lt;br /&gt;
&lt;br /&gt;
 function get_data() {&lt;br /&gt;
     $data = parent::get_data();&lt;br /&gt;
     if (!$data) {&lt;br /&gt;
         return $data;&lt;br /&gt;
     }&lt;br /&gt;
     if (!empty($data-&amp;gt;completionunlocked)) {&lt;br /&gt;
         // Turn off completion settings if the checkboxes aren&#039;t ticked&lt;br /&gt;
         $autocompletion = !empty($data-&amp;gt;completion) &amp;amp;&amp;amp; $data-&amp;gt;completion==COMPLETION_TRACKING_AUTOMATIC;&lt;br /&gt;
         if (empty($data-&amp;gt;completionpostsenabled) || !$autocompletion) {&lt;br /&gt;
            $data-&amp;gt;completionposts = 0;&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
     return $data;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
You may have noticed the &#039;completionunlocked&#039; check. When some users have already completed the activity, the completion settings are &#039;locked&#039;; they are disabled and cannot be edited, so there will be no value set for those fields in the &amp;lt;code&amp;gt;$data&amp;lt;/code&amp;gt; object. Normally this will automatically work but when dealing with checkboxes you need to include a check for the &#039;completionunlocked&#039; value before doing anything that would cause one of those fields to be changed in the database.&lt;br /&gt;
&lt;br /&gt;
Finally, forum already had a &amp;lt;tt&amp;gt;data_preprocessing&amp;lt;/tt&amp;gt; function but I added code to this to set up the checkboxes when the form is displayed, and to make the default value of the text fields 1 instead of 0:&lt;br /&gt;
&lt;br /&gt;
 function data_preprocessing(&amp;amp;$default_values){&lt;br /&gt;
     // [Existing code, not shown]&lt;br /&gt;
 &lt;br /&gt;
     // Set up the completion checkboxes which aren&#039;t part of standard data.&lt;br /&gt;
     // We also make the default value (if you turn on the checkbox) for those&lt;br /&gt;
     // numbers to be 1, this will not apply unless checkbox is ticked.&lt;br /&gt;
     $default_values[&#039;completionpostsenabled&#039;]=&lt;br /&gt;
         !empty($default_values[&#039;completionposts&#039;]) ? 1 : 0;&lt;br /&gt;
     if(empty($default_values[&#039;completionposts&#039;])) {&lt;br /&gt;
         $default_values[&#039;completionposts&#039;]=1;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Phew! That&#039;s the form done.&lt;br /&gt;
&lt;br /&gt;
=== Completion state function ===&lt;br /&gt;
&lt;br /&gt;
When you create completion conditions, you need to write a function &#039;&#039;module&#039;&#039;&amp;lt;tt&amp;gt;_get_completion_state&amp;lt;/tt&amp;gt; that checks the value of those conditions for a particular user. &lt;br /&gt;
&lt;br /&gt;
The function receives as parameters &amp;lt;tt&amp;gt;$course&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;$cm&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;$userid&amp;lt;/tt&amp;gt; - all self-explanatory, I hope - and &amp;lt;tt&amp;gt;$type&amp;lt;/tt&amp;gt;. This has two values: &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;COMPLETION_AND&#039;&#039;&#039; - if multiple conditions are selected, the user must meet all of them.&lt;br /&gt;
* &#039;&#039;&#039;COMPLETION_OR&#039;&#039;&#039; (not currently used) - if multiple conditions are selected, any one of them is good enough to complete the activity.&lt;br /&gt;
&lt;br /&gt;
Your function should return:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;true&#039;&#039;&#039; if your custom completion options are enabled and the user meets the conditions.&lt;br /&gt;
* &#039;&#039;&#039;false&#039;&#039;&#039; if your custom completion options are enabled but the user does not yet meet the conditions.&lt;br /&gt;
* &amp;lt;tt&amp;gt;$type&amp;lt;/tt&amp;gt; (not false!) if none of your custom completion options are not enabled.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the function for forum (simplified to include only the one completion option):&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * Obtains the automatic completion state for this forum based on any conditions&lt;br /&gt;
  * in forum settings.&lt;br /&gt;
  *&lt;br /&gt;
  * @param object $course Course&lt;br /&gt;
  * @param object $cm Course-module&lt;br /&gt;
  * @param int $userid User ID&lt;br /&gt;
  * @param bool $type Type of comparison (or/and; can be used as return value if no conditions)&lt;br /&gt;
  * @return bool True if completed, false if not, $type if conditions not set.&lt;br /&gt;
  */&lt;br /&gt;
 function forum_get_completion_state($course,$cm,$userid,$type) {&lt;br /&gt;
     global $CFG,$DB;&lt;br /&gt;
 &lt;br /&gt;
     // Get forum details&lt;br /&gt;
     if(!($forum=$DB-&amp;gt;get_record(&#039;forum&#039;,array(&#039;id&#039;=&amp;gt;$cm-&amp;gt;instance)))) {&lt;br /&gt;
         throw new Exception(&amp;quot;Can&#039;t find forum {$cm-&amp;gt;instance}&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     // If completion option is enabled, evaluate it and return true/false &lt;br /&gt;
     if($forum-&amp;gt;completionposts) {&lt;br /&gt;
         return $forum-&amp;gt;completionposts &amp;lt;= $DB-&amp;gt;get_field_sql(&amp;quot;&lt;br /&gt;
 SELECT &lt;br /&gt;
     COUNT(1) &lt;br /&gt;
 FROM &lt;br /&gt;
     {forum_posts} fp &lt;br /&gt;
     INNER JOIN {forum_discussions} fd ON fp.discussion=fd.id&lt;br /&gt;
 WHERE&lt;br /&gt;
     fp.userid=:userid AND fd.forum=:forumid&amp;quot;,&lt;br /&gt;
             array(&#039;userid&#039;=&amp;gt;$userid,&#039;forumid&#039;=&amp;gt;$forum-&amp;gt;id));&lt;br /&gt;
     } else {&lt;br /&gt;
         // Completion option is not enabled so just return $type&lt;br /&gt;
         return $type;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Notifying the completion system ===&lt;br /&gt;
&lt;br /&gt;
Finally you need to notify the completion system whenever these values might have changed for a user (in the case of the forum example, whenever somebody adds or deletes a post). The completion system will end up calling the function above - but only if it needs to. &lt;br /&gt;
&lt;br /&gt;
* To ensure performance is not compromised, you should notify the system only when the completion state might actually have changed. Don&#039;t notify the system unless your custom completion rule is actually enabled.&lt;br /&gt;
* You need to pass in the &#039;possible result&#039; of the change. This is used to significantly improve performance.  There are three values:&lt;br /&gt;
** &#039;&#039;&#039;COMPLETION_COMPLETE&#039;&#039;&#039; - this change will either have no effect on the user&#039;s completion state, or it will make it complete. The change cannot make a user&#039;s state &#039;&#039;in&#039;&#039;complete if it was complete previously. In the forum example, when you add a post, there is no way this can make the user&#039;s state incomplete, so this possible result applies.&lt;br /&gt;
** &#039;&#039;&#039;COMPLETION_INCOMPLETE&#039;&#039;&#039; - this change will either have no effect on the user&#039;s completion state, or it will make it incomplete. The change cannot make a user&#039;s state complete if it was incomplete previously. Deleting a forum post would fall into this category.&lt;br /&gt;
** &#039;&#039;&#039;COMPLETION_UNKNOWN&#039;&#039;&#039; - this change might have either effect. Using this option is much slower than the others, so try to avoid using it in anything that might happen frequently.&lt;br /&gt;
* If the user whose completion state would be updated is not the current user, then the optional &amp;lt;tt&amp;gt;$userid&amp;lt;/tt&amp;gt; parameter must be included. For example, if a teacher deletes a student&#039;s forum post, then it is the student&#039;s completion state which may need updating, not the teacher&#039;s.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code that runs when somebody makes a new forum post:&lt;br /&gt;
&lt;br /&gt;
 // Update completion state&lt;br /&gt;
 $completion=new completion_info($course);&lt;br /&gt;
 if($completion-&amp;gt;is_enabled($cm) &amp;amp;&amp;amp; $forum-&amp;gt;completionposts) {&lt;br /&gt;
     $completion-&amp;gt;update_state($cm,COMPLETION_COMPLETE);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[[Conditional activities|Activity completion and availability]] - Original Specification&lt;br /&gt;
&lt;br /&gt;
[[Course completion]] - Original Specification&lt;br /&gt;
&lt;br /&gt;
[[Policy_Retroactive effects of of completion settings]]&lt;br /&gt;
&lt;br /&gt;
[[Core APIs]]&lt;br /&gt;
&lt;br /&gt;
=== User Docs ===&lt;br /&gt;
[https://docs.moodle.org/en/Category:Completion Completion Docs]&lt;br /&gt;
&lt;br /&gt;
[https://docs.moodle.org/en/Activity_completion Activity Completion]&lt;br /&gt;
&lt;br /&gt;
[https://docs.moodle.org/en/Course_completion Course Completion]&lt;br /&gt;
&lt;br /&gt;
[[Category:Conditional activities]]&lt;br /&gt;
&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Activity_completion_API&amp;diff=39156</id>
		<title>Activity completion API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Activity_completion_API&amp;diff=39156"/>
		<updated>2013-04-18T14:08:29Z</updated>

		<summary type="html">&lt;p&gt;Raymor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
Modules do not need to be changed to support conditional availability, but they do need changing to support the completion system. &lt;br /&gt;
&lt;br /&gt;
If you make no changes to a module whatsoever, it can only support &#039;manual&#039; completion (where the user ticks a box).&lt;br /&gt;
&lt;br /&gt;
== Feature support ==&lt;br /&gt;
&lt;br /&gt;
To support the completion system, your module must include a &#039;&#039;modulename&#039;&#039;&amp;lt;tt&amp;gt;_supports&amp;lt;/tt&amp;gt; function in its &amp;lt;tt&amp;gt;lib.php&amp;lt;/tt&amp;gt;. Here is an example:&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * Indicates API features that the forum supports.&lt;br /&gt;
  *&lt;br /&gt;
  * @param string $feature&lt;br /&gt;
  * @return mixed True if yes (some features may use other values)&lt;br /&gt;
  */&lt;br /&gt;
 function forum_supports($feature) {&lt;br /&gt;
     switch($feature) {&lt;br /&gt;
         case FEATURE_COMPLETION_TRACKS_VIEWS: return true;&lt;br /&gt;
         case FEATURE_COMPLETION_HAS_RULES: return true;&lt;br /&gt;
         default: return null;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The relevant features for completion are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;FEATURE_COMPLETION_TRACKS_VIEWS&#039;&#039;&#039; - the module can support completion &#039;on view&#039;, meaning that an activity becomes marked complete as soon as a user clicks on it.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;FEATURE_GRADE_HAS_GRADE&#039;&#039;&#039; - the module provides (or may provide, depending on settings) a grade for students. When a module supports grades, it can support completion &#039;on grade&#039;, meaning that an activity becomes marked complete as soon as a user is assigned a grade.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;FEATURE_COMPLETION_HAS_RULES&#039;&#039;&#039; - the module has custom completion rules.&lt;br /&gt;
&lt;br /&gt;
== Completion on view ==&lt;br /&gt;
&lt;br /&gt;
Completion on view means that, if selected, an activity is marked complete as soon as the user views it. &#039;View&#039; is usually defined as seeing the module&#039;s main page; if you click on the activity, and there isn&#039;t an error, you have probably viewed it. However it is up to each module precisely how they define &#039;view&#039;.&lt;br /&gt;
&lt;br /&gt;
=== How to implement ===&lt;br /&gt;
&lt;br /&gt;
In your module&#039;s &#039;&#039;modulename&#039;&#039;&amp;lt;tt&amp;gt;_supports&amp;lt;/tt&amp;gt; function, return true for FEATURE_COMPLETION_TRACKS_VIEWS.&lt;br /&gt;
&lt;br /&gt;
Then add this code to run whenever a user successfully views the activity. In order for navigation to work as expected (i.e. so that the navigation block on the module&#039;s page takes account that you have viewed this activity, if there is another activity that depends on it) you should put this code before printing the page header.&lt;br /&gt;
&lt;br /&gt;
 $completion = new completion_info($course);&lt;br /&gt;
 $completion-&amp;gt;set_module_viewed($cm);&lt;br /&gt;
&lt;br /&gt;
=== Performance issues ===&lt;br /&gt;
&lt;br /&gt;
Calling this method has no significant performance cost if &#039;on view&#039; completion is not enabled for the activity. If it is enabled, then the performance cost is kept low because the &#039;viewed&#039; state is cached; it doesn&#039;t add a database query to every request.&lt;br /&gt;
&lt;br /&gt;
== Completion on grade ==&lt;br /&gt;
&lt;br /&gt;
Completion on grade means that, if selected, an activity is marked complete as soon as the user receives a grade from that activity.&lt;br /&gt;
&lt;br /&gt;
=== How to implement ===&lt;br /&gt;
&lt;br /&gt;
In your module&#039;s _supports function, return true for FEATURE_GRADE_HAS_GRADE. No other action is necessary.&lt;br /&gt;
&lt;br /&gt;
=== Performance issues ===&lt;br /&gt;
&lt;br /&gt;
When &#039;on grade&#039; completion is enabled, there will be some additional database queries after a grade is assigned or changed. Unless your activity changes grades very frequently, this is unlikely to be an issue.&lt;br /&gt;
&lt;br /&gt;
== Custom completion rules ==&lt;br /&gt;
&lt;br /&gt;
Custom completion rules allow for module-specific conditions. For example, the forum has custom rules so that you can make it mark a user completed when they make a certain number of posts to the forum.&lt;br /&gt;
&lt;br /&gt;
It is a lot harder to implement custom completion rules than it is to use the system-provided &#039;view&#039; or &#039;grade&#039; conditions, but the instructions below should help make it clear.&lt;br /&gt;
&lt;br /&gt;
=== Implementation overview ===&lt;br /&gt;
&lt;br /&gt;
To implement custom completion rules, you need to:&lt;br /&gt;
&lt;br /&gt;
# Return true for FEATURE_COMPLETION_HAS_RULES in your module&#039;s _supports function.&lt;br /&gt;
# Add database fields to your module&#039;s main table to store the custom completion settings.&lt;br /&gt;
# Add backup and restore code to back up these fields.&lt;br /&gt;
# Add controls to your module&#039;s settings form so that users can select the custom rules, altering these database settings.&lt;br /&gt;
# Add a function that checks the value of these rules (if set).&lt;br /&gt;
# Add code so that whenever the value affecting a rule might change, you inform the completion system.&lt;br /&gt;
&lt;br /&gt;
=== Database fields for completion settings ===&lt;br /&gt;
&lt;br /&gt;
When you provide a custom completion rule for a module, that rule requires data to be stored with each module instance: whether the rule is enabled for that instance, and any options that apply to the rule.&lt;br /&gt;
&lt;br /&gt;
Usually the best place to store this information is your module&#039;s main table because:&lt;br /&gt;
&lt;br /&gt;
* The information in the relevant row of this table is likely to be available in most parts of your code, so code changes are minimised.&lt;br /&gt;
* You already read this row with most requests, so there is no need for additional database queries which would reduce performance.&lt;br /&gt;
* The main table is used for most other module options so it is a logical place for this information.&lt;br /&gt;
&lt;br /&gt;
If you are adding a basic completion condition you probably only need to add one field. To add a field to an existing module, you need to change the install.xml and then the update.php in the same way as adding any other field.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Throughout this section I am using the forum as an example. The forum provides three completion options but because they all behave the same way, I am only showing one of them.&lt;br /&gt;
&lt;br /&gt;
The forum adds this field to store a completion option:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;completionposts&#039;&#039;&#039; - this may be 0 or an integer. If it&#039;s an integer, say 3, then the user needs to add 3 forum posts (either new discussions or replies) in order for the forum to count as &#039;completed&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Backup and restore for completion fields ===&lt;br /&gt;
&lt;br /&gt;
Modules do not need to back up the generic completion options, which are handled by the system, but they do need to back up any custom options. You should add backup and restore logic for the fields mentioned above. &lt;br /&gt;
&lt;br /&gt;
Remember that your restore code should handle the case when these fields are not present, setting the fields to a suitable default value.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
The following code in &amp;lt;tt&amp;gt;backup_forum_stepslib.php&amp;lt;/tt&amp;gt; lists the fields to back up:&lt;br /&gt;
&lt;br /&gt;
  $forum = new backup_nested_element(&#039;forum&#039;, array(&#039;id&#039;), array(&lt;br /&gt;
            &#039;type&#039;, &#039;name&#039;, &#039;intro&#039;, &#039;introformat&#039;,&lt;br /&gt;
            &#039;assessed&#039;, &#039;assesstimestart&#039;, &#039;assesstimefinish&#039;, &#039;scale&#039;,&lt;br /&gt;
            &#039;maxbytes&#039;, &#039;maxattachments&#039;, &#039;forcesubscribe&#039;, &#039;trackingtype&#039;,&lt;br /&gt;
            &#039;rsstype&#039;, &#039;rssarticles&#039;, &#039;timemodified&#039;, &#039;warnafter&#039;,&lt;br /&gt;
            &#039;blockafter&#039;, &#039;blockperiod&#039;, &#039;completiondiscussions&#039;, &#039;completionreplies&#039;,&lt;br /&gt;
            &#039;completionposts&#039;));&lt;br /&gt;
&lt;br /&gt;
As you can see, I added the &#039;&#039;&#039;completionposts&#039;&#039;&#039; field (and the others that aren&#039;t covered in this example) to the list of fields.&lt;br /&gt;
&lt;br /&gt;
=== Form changes for completion settings ===&lt;br /&gt;
&lt;br /&gt;
When you have custom completion conditions, you need to add controls to your module&#039;s settings form &amp;lt;tt&amp;gt;mod_form.php&amp;lt;/tt&amp;gt; so that users can select these conditions. You can add any necessary controls.&lt;br /&gt;
&lt;br /&gt;
* Implement the &amp;lt;tt&amp;gt;add_completion_rules&amp;lt;/tt&amp;gt; function which adds the form controls for your new rules.&lt;br /&gt;
&lt;br /&gt;
* Implement the &amp;lt;tt&amp;gt;completion_rule_enabled&amp;lt;/tt&amp;gt; function which is called during form validation to check whether one of your module&#039;s completion rules has been selected.&lt;br /&gt;
&lt;br /&gt;
* Implement other form changes if necessary to set up the form with your data. If your data is in the form of simple text boxes or dropdowns then this is not necessary, but you might want to have a checkbox that enables the rule with a separate control to set its value. This needs form tweaks.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
The forum offers a checkbox with a text input box beside it. You tick the checkbox to enable the rule, then type in the desired number of posts.&lt;br /&gt;
&lt;br /&gt;
First, the function that adds these controls:&lt;br /&gt;
&lt;br /&gt;
 function add_completion_rules() {&lt;br /&gt;
     $mform =&amp;amp; $this-&amp;gt;_form;&lt;br /&gt;
 &lt;br /&gt;
     $group=array();&lt;br /&gt;
     $group[] =&amp;amp; $mform-&amp;gt;createElement(&#039;checkbox&#039;, &#039;completionpostsenabled&#039;, &#039; &#039;, get_string(&#039;completionposts&#039;,&#039;forum&#039;));&lt;br /&gt;
     $group[] =&amp;amp; $mform-&amp;gt;createElement(&#039;text&#039;, &#039;completionposts&#039;, &#039; &#039;, array(&#039;size&#039;=&amp;gt;3));&lt;br /&gt;
     $mform-&amp;gt;setType(&#039;completionposts&#039;,PARAM_INT);&lt;br /&gt;
     $mform-&amp;gt;addGroup($group, &#039;completionpostsgroup&#039;, get_string(&#039;completionpostsgroup&#039;,&#039;forum&#039;), array(&#039; &#039;), false);&lt;br /&gt;
     $mform-&amp;gt;setHelpButton(&#039;completionpostsgroup&#039;, array(&#039;completion&#039;, get_string(&#039;completionpostshelp&#039;, &#039;forum&#039;), &#039;forum&#039;));&lt;br /&gt;
     $mform-&amp;gt;disabledIf(&#039;completionposts&#039;,&#039;completionpostsenabled&#039;,&#039;notchecked&#039;);&lt;br /&gt;
 &lt;br /&gt;
     return array(&#039;completionpostsgroup&#039;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* The function creates a checkbox and a text input field, which is set to accept only numbers.&lt;br /&gt;
* These are grouped together so they appear on the same line, and we add a help button.&lt;br /&gt;
* The text input field is disabled if the checkbox isn&#039;t ticked.&lt;br /&gt;
* Note that this function must return the top-level element associated with the completion rule. (If there are multiple elements, you can return more than one.) &lt;br /&gt;
** This is used so that your controls become disabled if automatic completion is not selected.&lt;br /&gt;
&lt;br /&gt;
Next, a function for checking whether the user selected this option:&lt;br /&gt;
&lt;br /&gt;
 function completion_rule_enabled($data) {&lt;br /&gt;
     return (!empty($data[&#039;completionpostsenabled&#039;]) &amp;amp;&amp;amp; $data[&#039;completionposts&#039;]!=0);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* The custom completion rule is enabled if the &#039;enabled&#039; checkbox is ticked and the text field value is something other than zero.&lt;br /&gt;
** This is used to give an error if the user selects automatic completion, but fails to select any conditions.&lt;br /&gt;
&lt;br /&gt;
That&#039;s all the &#039;required&#039; functions, but we need to add some extra code to support the checkbox behaviour. I overrode get_data so that if there is a value in the edit field, but the checkbox is not ticked, the value counts as zero (the rule will not be enabled).&lt;br /&gt;
&lt;br /&gt;
 function get_data() {&lt;br /&gt;
     $data = parent::get_data();&lt;br /&gt;
     if (!$data) {&lt;br /&gt;
         return $data;&lt;br /&gt;
     }&lt;br /&gt;
     if (!empty($data-&amp;gt;completionunlocked)) {&lt;br /&gt;
         // Turn off completion settings if the checkboxes aren&#039;t ticked&lt;br /&gt;
         $autocompletion = !empty($data-&amp;gt;completion) &amp;amp;&amp;amp; $data-&amp;gt;completion==COMPLETION_TRACKING_AUTOMATIC;&lt;br /&gt;
         if (empty($data-&amp;gt;completionpostsenabled) || !$autocompletion) {&lt;br /&gt;
            $data-&amp;gt;completionposts = 0;&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
     return $data;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
You may have noticed the &#039;completionunlocked&#039; check. When some users have already completed the activity, the completion settings are &#039;locked&#039;; they are disabled and cannot be edited, so there will be no value set for those fields in the &amp;lt;code&amp;gt;$data&amp;lt;/code&amp;gt; object. Normally this will automatically work but when dealing with checkboxes you need to include a check for the &#039;completionunlocked&#039; value before doing anything that would cause one of those fields to be changed in the database.&lt;br /&gt;
&lt;br /&gt;
Finally, forum already had a &amp;lt;tt&amp;gt;data_preprocessing&amp;lt;/tt&amp;gt; function but I added code to this to set up the checkboxes when the form is displayed, and to make the default value of the text fields 1 instead of 0:&lt;br /&gt;
&lt;br /&gt;
 function data_preprocessing(&amp;amp;$default_values){&lt;br /&gt;
     // [Existing code, not shown]&lt;br /&gt;
 &lt;br /&gt;
     // Set up the completion checkboxes which aren&#039;t part of standard data.&lt;br /&gt;
     // We also make the default value (if you turn on the checkbox) for those&lt;br /&gt;
     // numbers to be 1, this will not apply unless checkbox is ticked.&lt;br /&gt;
     $default_values[&#039;completionpostsenabled&#039;]=&lt;br /&gt;
         !empty($default_values[&#039;completionposts&#039;]) ? 1 : 0;&lt;br /&gt;
     if(empty($default_values[&#039;completionposts&#039;])) {&lt;br /&gt;
         $default_values[&#039;completionposts&#039;]=1;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Phew! That&#039;s the form done.&lt;br /&gt;
&lt;br /&gt;
=== Completion state function ===&lt;br /&gt;
&lt;br /&gt;
When you create completion conditions, you need to write a function &#039;&#039;module&#039;&#039;&amp;lt;tt&amp;gt;_get_completion_state&amp;lt;/tt&amp;gt; that checks the value of those conditions for a particular user. &lt;br /&gt;
&lt;br /&gt;
The function receives as parameters &amp;lt;tt&amp;gt;$course&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;$cm&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;$userid&amp;lt;/tt&amp;gt; - all self-explanatory, I hope - and &amp;lt;tt&amp;gt;$type&amp;lt;/tt&amp;gt;. This has two values: &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;COMPLETION_AND&#039;&#039;&#039; - if multiple conditions are selected, the user must meet all of them.&lt;br /&gt;
* &#039;&#039;&#039;COMPLETION_OR&#039;&#039;&#039; (not currently used) - if multiple conditions are selected, any one of them is good enough to complete the activity.&lt;br /&gt;
&lt;br /&gt;
Your function should return:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;true&#039;&#039;&#039; if your custom completion options are enabled and the user meets the conditions.&lt;br /&gt;
* &#039;&#039;&#039;false&#039;&#039;&#039; if your custom completion options are enabled but the user does not yet meet the conditions.&lt;br /&gt;
* &amp;lt;tt&amp;gt;$type&amp;lt;/tt&amp;gt; (not false!) if none of your custom completion options are not enabled.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the function for forum (simplified to include only the one completion option):&lt;br /&gt;
&lt;br /&gt;
 /**&lt;br /&gt;
  * Obtains the automatic completion state for this forum based on any conditions&lt;br /&gt;
  * in forum settings.&lt;br /&gt;
  *&lt;br /&gt;
  * @param object $course Course&lt;br /&gt;
  * @param object $cm Course-module&lt;br /&gt;
  * @param int $userid User ID&lt;br /&gt;
  * @param bool $type Type of comparison (or/and; can be used as return value if no conditions)&lt;br /&gt;
  * @return bool True if completed, false if not, $type if conditions not set.&lt;br /&gt;
  */&lt;br /&gt;
 function forum_get_completion_state($course,$cm,$userid,$type) {&lt;br /&gt;
     global $CFG,$DB;&lt;br /&gt;
 &lt;br /&gt;
     // Get forum details&lt;br /&gt;
     if(!($forum=$DB-&amp;gt;get_record(&#039;forum&#039;,array(&#039;id&#039;=&amp;gt;$cm-&amp;gt;instance)))) {&lt;br /&gt;
         throw new Exception(&amp;quot;Can&#039;t find forum {$cm-&amp;gt;instance}&amp;quot;);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     // If completion option is enabled, evaluate it and return true/false &lt;br /&gt;
     if($forum-&amp;gt;completionposts) {&lt;br /&gt;
         return $forum-&amp;gt;completionposts &amp;lt;= $DB-&amp;gt;get_field_sql(&amp;quot;&lt;br /&gt;
 SELECT &lt;br /&gt;
     COUNT(1) &lt;br /&gt;
 FROM &lt;br /&gt;
     {forum_posts} fp &lt;br /&gt;
     INNER JOIN {forum_discussions} fd ON fp.discussion=fd.id&lt;br /&gt;
 WHERE&lt;br /&gt;
     fp.userid=:userid AND fd.forum=:forumid&amp;quot;,&lt;br /&gt;
             array(&#039;userid&#039;=&amp;gt;$userid,&#039;forumid&#039;=&amp;gt;$forum-&amp;gt;id));&lt;br /&gt;
     } else {&lt;br /&gt;
         // Completion option is not enabled so just return $type&lt;br /&gt;
         return $type;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Notifying the completion system ===&lt;br /&gt;
&lt;br /&gt;
Finally you need to notify the completion system whenever these values might have changed for a user (in the case of the forum example, whenever somebody adds or deletes a post). The completion system will end up calling the function above - but only if it needs to. &lt;br /&gt;
&lt;br /&gt;
* To ensure performance is not compromised, you should notify the system only when the completion state might actually have changed. Don&#039;t notify the system unless your custom completion rule is actually enabled.&lt;br /&gt;
* You need to pass in the &#039;possible result&#039; of the change. This is used to significantly improve performance.  There are three values:&lt;br /&gt;
** &#039;&#039;&#039;COMPLETION_COMPLETE&#039;&#039;&#039; - this change will either have no effect on the user&#039;s completion state, or it will make it complete. The change cannot make a user&#039;s state &#039;&#039;in&#039;&#039;complete if it was complete previously. In the forum example, when you add a post, there is no way this can make the user&#039;s state incomplete, so this possible result applies.&lt;br /&gt;
** &#039;&#039;&#039;COMPLETION_INCOMPLETE&#039;&#039;&#039; - this change will either have no effect on the user&#039;s completion state, or it will make it incomplete. The change cannot make a user&#039;s state complete if it was incomplete previously. Deleting a forum post would fall into this category.&lt;br /&gt;
** &#039;&#039;&#039;COMPLETION_UNKNOWN&#039;&#039;&#039; - this change might have either effect. Using this option is much slower than the others, so try to avoid using it in anything that might happen frequently.&lt;br /&gt;
* If the user whose completion state would be updated is not the current user, then the optional &amp;lt;tt&amp;gt;$userid&amp;lt;/tt&amp;gt; parameter must be included. For example, if a teacher deletes a student&#039;s forum post, then it is the student&#039;s completion state which may need updating, not the teacher&#039;s.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code that runs when somebody makes a new forum post:&lt;br /&gt;
&lt;br /&gt;
 // Update completion state&lt;br /&gt;
 $completion=new completion_info($course);&lt;br /&gt;
 if($completion-&amp;gt;is_enabled($cm) &amp;amp;&amp;amp; $forum-&amp;gt;completionposts) {&lt;br /&gt;
     $completion-&amp;gt;update_state($cm,COMPLETION_COMPLETE);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[[Conditional activities|Activity completion and availability]] - Original Specification&lt;br /&gt;
&lt;br /&gt;
[[Course completion]] - Original Specification&lt;br /&gt;
&lt;br /&gt;
[[Policy|Retroactive effects of of completion settings]]&lt;br /&gt;
&lt;br /&gt;
[[Core APIs]]&lt;br /&gt;
&lt;br /&gt;
=== User Docs ===&lt;br /&gt;
[https://docs.moodle.org/en/Category:Completion Completion Docs]&lt;br /&gt;
&lt;br /&gt;
[https://docs.moodle.org/en/Activity_completion Activity Completion]&lt;br /&gt;
&lt;br /&gt;
[https://docs.moodle.org/en/Course_completion Course Completion]&lt;br /&gt;
&lt;br /&gt;
[[Category:Conditional activities]]&lt;br /&gt;
&lt;br /&gt;
[[Category:API]]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Moodle_architecture&amp;diff=39155</id>
		<title>Moodle architecture</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Moodle_architecture&amp;diff=39155"/>
		<updated>2013-04-18T14:05:21Z</updated>

		<summary type="html">&lt;p&gt;Raymor: /* Activity and course completion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The aim of this document is to quickly give an overview of how the Moodle works at a technical level. Hopefully this will be helpful to Administrators and Developers. However, to actually do Moodle development you will have to study the code in much more detail than is provided here. See the [[Developer_documentation|developer documentation]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==What is Moodle?==&lt;br /&gt;
&lt;br /&gt;
Moodle is a Learning Management System, Course Management System, or Virtual Learning Environment, depending on which term you prefer. Its goal is to give teachers and students the tools they need to teach and learn. Moodle comes from a background of [[:en:Pedagogy|Social Constructionist pedagogy]], however, it can be used to support any style of teaching and learning.&lt;br /&gt;
&lt;br /&gt;
There are other types of software systems that are important for educational institutions, for example ePortfolios, Student Information Systems and Content repositories. Generally, Moodle does not try to re-invent these areas of functionality. Instead, tries to be the best LMS possible, and then interoperate gracefully with other systems that provide the other areas of functionality. It is, however, perfectly possible to use Moodle as a stand-alone system, without integrating it with anything else.&lt;br /&gt;
&lt;br /&gt;
Moodle is a web application written in PHP. Moodle is open source. Copyright is owned by individual contributors, not assigned to a single entity, although the company Moodle Pty Ltd in Perth Australia, owned by Moodle&#039;s founder Martin Dougiamas, manages the project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Overview of a Moodle installation==&lt;br /&gt;
&lt;br /&gt;
A Moodle installation comprises the Moodle code executing in a PHP-capable web server; a database managed by MySQL, PostgreSQL, Microsoft SQL Server, or Oracle; and a file store for uploaded and generated files (the moodledata folder).&lt;br /&gt;
&lt;br /&gt;
All three parts can run on a single server; or they can be separated with many load-balanced web-servers, a database cluster, and a file-server; or anywhere between those extremes.&lt;br /&gt;
&lt;br /&gt;
Moodle is designed to be simple to install on any server that meets these basic requirements. Moodle self-installs once the code has been copied to the web server and a blank database created (see [[:en:Installing Moodle]]). Similarly, Moodle can always self-upgrade from one version to the next (see [[:en:Upgrading]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Moodle as a modular system==&lt;br /&gt;
&lt;br /&gt;
Like many successful open source systems, Moodle is structured as an application core, surrounded by numerous plugins to provide specific functionality. Moodle is designed to be highly extensible and customizable without modifying the core libraries, as doing so would create problems when upgrading Moodle to a newer version. So when customizing or extending your own Moodle install, always do so through the plugin architecture. &lt;br /&gt;
&lt;br /&gt;
Plugins in Moodle are of specific types. That is, an authentication plugin and an activity module will communicate with Moodle core using different APIs, tailored to the type of functionality the plugin provides. Functionality common to all plugins (installation, upgrade, permissions, configuration, ...) are, however, handled consistently across all plugin types.&lt;br /&gt;
&lt;br /&gt;
The standard Moodle distribution includes Moodle core and a number of plugins of each type, so that a new Moodle installation can immediately be used to start teaching and learning. After installation a Moodle site can be adapted for a particular purpose by changing the default configuration option, and by installing and removing plugins. Most plugins that have been shared publicly are listed in the [http://moodle.org/plugins/index.php Moodle Plugins Directory].&lt;br /&gt;
&lt;br /&gt;
Physically, a Moodle plugin is just a folder of PHP scripts (and CSS, JavaScript, etc. if necessary). Moodle core communicates with the plugin by looking for particular entry points, often defined in the file &amp;lt;tt&amp;gt;lib.php&amp;lt;/tt&amp;gt; within the plugin.&lt;br /&gt;
&lt;br /&gt;
==An overview of Moodle core==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Apologies, this section is not complete yet. If you have the knowledge and time, please add to it.--[[User:Tim Hunt|Tim Hunt]] 18:28, 8 December 2010 (UTC)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Moodle core provides all the infrastructure necessary to build an LMS. It implements the key concepts that all the different plugins will need to work with. These include&lt;br /&gt;
&lt;br /&gt;
===Courses and activities===&lt;br /&gt;
&lt;br /&gt;
A Moodle course is a sequence of activities and resources grouped into sections. Courses themselves are organised into a hierarchical set of categories within a Moodle site.&lt;br /&gt;
&lt;br /&gt;
===Users===&lt;br /&gt;
&lt;br /&gt;
Users, profile, my moodle ...&lt;br /&gt;
&lt;br /&gt;
===Groups and cohorts===&lt;br /&gt;
&lt;br /&gt;
===Enrolments and access control===&lt;br /&gt;
&lt;br /&gt;
Contexts, roles, capabilities, and permissions, ...&lt;br /&gt;
&lt;br /&gt;
===Activity and course completion===&lt;br /&gt;
&lt;br /&gt;
The activity completion system allows activities such as Quizzes, SCORM modules, etc. to be marked complete when specified conditions are met.&lt;br /&gt;
For more information, see [[Activity_completion_API]]&lt;br /&gt;
&lt;br /&gt;
===Navigation, settings and configuration===&lt;br /&gt;
&lt;br /&gt;
===Forms library===&lt;br /&gt;
&lt;br /&gt;
===JavaScript library===&lt;br /&gt;
&lt;br /&gt;
Moodle has adopted the [http://developer.yahoo.com/yui/3/ Yahoo User Interface library]. There is also a nice system for loading the additional JavaScript files required by each page.&lt;br /&gt;
&lt;br /&gt;
===Installation and upgrade===&lt;br /&gt;
&lt;br /&gt;
===Logs and statistics===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==The most important plugin types==&lt;br /&gt;
&lt;br /&gt;
===Activities and resources===&lt;br /&gt;
&lt;br /&gt;
Activities and resources are the most basic individual components that make up a course and are the main tools for teaching and learning. Some examples of resources are: pages, links and IMS content packages. Examples of activities include: forums, wikis, quizzes, and assignments.&lt;br /&gt;
&lt;br /&gt;
Activities are by far the largest type of plugin in terms of amount of code. A forum or wiki system could be a software project in its own right. Both activities and resources are installed in the &amp;lt;tt&amp;gt;mod&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
===Blocks===&lt;br /&gt;
&lt;br /&gt;
Blocks are small bits of interface functionality that can be added to (normally the sides of) pages. Many blocks provide additional views of data stored and modified elsewhere. Blocks live in the &amp;lt;tt&amp;gt;blocks&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
===Themes===&lt;br /&gt;
&lt;br /&gt;
The overall visual style of a Moodle site, a particular course, or all courses in a category, can be changed by selecting a different theme at these different levels. Themes are the standard way of making aesthetic changes to your Moodle application, decoupling presentation from content and functionality.&lt;br /&gt;
&lt;br /&gt;
Themes live in the &amp;lt;tt&amp;gt;theme&amp;lt;/tt&amp;gt; folder, and published themes are listed in the [http://moodle.org/mod/data/view.php?id=6552 Themes database].&lt;br /&gt;
&lt;br /&gt;
===Language packs===&lt;br /&gt;
&lt;br /&gt;
Moodle is internationalised. That is, you can get language packs for many different languages. Language packs are normally downloaded and installed via the Moodle administration screens, but they can also be downloaded manually from [http://download.moodle.org/langpack/ Moodle.org: language packs].&lt;br /&gt;
&lt;br /&gt;
Administrators can also manually change any of the standard user interface strings if the terms used in the installed language pack are not appropriate.&lt;br /&gt;
&lt;br /&gt;
===Course formats===&lt;br /&gt;
&lt;br /&gt;
control how the structure of the course, a sequence of activities grouped into sections, is presented to the users. Course formats live in the &amp;lt;tt&amp;gt;course/format&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
===Authentication plugins===&lt;br /&gt;
&lt;br /&gt;
control how users log in. Moodle can manage usernames and passwords itself, or use those stored in LDAP or another database. Alternatively, Moodle can use a number of single-sign-on schemes. Authentication plugins live in the &amp;lt;tt&amp;gt;auth&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
===Enrolment plugins===&lt;br /&gt;
&lt;br /&gt;
control which users are enrolled in which courses. Again this can be by synchronising with another system, perhaps a student information system, or it can be tracked internally by Moodle. Enrolment plugins live in the &amp;lt;tt&amp;gt;enrol&amp;lt;/tt&amp;gt; folder. (Moodle was created by an Australian, so enrol is the correct spelling ;-).)&lt;br /&gt;
&lt;br /&gt;
===Repository plugins===&lt;br /&gt;
&lt;br /&gt;
Ways for users to get content (files) into Moodle, either by uploading from their hard drive, or by getting the file from another location on the Internet, perhaps Drop Box, Google Docs, or Flickr. Repository plugins live in the &amp;lt;tt&amp;gt;repository&amp;lt;/tt&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
===Others===&lt;br /&gt;
&lt;br /&gt;
There are [[Developer_documentation#Make_a_new_plugin|many more types of plugins]] (more than 30 at the last count). These include text filters, question types, gradebook reports, admin reports, course reports, plagiarism detection services and web service protocols.&lt;br /&gt;
&lt;br /&gt;
For a definitive, up-to-date list, look at the value returned by the &amp;lt;tt&amp;gt;get_plugin_types()&amp;lt;/tt&amp;gt; function, which is defined in &amp;lt;tt&amp;gt;lib/moodlelib.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==How Moodle code is organised==&lt;br /&gt;
&lt;br /&gt;
Moodle mostly follows a [http://martinfowler.com/eaaCatalog/transactionScript.html transaction script] approach. That is, suppose you are looking a Forum. The URL will be &amp;lt;tt&amp;gt;.../mod/forum/view.php?id=1234&amp;lt;/tt&amp;gt;. and &amp;lt;tt&amp;gt;mod/forum/view.php&amp;lt;/tt&amp;gt; the PHP script that generates that page. One could argue that transaction script is not an appropriate pattern for an application as complex as Moodle. However, it is a very natural architecture for a PHP application, and Moodle is an aggregate of many different plugins, rather than a single complex application.&lt;br /&gt;
&lt;br /&gt;
Behind that basic transaction script approach, a lot of the core functionality has be refactored out into libraries (mostly in the &amp;lt;tt&amp;gt;lib&amp;lt;/tt&amp;gt; folder). This provides elements of a [http://martinfowler.com/eaaCatalog/domainModel.html domain model]. The Moodle project started before PHP could handle object-oriented code, however, so don&#039;t expect an object-oriented domain model except in some of the more recent parts of the Moodle code.&lt;br /&gt;
&lt;br /&gt;
There are two layers used to separate presentation from the business logic. The outer layer is the theme (see above) which controls the more visual aspects of the Moodle interface. Then there are renderer classes which generate the HTML to be output from the data supplied by the transaction scripts and the domain model. Unfortunately, neither PHP, nor the Moodle architecture, enforces a clear separation of the UI layer. It is possible for sloppy developers to make a mess, and this has happened in the past. The code in the standard Moodle distribution is gradually being cleaned up.&lt;br /&gt;
&lt;br /&gt;
==The Moodle database==&lt;br /&gt;
&lt;br /&gt;
The Moodle database comprises many tables (more than 250) because the whole database is an aggregate of the core tables and the tables belonging to each plugin. Fortunately, this large structure is understandable, because the tables for one particular plugin typically only link to each other and a few core tables. See [[Database_schema_introduction|Database schema introduction]] for more information.&lt;br /&gt;
&lt;br /&gt;
The Moodle database structure is defined in &amp;lt;tt&amp;gt;install.xml&amp;lt;/tt&amp;gt; files inside the &amp;lt;tt&amp;gt;db&amp;lt;/tt&amp;gt; folder in each plugin. For example &amp;lt;tt&amp;gt;mod/forum/db/install.xml&amp;lt;/tt&amp;gt; contains the database definition for the forum module. &amp;lt;tt&amp;gt;lib/db/install.xml&amp;lt;/tt&amp;gt; defines the tables used by Moodle core. The &amp;lt;tt&amp;gt;install.xml&amp;lt;/tt&amp;gt; files contain comments that should explain the purpose of each table and column. These comments can be turned into human-readable documentation by going to Site administration -&amp;gt; Development -&amp;gt; XMLDB editor in your Moodle installation, and clicking on the [Doc] link.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[:en:Administrator documentation]]&lt;br /&gt;
* [[Developer_documentation|Developer documentation]]&lt;br /&gt;
* [[Database_schema_introduction|Database schema introduction]]&lt;br /&gt;
* [http://moodle.org/mod/data/view.php?id=6009 Modules and plugins] and [http://moodle.org/mod/data/view.php?id=6552 themes] databases&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=64465 Forum thread with a vigorous argument about whether an architecture document is a good idea, which eventually lead to this page being rewritten]&lt;br /&gt;
* [http://www.aosabook.org/en/moodle.html The chapter of The Architecture of Open Source Applications about Moodle]&lt;br /&gt;
&lt;br /&gt;
[[Category:Coding guidelines]]&lt;/div&gt;</summary>
		<author><name>Raymor</name></author>
	</entry>
</feed>