NEWMODULE Documentation

Jump to: navigation, search

Note: This page is a work-in-progress. Feedback and suggested improvements are welcome. Please join the discussion on or use the page comments.

This first draft of Moodle Docs page about the creation of a new module is divided into the some sections. See block NEWMODULE at right side.


Getting started

Base module folder content

We have created a NEWMODULE package, which a skeleton for a new module:

This tutorial was written for the 1.9 version and has not been updated yet for Moodle 2.x. Until it is updated, however, most of it should still apply.

Let's start by getting an idea about what you find in the newmodule folder taken from

  1. db/install.xml
  2. db/upgrade.php
  3. icon.gif
  4. index.php
  5. lang/en_utf8/help/newmodule/index.html
  6. lang/en_utf8/help/newmodule/mods.html
  7. lang/en_utf8/newmodule.php
  8. lib.php
  9. mod_form.php
  10. README.txt
  11. version.php
  12. view.php

The path where you find each file is the correct one. So don't change the path of files and folders in this newmodule package.

Inside the db folder, at the beginning, you can only find install.xml and upgrade.php but sooner you will start to always add the new file "access.php".


db/install.xml is the file to write the xml describing the tables needed by the module. Tables are at least two, first named with the same name of the module, second named "log_display". They follow a strict syntax that you can learn by editing one of the several example you can find inside moodle modules. Ultimately the only thing to take care is the <<previous>> <<next>> connection between tables and fields. This is the mandatory file where you MUST write the structure of the tables your module is going to use. The table "log_display" is the tables where you are requested to list all the "actions" that you will add to the logs of your module.


db/upgrade.php is the file that you will write each time you need to change the structure of the tables of your module.

To learn how to write this file, please refer to the examples you may find in the file itself.


It is a 16px per 16px icon identifying each instance of your module in the frame of a course.


index.php is a page to list all instances of the functionality the module provides in a course.


lang is the folder reserved to language packs.

A module language pack is a folder named "xx_utf8" containing, in turn, a folder named "help" and a language file named with the same name of the module. xx is the two char long name of the language, i.e. en, de, es, it, fr and so forth. Each language file is dedicated to a specific language. The lang folder may contain as much language packs as provided by different translators.

The lang/xx_utf8/help/ folder contains all the help files you want to provide to your module. In order to link a help file from inside the code of your module pages use $mform->setHelpButton in mod_form.php and in other places use
helpbutton('<<name of your help file saved in lang/xx_utf8/help/>>', get_string('your_string','newmodule'), 'newmodule');


lib.php is the pre-filled file with "core" functions needed by each module.

Almost all newmodule functions go here. Each of them must have a name that starts with newmodule_ This file should contain only the standard moodle API functions, needed to allow the module to work integrated in Moodle.

All the newmodule specific functions, needed to implement the rest of the module logic should live in autoloaded classes inside the newmodule/classes directory. This will help to save some memory when Moodle is performing actions across all modules. See Automatic class loading for more information.

There are convention to name functions into lib.php. See:

There are some details just above the each function in lib.php.

Mandatory function are, at least:

Module instance editing form handlers, that called from /course/mod.php or /course/modedit.php:

  • function newmodule_add_instance($newmodule)

This function is executed after an editing teacher create an instance of newmodule.

  • function newmodule_update_instance($newmodule)

This function is executed after an editing teacher update an instance of newmodule

  • function newmodule_delete_instance($id)

This function is executed after an editing teacher delete an instance of newmodule

  • function newmodule_user_outline()
  • function newmodule_user_complete($course, $user, $mod, $newmodule)
  • function newmodule_print_recent_activity($course, $isteacher, $timestart)
  • function newmodule_cron()

Take care with this function. Differently by all the other functions, this function is not called by passing it the $newmodule record. This means that this function, called by moodle core cron has to look for each newmodule instance id before operating.

Don't worry, even if you have more than a single instance of your module among moodle courses, this function will be executed just one time.

  • function newmodule_get_participants($newmoduleid)
  • function newmodule_scale_used($newmoduleid, $scaleid)
  • function newmodule_scale_used_anywhere($scaleid)

  • function newmodule_install()
  • function newmodule_uninstall()

