Development:NEWMODULE Documentation

From MoodleDocs
(Redirected from newmodule)

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


Template:New Module 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.

Template:Moodle 1.9

Getting started

Base module folder content

To download the newmodule package, please refer to:

Although you can download the newmodule package for moodle 1.8, such as 1.9 and HEAD, this tutorial is intended for the newmodule development in Moodle 1.9 only.

Let's start by getting an idea about what you find in the newmodule folder taken from http://download.moodle.org/plugins19/mod/NEWMODULE.zip

  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

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

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.

icon.gif

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

index.php

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

lang

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

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 have two well differenced parts:

  • All the core Moodle functions, neeeded to allow the module to work integrated in Moodle.
  • All the newmodule specific functions, needed to implement all the module logic.

Please, note that, if the module become complex and this lib grows a lot, it's HIGHLY recommended to move all these module specific functions to a new php file, called "locallib.php" (see forum, quiz...). This will help to save some memory when Moodle is performing actions across all modules.

There are convention to name functions into lib.php and locallib.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 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.

Two more functions should be added to lib.php are:

  • function newmodule_get_view_actions()
  • function newmodule_get_post_actions()

They distinguish between "read" and "post" log actions. These functions are used by moodle core during log gather. The actions you list inside these two functions, must match the ones you listed in the table "log_display" in install.xml

Connection between lib.php and locallib.php

One important issue is about the connection between lib.php and locallib.php. Who has to call the other, how and why? It has to be locallib.php to call lib.php through:

 require_once("$CFG->dirroot/mod/newmodule/lib.php");

as first line.

In this way, if moodle core calls function inside mod/newmodule/lib.php no module specific function will be loaded in memory. If it is your newmodule to call a function, it has to require_once('locallib.php'); that, in turn, will require_once('lib.php') so that your module will "see" all its available functions.

mod_form.php

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 Development: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->standard_coursemodule_elements();
 //------------------------------------------------------------------------------

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;
 $this->standard_coursemodule_elements($features);
 //------------------------------------------------------------------------------

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: print_object($newmodule);
  • 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;
   }

}

README.txt

This is the file where you are welcome to write what your newmodule does.

version.php

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

view.php

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 five files that are not present in the newmodule package that 90% of times you will go to add to your newmodule.

locallib.php
The first one is locallib.php already described before.
access.php
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: https://docs.moodle.org/en/Development:NEWMODULE_Adding_capabilities
settings.php
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
backuplib.php
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.
restorelib.php
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 Development: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: print_string('welcomemessage','newmodule'); 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

if (newmodule_hascapabilitytodothis()) {

   //user is allowed

} else {

   // user is not allowed

}

typing in locallib.php

function newmodule_hascapabilitytodothis($cm) {

   $context = get_context_instance(CONTEXT_MODULE, $cm->id);
   return (has_capability('mod/newmodule:candothis', $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:

require_once('myscript.php');


To include php library, try:

require_once('locallib.php');


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

require_once('config.php')

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


Template:CategoryDeveloper