Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Activity modules: Difference between revisions

From MoodleDocs
(Add a mention of course drag and drop upload support)
No edit summary
Line 1: Line 1:
== Introduction ==
Activity modules reside in the '''/mod''' directory.  They are the oldest type of plugins in Moodle - that's why they have this overly-generic name and also why they have a few idiosyncrasies and operate slightly differently from all the plugins that came later.
Activity modules reside in the '''/mod''' directory.  They are the oldest type of plugins in Moodle - that's why they have this overly-generic name and also why they have a few idiosyncrasies and operate slightly differently from all the plugins that came later.


Each module is in a separate subdirectory and consists of a number of ''''mandatory elements'''' (see below) plus extra scripts unique to each module.
Each module is in a separate subdirectory and consists of a number of ''''mandatory files'''' and any other files the developer is going to use. The below image is an example of the certificate module's filestructure.
 
[[File:Activities_file_structure_example.jpg]]
 
== Standard Files and their Functions ==
 
There are several files that Moodle looks for when using your module, they each have a particular function and are all not necessary. Below are the list of most commonly used files, to view them all please
 
=== Backup Folder ===
 
This is the location to place the files that define how your module is going to behave when a course backup or restore is performed. You may have added a lot of information to the database for a specific module that you do not wish to enter again when restoring a course, this is where you define what should be saved during a backup and how to then restore this information from the Moodle backup.
 
To read more on this please visit [[Backup_2.0_for_developers]] and [[Restore_2.0_for_developers]].
 
=== DB Folder ===
 
==== access.php ====
 
This is where you define what capabilities your plugin will create. Note, if you add new capabilities to this file after your plugin has been installed you will need to increase the version number in your version.php file (discussed later) in order for them to be installed.
 
An example of the file is below -
 
<code php>
 
$capabilities = array(
 
    'mod/certificate:addinstance' => array(
        'riskbitmask' => RISK_XSS,
        'captype' => 'write',
        'contextlevel' => CONTEXT_COURSE,
        'archetypes' => array(
            'editingteacher' => CAP_ALLOW,
            'manager' => CAP_ALLOW
        ),
        'clonepermissionsfrom' => 'moodle/course:manageactivities'
    ),
);
 
</code>
 
In Moodle 2.3 a new capability called 'addinstance' was added for all core modules. Moodle will look for this capability by searching for 'mod/<modname>:addinstance' and if it is not created then it assumed that the user does have this capability with a debug message being displayed that the capability is missing. To avoid this situation it is good to add this to your module. For further information on what each attribute in that capabalities array means visit [[NEWMODULE_Adding_capabilities]].
 
==== install.xml ====
 
This file is used on installation of your module. It includes the database tables and fields that your module will be creating. If your module does not require any new tables then this file is not necessary. In order to create this XML file please view [[XMLDB_editor]]. Please note, in the XML file the table names are listed without the config.php prefix, this is automatically used when creating the tables and does not need to be specified.
 
An example of this file is below -
 
<code php>
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/certificate/db" VERSION="20120925" COMMENT="XMLDB file for Moodle mod/certificate"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
  <TABLES>
    <TABLE NAME="certificate" COMMENT="Defines certificates" NEXT="certificate_issues">
      <FIELDS>
        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="course"/>
        <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="name"/>
        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="course" NEXT="intro"/>
        <FIELD NAME="intro" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="introformat"/>
        <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="intro" NEXT="emailteachers"/>
        <FIELD NAME="emailteachers" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="introformat" NEXT="emailothers"/>
        <FIELD NAME="emailothers" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="emailteachers" NEXT="savecert"/>
        <FIELD NAME="savecert" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="emailothers" NEXT="reportcert"/>
        <FIELD NAME="reportcert" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="savecert" NEXT="delivery"/>
        <FIELD NAME="delivery" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="reportcert" NEXT="requiredtime"/>
        <FIELD NAME="requiredtime" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="delivery" NEXT="type"/>
        <FIELD NAME="type" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="requiredtime" NEXT="orientation"/>
        <FIELD NAME="orientation" TYPE="char" LENGTH="10" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="type" NEXT="width"/>
        <FIELD NAME="width" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="orientation" NEXT="height"/>
        <FIELD NAME="height" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="width" NEXT="backgroundimage"/>
        <FIELD NAME="backgroundimage" TYPE="char" LENGTH="255" NOTNULL="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="height" NEXT="timecreated"/>
        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="backgroundimage"  NEXT="timemodified"/>
        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated"/>
      </FIELDS>
      <KEYS>
        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for certificate"/>
      </KEYS>
    </TABLE>
    <TABLE NAME="certificate_issues" COMMENT="Info about issued certificates" PREVIOUS="certificate" NEXT="certificate_images">
      <FIELDS>
        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="userid"/>
        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="certificateid"/>
        <FIELD NAME="certificateid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="userid" NEXT="timecreated"/>
        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="certificateid"/>
      </FIELDS>
      <KEYS>
        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for certificate_issues" NEXT="certificate"/>
        <KEY NAME="certificate" TYPE="foreign" FIELDS="certificateid" REFTABLE="certificate" REFFIELDS="id" PREVIOUS="primary"/>
      </KEYS>
    </TABLE>
  </TABLES>