Some more functions should be added:

  • function newmodule_reset_course_form_definition(&$mform)
  • function newmodule_reset_course_form_defaults($course)
  • function newmodule_reset_userdata($data)

These three functions are responsible for the newmodule reset process during the more general course reset process. Please, refer to mod/data/lib.php or to mod/feedback/lib.php, for instance, to understand them better.

Another functions that can be added to lib.php is:

  • function newmodule_get_shortcuts($defaultmodule) - returns the list of items to be added to the "Activity chooser" instead of the default one. This is used in mod/lti/lib.php
  • function newmodule_check_updates_since) - Check if the module has any update that affects the current user since the given time. Please refer to mod/assign/lib.php, mod/forum/lib.php or mod/quiz/lib.php for sample code.

If your module uses the calendar then you should consider adding and implementing the following in lib.php.

  • function newmodule_refresh_events($courseid, $instance = null, $cm = null) - This updates all relevant calendar events with changes made to the activity, such as a change in name.


mod_form.php is the file describing the form you get at the module instance creation or at the instance editing time.

There are only one class definition, that extends class moodleform_mod from /course/moodleform_mod.php.

The syntax for add new form elements is very simple and by reading the file it is simple to change it on your need. It uses the syntax you can learn in lib/formslib.php_Form_Definition.

This file used only from /course/modedit.php.

At date, there is a missing detail by the end of the file. You can read:

  // add standard elements, common to all modules

This part with one call of function inherited from moodleform_mod that is responsible for the common modules section at the end of your newmodule editing instance page. The section related to groups, outcomes, grades, visibility etc. This code can be customized by settings object passed to it:

  // add standard elements, common to all modules
  $features = new object();
  $features->groups           = false;
  $features->groupings        = false;
  $features->groupmembersonly = true;

One more tip about this file.

  • Once you submit the form described by this file, your module executes the function: newmodule_add_instance or newmodule_update_instance both pre-written in lib.php.
  • It seems that check boxes in the editing instance form don't work. To test this, please verify the passed parameter $newmodule inside your function newmodule_update_instance through a simple:
  • You will find that even by selecting or unselecting the check box in the newmodule instance editing form, the corresponding value in the array doesn't change. This is not an error, but at least a lack of code. You will find that all works fine by adding at the beginning of both functions a simple code like this:
$checkboxes = array('myfirstcheckboxfield', 'mysecondcheckboxfield', and so fort with all your checkbox field);
foreach ($checkboxes as $checkbox) {
    if (empty($newmodule->{$checkbox})) {
        $newmodule->{$checkbox} = 0;


This is the file where you are welcome to write what your newmodule does. Include instructions to start of using your plugin such as installation steps.

If you plan to publish your module at Github, you may consider to call the file and format it with Markdown syntax.


List of all 3rd party libraries bundled with a plugin.


<?xml version="1.0"?>
    <name>Library name</name>

Where location is a relative path to library directory or file. Please note that license must be always compatible with GNU GPL 3.


version.php is a really very simple file as simple as important.

To understand why it is important, you need to know that there are a bunch of actions that moodle performs for your newmodule ONLY (with only one exception) at the newmodule installation. They are, at least, db tables editing and load of capability. If during the development of your module (that you already installed on your development environment or that you already shared with remote users) you need to change the structure of your newmodule tables or you need to change the capability used by your newmodule, you need to force moodle to edit tables and reload capability.

This is done by:

  • adding the proper code in newmodule/db/upgrade.php (to do this, use XMLDB as stated in this same page below)
  • increasing the newmodule version in version.php
  • visiting the notification page of your installation of Moodle


This is the first executed code of your module. By selecting the link of the instance of your module, the code of newmodule/view.php is executed.

Some very important missing files

There are four files that are not present in the newmodule package that 90% of times you will go to add to your newmodule.

The second one is access.php that has to be saved inside newmodule/db/ folder.
In this file you will add all the capability used by your newmodule and loaded at the installation time or upgrade time. To learn the syntax of the capability, please refer to the same file in other modules or to:
The third missing file must be added to newmodule/ folder. It is settings.php and describes the form that can be accessed from: Site Administration block -> Modules -> Activities -> <<your newmodule name>>
This form stores general settings for your newmodule into the site wide $CFG object. Because of this, it is strongly recommended to give to your newmodule general settings with names starting with "newmodule_". This file is useful when there is a setting that doesn't depend from the instance. I.e., if your newmodule simulates a telephone, you will probably save your telephone number in this newmodule setting site wide form instead of typing it each time you add a new instance of your newmodule into a course. In this case, to refer to you telephone number inside your newmodule you will use: $CFG->newmodule_telephonenumber
Directly in the newmodule folder, you need to add backuplib.php that is responsible for the backup of each instance of your module and of its log.
To learn how to code it, start by stealing it from some other module and read it.
Again in the newmodule folder, you need to add restorelib.php that is responsible for the restore of each instance your module and of its log.
To learn how to code it, start by stealing it from some other module and read it.

Let's start

To start using a downloaded package, please perform the 7 actions described in NEWMODULE_Tutorial in How to Begin the Creation of a New Module paragraph.

Then, draw the structure of your tables on a sheet, edit the file db/install.xml according to your project, save, put your renamed newmodule folder in moodle/mod/ and visit the moodle notification page.

To add code to db/upgrade.php never do it manually. I always make use of Site Administration block -> Miscellaneous -> XMLDB editor and I ask it to write the code for me. It never fails.

Please remember: within your module, never use "embedded messages" like:

echo 'Welcome to this newmodule';

but make use of get_string or print_string. In this way your module will be multilang with a really small effort. Use, for instance:


saving in newmodule/lang/en_utf8/newmodule.php

$string['welcomemessage'] = 'Welcome to this newmodule';

Some code snippets that I find useful

Check the capability of a user

$mod = mod_newmodule\newmodule($cm)
if ($mod->usercandothis()) {
    //user is allowed
} else {
    // user is not allowed

typing in mod/newmodule/classes/newmodule.php

namespace mod_newmodule;
class newmodule {
    private $cm;
    private $context;
    __construct(\cm_info $cm) {
        $this->cm = $cm;
        $this->context = context_module::instance($cm->id);
    public function usercandothis() {
        return (has_capability('mod/newmodule:candothis', $this->context));

typing in db/access.php

$mod_newmodule_capabilities = array(
    'mod/newmodule:candothis' => array(
        'captype' => 'read',
        'contextlevel' => CONTEXT_MODULE,
        'legacy' => array(
            'teacher' => CAP_ALLOW,
            'editingteacher' => CAP_ALLOW,
            'admin' => CAP_ALLOW

Edit the tables in use by your newmodule

  • edit db/install.xml manually by editing fields and or tables in the xml structure.
  • go to Site Administration block -> Miscellaneous -> XMLDB editor and load the tables of your module
  • ask to the XMLDB editor the snippets of code you need to add to db/upgrade.php
  • copy and paste in db/upgrade.php
  • in the line:
    if ($result && $oldversion < xxxxxxxxxxxx)
    (replace xxxxxxxxxxxx with the version number you are going to give to your newmodule)
  • change (increase) the version number
  • visit the Moodle notification page

Add a single line to logs from your newmodule

add_to_log($course->id, 'newmodule', '<<action already listed in log_display>>', "view.php?id=$cm->id", "$newmodule->id");

Ensure that remote user will not be able to contact your pages by typing their URL directly in the address bar

as first line of each of your php script

if (!defined('MOODLE_INTERNAL')) {
    die('Direct access to this script is forbidden.'); // It must be included from a Moodle page

Some suggestion I find useful

To include php scripts, try:


To periodically execute function newmodule_cron(), try:

$module->cron = xxxx;
providing some code in:
function newmodule_cron()

Your function newmodule_cron() will be executed about each xxxx seconds

Do not include config when it is not needed


is not needed in library scripts

Do not use global $cm or $newmodule in your function but use proper function parameters.

So, never use:

function newmodule_lookatthesky() {
    global $cm, $newmodule;
    // your stuff

but use:

function newmodule_lookatthesky($cm, $newmodule) {
    // your stuff

See also