</XMLDB>
</code>
 
The above example contains the structure of the table certificate and certificate_issues. Each table, field and key lists what element is before and after it (if there are any present). This is automatically created by the XMLDB editor. Your module should always have a table called after the module itself with the fields id, name and course.
 
==== upgrade.php ====
 
This file handles upgrading the module to match the latest version. After creating a module and using it extensively on your site (and others) you may want to extend the functionality of your module. Using the certificate example, a suggestion was made that a unique code could be generated for each certificate issued and displayed if a setting was selected. This requires two new database fields, one to store whether the user has chosen to display the code on the certificate and another to store the actual code. This is where the upgrade.php script becomes used. The install.xml file is only executed once, that is when your module is first installed, so adding these two extra columns to this file does not change the database structure for users who have already installed the module. So, to perform this upgrade you need to do three things.
 
1. Add the new columns to the install.xml file so that any users who install the module after this point are given the new table structure.
2. Add the instructions for the upgrade.php files.
3. Update the version number in your version.php file.
 
In this example we are only adding two new columns to the database, so we can use the XMLDB editor to change the install.xml file AND create the upgrade path. Please view [[XMLDB_editor]].
 
An example of the upgrade.php file is as follows -
 
<code php>
function xmldb_certificate_upgrade($oldversion=0) {
    if ($oldversion < 2012091801) {
        // Add new fields to certificate table.
        $table = new xmldb_table('certificate');
        $field = new xmldb_field('showcode');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'savecert');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        // Add new fields to certificate_issues table.
        $table = new xmldb_table('certificate_issues');
        $field = new xmldb_field('code');
        $field->set_attributes(XMLDB_TYPE_CHAR, '50', null, null, null, null, 'certificateid');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
    }
}
</code>
 
Whenever you change the version in your version.php module Moodle will look to see if anything needs to be done. The version that is stored in the database is passed to the xmldb_<modname>_upgrade function as the variable $oldversion in this case. In this example lets say that the initial version was 2012091600, since this is less than 2012091800 (the new version.php numer) we will execute the code in the if statement which will then update the version stored in the database meaning this if statement is never executed again. For more extensive details on this please see [[Upgrade_API]].
 
=== Lang Folder ===
 
This is where you store any strings you are going to use in your plugin. Each language has a specific folder that needs to be created in order for it to be used with your module. In this case we are going to use the English language (since unfortunately it is the only one I know). A folder called en is created in your lang folder that contains a file called <modname>.php that lists the translations of your string. For example, your module may have a setting called 'User preferences', rather than hard coding this term in your form, you use a placeholder that will then retrieve the appropriate string depending on the language being used on your Moodle site. There is one mandatory placeholder for modules called 'pluginname' that Moodle will use when listing this module as an option to add to a course and other various pages. To keep with Moodle standards you should order your strings alphabetically by the placeholder name.
 
<code php>
$string['pluginname'] = 'Certificate';
$string['userpreferences'] = 'User preferences';
</code>
 
If you wanted to add the French translation you would create a folder called fr and add the file <modname>.php to it.
 
<code php>
$string['pluginname'] = 'Certificat';
$string['userpreferences'] = 'Préférences d\'utilisateur';
</code>
 
Now, when using the string 'User preferences' we will use the Moodle function get_string instead, which will get the appropriate string depending on the language being used.
 
<code php>
get_string('userpreferences', '<modname>');
</code>
 
=== Pix folder ===
 
Here you simply store the icon you wish Moodle to display next to the name of your module. The name of the file should be icon.gif and is displayed with the resolution of 64 * 64. Feel free to use this folder to store other pictures you may use.
 
=== lib.php ===
 
The list of functions that are possible to override in the lib.php are listed here [[NEWMODULE_Documentation#lib.php]]. The essential ones are listed below
 
<code php>
function certificate_add_instance($certificate);
function certificate_update_instance($certificate);
function certificate_delete_instance($id);
</code>
 
The certificate_add_instance function is passed the variables from the mod_form.php file (discussed later) as an object when you first create an activity and click submit. This is where you can take that data, do what you want with it and then insert it into the database if you wish. This is only called once when the module instance is added, so this is where you should place the logic to add the activity.
The certificate_update_instance function is passed the variables from the mod_form.php file as an object whenever you update an activity and click submit.
The certificate_delete_instance function is passed the id of your module which you can use to delete the records from any database tables associated with that id. For example, in the certificate module the ID of the certificate table is passed, and then used to delete the certificate from the database, any issues of this certificate and any files associated with it on the filesystem.
 
=== mod_form.php ===
 
This file is used when adding/editing a module to a course. It contains the elements that will be displayed on the form responsible for creating/installing an instance of your module.
 
<code php>
if (!defined('MOODLE_INTERNAL')) {
    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
}
 
require_once($CFG->dirroot.'/course/moodleform_mod.php');
require_once($CFG->dirroot.'/mod/certificate/lib.php');
 
class mod_certificate_mod_form extends moodleform_mod {


In the example below we will assume a module called ''''widget'''', that is stored in the ''''/mod/widget'''' directory.  All functions and classes should have names starting with '''widget_'''' and any constants you define should start with ''''WIDGET_''''.  (Note that activity modules are the only exception from the normal frankenstyle naming rules which would normally have required prefixes like "mod_widget_")  
    function definition() {
        global $CFG, $DB, $OUTPUT;


* ''[[mod_form.php]]'' - a form to set up or update an instance of this module
        $mform =& $this->_form;
* ''[[version.php]]'' - defines some meta-info
* ''pix/icon.gif'' - a 16x16 icon for the module
* ''db/install.xml'' - defines the structure of db tables for all database types. Is used during module installation
* ''[[db/upgrade.php]]'' - defines changes in the structure of db tables. Is used during module upgrade
* ''[[db/access.php]]'' - defines module capabilities
* ''[[index.php]]'' - a page to list all instances in a course
* ''[[view.php]]'' - a page to view a particular instance
* ''[[lib.php]]'' - all functions intended to be called from OUTSIDE this activity module are here.  Required functions are:
:* widget_install() - will be called during the installation of the module
:* widget_add_instance() - code to add a new instance of widget
:* widget_update_instance() - code to update an existing instance
:* widget_delete_instance() - code to delete an instance
:* widget_user_outline() - given an instance, return a summary of a user's contribution
:* widget_user_complete() - given an instance, print details of a user's contribution
:* widget_get_view_actions() / widget_get_post_actions() - Used by the participation report (course/report/participation/index.php) to classify actions in the logs table.
:* Other functions available but not required are:
:** widget_delete_course() - code to clean up anything that would be leftover after all instances are deleted
:** widget_process_options() - code to pre-process the form data from module settings
:** [[Implementing Reset course functionality in a module|widget_reset_course_form() and widget_delete_userdata()]] - used to implement [[Reset course]] feature.
:** [[Implementing Course drag and drop upload support in a module|widget_dndupload_register() and widget_dndupload_handle()]] - used to support Course drag and drop upload.
* ''backuplib.php'' and ''restorelib.php'' (optional)
* ''settings.php'' or ''settingstree.php'' - (optional) a definition of an admin settings page for this module. mod/assignment/settings.php is a good simple example. mod/quiz/settingstree.php is a more complex example.
* ''defaults.php'' - lets you easily define default values for your configuration variables. It is included by upgrade_activity_modules in lib/adminlib.php. It should define an array $defaults. These values are then loaded into the config table. Alternatively, if you set $defaults['_use_config_plugins'] to true, the values are instead loaded into the config_plugins table, which is better practice. See mod/quiz/defaults.php for an example. (This apparently only works with moodle 2.x branch.)
* ''lang/en/widget.php'' - Lastly, each module will have some language files that contain strings for that module, especially:
:* $string['pluginname'] = 'Widget';


=== IMPORTANT: ===
        $mform->addElement('text', 'name', get_string('certificatename', 'certificate'), array('size'=>'64'));
* When creating a new module, the new name of the module must not contain numbers or other special characters!
        $mform->setType('name', PARAM_TEXT);
        $mform->addRule('name', null, 'required', null, 'client');


* You need a ''data base table'' with the same name as your module. This table must have at least three fields:
        $mform->addElement('select', 'savecert', get_string('savecert', 'certificate'), $ynoptions);
*# id
        $mform->setDefault('savecert', 0);
*# course
        $mform->addHelpButton('savecert', 'savecert', 'certificate');
*# name


* You should also make sure that your activity module provides appropriate support for groups and meta-courses.
        $this->standard_coursemodule_elements();


== See also ==
        $this->add_action_buttons();
    }
}
</code>


* Moodle 2.x activity module template [https://github.com/moodlehq/moodle-mod_newmodule https://github.com/moodlehq/moodle-mod_newmodule] for developing new modules.
The above example does not contain the full file, just enough to provide you with an idea. First we create a text element called 'name' that is required, this is obviously the name of the instance. I then created another element that stores whether a user wishes to store the PDF generated by the certificate on the filesystem or not with a default value of 0 and a help button explaining what it's function is. The function standard_coursemodule_elements adds the elements common to the modules, such as the conditional fields. The add_action_buttons function adds the submit and cancel buttons to the form. This data will be passed to either certificate_add_instance or certificate_update_instance depending on whether you are adding a new instance or updating a current one. You can also add validation to this form, just like any other form in Moodle. For more information on how to create forms in Moodle see [[Form_API]].
* [[Blocks]]
* [[Backup]]
* Tracker issue [http://tracker.moodle.org/browse/CONTRIB-52 CONTRIB-52 Improvements to make NEWMODULE really useful] - including download link for new module template supporting roles, formslib etc. (unfinished)
* http://download.moodle.org/plugins16/mod/NEWMODULE.zip - new module template for versions of Moodle prior to 1.7. Please follow the README instructions inside the zip.
* [[NEWMODULE_Documentation]]


Using Moodle forum discussions:
=== version.php ===
*[http://moodle.org/mod/forum/discuss.php?d=66165 A new resource type: where do I put the language strings?]
*[http://moodle.org/mod/forum/discuss.php?d=65986 New Module Template Code for Moodle 1.7]
*[http://moodle.org/mod/forum/discuss.php?d=90154 LEGACY roles and capabilities]


[[Category:Modules]]
The version.php file keeps track of the version of your module, and other attributes, such as what version of Moodle it requires. For a full list of the attributes please see [[version.php]].
[[Category:Modules]]
[[Category:Tutorial]]
[[Category:Plugins]]

Revision as of 09:12, 18 October 2012

Introduction

Activity modules reside in the /mod directory. They are the oldest type of plugins in Moodle - that's why they have this overly-generic name and also why they have a few idiosyncrasies and operate slightly differently from all the plugins that came later.

Each module is in a separate subdirectory and consists of a number of 'mandatory files' and any other files the developer is going to use. The below image is an example of the certificate module's filestructure.

Activities file structure example.jpg

Standard Files and their Functions

There are several files that Moodle looks for when using your module, they each have a particular function and are all not necessary. Below are the list of most commonly used files, to view them all please

Backup Folder

This is the location to place the files that define how your module is going to behave when a course backup or restore is performed. You may have added a lot of information to the database for a specific module that you do not wish to enter again when restoring a course, this is where you define what should be saved during a backup and how to then restore this information from the Moodle backup.

To read more on this please visit Backup_2.0_for_developers and Restore_2.0_for_developers.

DB Folder

access.php

This is where you define what capabilities your plugin will create. Note, if you add new capabilities to this file after your plugin has been installed you will need to increase the version number in your version.php file (discussed later) in order for them to be installed.

An example of the file is below -

$capabilities = array(

   'mod/certificate:addinstance' => array(
       'riskbitmask' => RISK_XSS,
       'captype' => 'write',
       'contextlevel' => CONTEXT_COURSE,
       'archetypes' => array(
           'editingteacher' => CAP_ALLOW,
           'manager' => CAP_ALLOW
       ),
       'clonepermissionsfrom' => 'moodle/course:manageactivities'
   ),

);

In Moodle 2.3 a new capability called 'addinstance' was added for all core modules. Moodle will look for this capability by searching for 'mod/<modname>:addinstance' and if it is not created then it assumed that the user does have this capability with a debug message being displayed that the capability is missing. To avoid this situation it is good to add this to your module. For further information on what each attribute in that capabalities array means visit NEWMODULE_Adding_capabilities.

install.xml

This file is used on installation of your module. It includes the database tables and fields that your module will be creating. If your module does not require any new tables then this file is not necessary. In order to create this XML file please view XMLDB_editor. Please note, in the XML file the table names are listed without the config.php prefix, this is automatically used when creating the tables and does not need to be specified.

An example of this file is below -

<?xml version="1.0" encoding="UTF-8" ?> <XMLDB PATH="mod/certificate/db" VERSION="20120925" COMMENT="XMLDB file for Moodle mod/certificate"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"

>

 <TABLES>
<FIELDS> <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="course"/> <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="name"/> <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="course" NEXT="intro"/> <FIELD NAME="intro" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="introformat"/> <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="intro" NEXT="emailteachers"/> <FIELD NAME="emailteachers" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="introformat" NEXT="emailothers"/> <FIELD NAME="emailothers" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="emailteachers" NEXT="savecert"/> <FIELD NAME="savecert" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="emailothers" NEXT="reportcert"/> <FIELD NAME="reportcert" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="savecert" NEXT="delivery"/> <FIELD NAME="delivery" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="reportcert" NEXT="requiredtime"/> <FIELD NAME="requiredtime" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="delivery" NEXT="type"/> <FIELD NAME="type" TYPE="char" LENGTH="50" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="requiredtime" NEXT="orientation"/> <FIELD NAME="orientation" TYPE="char" LENGTH="10" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="type" NEXT="width"/> <FIELD NAME="width" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="orientation" NEXT="height"/> <FIELD NAME="height" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="width" NEXT="backgroundimage"/> <FIELD NAME="backgroundimage" TYPE="char" LENGTH="255" NOTNULL="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="height" NEXT="timecreated"/> <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="backgroundimage" NEXT="timemodified"/> <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timecreated"/> </FIELDS> <KEYS> <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for certificate"/> </KEYS>
<FIELDS> <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="userid"/> <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="certificateid"/> <FIELD NAME="certificateid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="userid" NEXT="timecreated"/> <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="certificateid"/> </FIELDS> <KEYS> <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for certificate_issues" NEXT="certificate"/> <KEY NAME="certificate" TYPE="foreign" FIELDS="certificateid" REFTABLE="certificate" REFFIELDS="id" PREVIOUS="primary"/> </KEYS>
 </TABLES>

</XMLDB>

The above example contains the structure of the table certificate and certificate_issues. Each table, field and key lists what element is before and after it (if there are any present). This is automatically created by the XMLDB editor. Your module should always have a table called after the module itself with the fields id, name and course.

upgrade.php

This file handles upgrading the module to match the latest version. After creating a module and using it extensively on your site (and others) you may want to extend the functionality of your module. Using the certificate example, a suggestion was made that a unique code could be generated for each certificate issued and displayed if a setting was selected. This requires two new database fields, one to store whether the user has chosen to display the code on the certificate and another to store the actual code. This is where the upgrade.php script becomes used. The install.xml file is only executed once, that is when your module is first installed, so adding these two extra columns to this file does not change the database structure for users who have already installed the module. So, to perform this upgrade you need to do three things.

1. Add the new columns to the install.xml file so that any users who install the module after this point are given the new table structure. 2. Add the instructions for the upgrade.php files. 3. Update the version number in your version.php file.

In this example we are only adding two new columns to the database, so we can use the XMLDB editor to change the install.xml file AND create the upgrade path. Please view XMLDB_editor.

An example of the upgrade.php file is as follows -

function xmldb_certificate_upgrade($oldversion=0) {

   if ($oldversion < 2012091801) {
       // Add new fields to certificate table.
       $table = new xmldb_table('certificate');
       $field = new xmldb_field('showcode');
       $field->set_attributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'savecert');
       if (!$dbman->field_exists($table, $field)) {
           $dbman->add_field($table, $field);
       }
       // Add new fields to certificate_issues table.
       $table = new xmldb_table('certificate_issues');
       $field = new xmldb_field('code');
       $field->set_attributes(XMLDB_TYPE_CHAR, '50', null, null, null, null, 'certificateid');
       if (!$dbman->field_exists($table, $field)) {
           $dbman->add_field($table, $field);
       }
   }

}

Whenever you change the version in your version.php module Moodle will look to see if anything needs to be done. The version that is stored in the database is passed to the xmldb_<modname>_upgrade function as the variable $oldversion in this case. In this example lets say that the initial version was 2012091600, since this is less than 2012091800 (the new version.php numer) we will execute the code in the if statement which will then update the version stored in the database meaning this if statement is never executed again. For more extensive details on this please see Upgrade_API.

Lang Folder

This is where you store any strings you are going to use in your plugin. Each language has a specific folder that needs to be created in order for it to be used with your module. In this case we are going to use the English language (since unfortunately it is the only one I know). A folder called en is created in your lang folder that contains a file called <modname>.php that lists the translations of your string. For example, your module may have a setting called 'User preferences', rather than hard coding this term in your form, you use a placeholder that will then retrieve the appropriate string depending on the language being used on your Moodle site. There is one mandatory placeholder for modules called 'pluginname' that Moodle will use when listing this module as an option to add to a course and other various pages. To keep with Moodle standards you should order your strings alphabetically by the placeholder name.

$string['pluginname'] = 'Certificate'; $string['userpreferences'] = 'User preferences';

If you wanted to add the French translation you would create a folder called fr and add the file <modname>.php to it.

$string['pluginname'] = 'Certificat'; $string['userpreferences'] = 'Préférences d\'utilisateur';

Now, when using the string 'User preferences' we will use the Moodle function get_string instead, which will get the appropriate string depending on the language being used.

get_string('userpreferences', '<modname>');

Pix folder

Here you simply store the icon you wish Moodle to display next to the name of your module. The name of the file should be icon.gif and is displayed with the resolution of 64 * 64. Feel free to use this folder to store other pictures you may use.

lib.php

The list of functions that are possible to override in the lib.php are listed here NEWMODULE_Documentation#lib.php. The essential ones are listed below

function certificate_add_instance($certificate); function certificate_update_instance($certificate); function certificate_delete_instance($id);

The certificate_add_instance function is passed the variables from the mod_form.php file (discussed later) as an object when you first create an activity and click submit. This is where you can take that data, do what you want with it and then insert it into the database if you wish. This is only called once when the module instance is added, so this is where you should place the logic to add the activity. The certificate_update_instance function is passed the variables from the mod_form.php file as an object whenever you update an activity and click submit. The certificate_delete_instance function is passed the id of your module which you can use to delete the records from any database tables associated with that id. For example, in the certificate module the ID of the certificate table is passed, and then used to delete the certificate from the database, any issues of this certificate and any files associated with it on the filesystem.

mod_form.php

This file is used when adding/editing a module to a course. It contains the elements that will be displayed on the form responsible for creating/installing an instance of your module.

if (!defined('MOODLE_INTERNAL')) {

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

}

require_once($CFG->dirroot.'/course/moodleform_mod.php'); require_once($CFG->dirroot.'/mod/certificate/lib.php');

class mod_certificate_mod_form extends moodleform_mod {

   function definition() {
       global $CFG, $DB, $OUTPUT;
       $mform =& $this->_form;
       $mform->addElement('text', 'name', get_string('certificatename', 'certificate'), array('size'=>'64'));
       $mform->setType('name', PARAM_TEXT);
       $mform->addRule('name', null, 'required', null, 'client');
       $mform->addElement('select', 'savecert', get_string('savecert', 'certificate'), $ynoptions);
       $mform->setDefault('savecert', 0);
       $mform->addHelpButton('savecert', 'savecert', 'certificate');
       $this->standard_coursemodule_elements();
       $this->add_action_buttons();
   }

}

The above example does not contain the full file, just enough to provide you with an idea. First we create a text element called 'name' that is required, this is obviously the name of the instance. I then created another element that stores whether a user wishes to store the PDF generated by the certificate on the filesystem or not with a default value of 0 and a help button explaining what it's function is. The function standard_coursemodule_elements adds the elements common to the modules, such as the conditional fields. The add_action_buttons function adds the submit and cancel buttons to the form. This data will be passed to either certificate_add_instance or certificate_update_instance depending on whether you are adding a new instance or updating a current one. You can also add validation to this form, just like any other form in Moodle. For more information on how to create forms in Moodle see Form_API.

version.php

The version.php file keeps track of the version of your module, and other attributes, such as what version of Moodle it requires. For a full list of the attributes please see version.php.